1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
3
The following changes since commit d495e432c04a6394126c35cf96517749708b410f:
4
5
Merge tag 'pull-aspeed-20220630' of https://github.com/legoater/qemu into staging (2022-06-30 22:04:12 +0530)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220703-1
8
10
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
11
for you to fetch changes up to 435774992e82d2d16f025afbb20b4f7be9b242b0:
10
12
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
13
target/riscv: Update default priority table for local interrupts (2022-07-03 10:03:20 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
RISC-V PR for 9.1
16
Fifth RISC-V PR for QEMU 7.1
15
17
16
* APLICs add child earlier than realize
18
* Fix register zero guarding for auipc and lui
17
* Fix exposure of Zkr
19
* Ensure bins (mtval) is set correctly
18
* Raise exceptions on wrs.nto
20
* Minimize the calls to decode_save_opc
19
* Implement SBI debug console (DBCN) calls for KVM
21
* Guard against PMP ranges with a negative size
20
* Support 64-bit addresses for initrd
22
* Implement mcountinhibit CSR
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
23
* Add support for hpmcounters/hpmevents
22
* Tolerate KVM disable ext errors
24
* Improve PMU implenentation
23
* Set tval in breakpoints
25
* Support mcycle/minstret write operation
24
* Add support for Zve32x extension
26
* Fixup MSECCFG minimum priv check
25
* Add support for Zve64x extension
27
* Ibex (OpenTitan) fixup priv version
26
* Relax vector register check in RISCV gdbstub
28
* Fix bug resulting in always using latest priv spec
27
* Fix the element agnostic Vector function problem
29
* Reduce FDT address alignment constraints
28
* Fix Zvkb extension config
30
* Set minumum priv spec version for mcountinhibit
29
* Implement dynamic establishment of custom decoder
31
* AIA update to v0.3 of the spec
30
* Add th.sxstatus CSR emulation
31
* Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
32
* Check single width operator for vector fp widen instructions
33
* Check single width operator for vfncvt.rod.f.f.w
34
* Remove redudant SEW checking for vector fp narrow/widen instructions
35
* Prioritize pmp errors in raise_mmu_exception()
36
* Do not set mtval2 for non guest-page faults
37
* Remove experimental prefix from "B" extension
38
* Fixup CBO extension register calculation
39
* Fix the hart bit setting of AIA
40
* Fix reg_width in ricsv_gen_dynamic_vector_feature()
41
* Decode all of the pmpcfg and pmpaddr CSRs
42
* Raise an exception when CSRRS/CSRRC writes a read-only CSR
43
32
44
----------------------------------------------------------------
33
----------------------------------------------------------------
45
Alexei Filippov (1):
34
Alistair Francis (3):
46
target/riscv: do not set mtval2 for non guest-page faults
35
target/riscv: Fixup MSECCFG minimum priv check
36
target/riscv: Ibex: Support priv version 1.11
37
hw/riscv: boot: Reduce FDT address alignment constraints
47
38
48
Alistair Francis (2):
39
Anup Patel (4):
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
40
target/riscv: Don't force update priv spec version to latest
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
41
target/riscv: Set minumum priv spec version for mcountinhibit
42
target/riscv: Remove CSRs that set/clear an IMSIC interrupt file bits
43
target/riscv: Update default priority table for local interrupts
51
44
52
Andrew Jones (2):
45
Atish Patra (7):
53
target/riscv/kvm: Fix exposure of Zkr
46
target/riscv: Fix PMU CSR predicate function
54
target/riscv: Raise exceptions on wrs.nto
47
target/riscv: Implement PMU CSR predicate function for S-mode
48
target/riscv: pmu: Rename the counters extension to pmu
49
target/riscv: pmu: Make number of counters configurable
50
target/riscv: Implement mcountinhibit CSR
51
target/riscv: Add support for hpmcounters/hpmevents
52
target/riscv: Support mcycle/minstret write operation
55
53
56
Cheng Yang (1):
54
Nicolas Pitre (1):
57
hw/riscv/boot.c: Support 64-bit address for initrd
55
target/riscv/pmp: guard against PMP ranges with a negative size
58
56
59
Christoph Müllner (1):
57
Richard Henderson (3):
60
riscv: thead: Add th.sxstatus CSR emulation
58
target/riscv: Set env->bins in gen_exception_illegal
59
target/riscv: Remove generate_exception_mtval
60
target/riscv: Minimize the calls to decode_save_opc
61
61
62
Clément Léger (1):
62
Víctor Colombo (1):
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
63
target/riscv: Remove condition guarding register zero for auipc and lui
64
64
65
Daniel Henrique Barboza (6):
65
target/riscv/cpu.h | 24 +-
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
66
target/riscv/cpu_bits.h | 30 +-
67
target/riscv/kvm: tolerate KVM disable ext errors
67
target/riscv/pmu.h | 28 +
68
target/riscv/debug: set tval=pc in breakpoint exceptions
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
72
73
Huang Tao (2):
74
target/riscv: Fix the element agnostic function problem
75
target/riscv: Implement dynamic establishment of custom decoder
76
77
Jason Chien (3):
78
target/riscv: Add support for Zve32x extension
79
target/riscv: Add support for Zve64x extension
80
target/riscv: Relax vector register check in RISCV gdbstub
81
82
Max Chou (4):
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
87
88
Rob Bradford (1):
89
target/riscv: Remove experimental prefix from "B" extension
90
91
Yangyu Chen (1):
92
target/riscv/cpu.c: fix Zvkb extension config
93
94
Yong-Xuan Wang (1):
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
96
97
Yu-Ming Chang (1):
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
99
100
yang.zhang (1):
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
102
103
MAINTAINERS | 1 +
104
target/riscv/cpu.h | 11 ++
105
target/riscv/cpu_bits.h | 2 +-
106
target/riscv/cpu_cfg.h | 2 +
107
target/riscv/helper.h | 1 +
108
target/riscv/sbi_ecall_interface.h | 17 +++
109
target/riscv/tcg/tcg-cpu.h | 15 +++
110
disas/riscv.c | 65 +++++++++-
111
hw/intc/riscv_aplic.c | 8 +-
112
hw/riscv/boot.c | 4 +-
68
hw/riscv/boot.c | 4 +-
113
target/riscv/cpu.c | 10 +-
69
target/riscv/cpu.c | 17 +-
114
target/riscv/cpu_helper.c | 37 +++---
70
target/riscv/cpu_helper.c | 134 ++--
115
target/riscv/csr.c | 71 +++++++++--
71
target/riscv/csr.c | 857 +++++++++++++++----------
116
target/riscv/debug.c | 3 +
72
target/riscv/machine.c | 25 +
117
target/riscv/gdbstub.c | 8 +-
73
target/riscv/pmp.c | 3 +
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
74
target/riscv/pmu.c | 32 +
119
target/riscv/op_helper.c | 17 ++-
75
target/riscv/translate.c | 31 +-
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
76
target/riscv/insn_trans/trans_privileged.c.inc | 4 +
121
target/riscv/th_csr.c | 79 +++++++++++++
77
target/riscv/insn_trans/trans_rvh.c.inc | 2 +
122
target/riscv/translate.c | 31 +++--
78
target/riscv/insn_trans/trans_rvi.c.inc | 10 +-
123
target/riscv/vector_internals.c | 22 ++++
79
target/riscv/meson.build | 3 +-
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
80
tests/tcg/riscv64/Makefile.softmmu-target | 21 +
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
81
tests/tcg/riscv64/issue1060.S | 53 ++
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
82
tests/tcg/riscv64/semihost.ld | 21 +
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
83
18 files changed, 843 insertions(+), 456 deletions(-)
128
target/riscv/meson.build | 1 +
84
create mode 100644 target/riscv/pmu.h
129
26 files changed, 596 insertions(+), 109 deletions(-)
85
create mode 100644 target/riscv/pmu.c
130
create mode 100644 target/riscv/th_csr.c
86
create mode 100644 tests/tcg/riscv64/Makefile.softmmu-target
131
87
create mode 100644 tests/tcg/riscv64/issue1060.S
88
create mode 100644 tests/tcg/riscv64/semihost.ld
diff view generated by jsdifflib
Deleted patch
1
From: "yang.zhang" <yang.zhang@hexintek.com>
2
1
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
4
be initialized first.
5
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/intc/riscv_aplic.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/riscv_aplic.c
19
+++ b/hw/intc/riscv_aplic.c
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
21
qdev_prop_set_bit(dev, "msimode", msimode);
22
qdev_prop_set_bit(dev, "mmode", mmode);
23
24
+ if (parent) {
25
+ riscv_aplic_add_child(parent, dev);
26
+ }
27
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
29
30
if (!is_kvm_aia(msimode)) {
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
32
}
33
34
- if (parent) {
35
- riscv_aplic_add_child(parent, dev);
36
- }
37
-
38
if (!msimode) {
39
for (i = 0; i < num_harts; i++) {
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
41
--
42
2.45.1
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Víctor Colombo <victor.colombo@eldorado.org.br>
2
2
3
When running the instruction
3
Commit 57c108b8646 introduced gen_set_gpri(), which already contains
4
a check for if the destination register is 'zero'. The check in auipc
5
and lui are then redundant. This patch removes those checks.
4
6
5
```
7
Signed-off-by: Víctor Colombo <victor.colombo@eldorado.org.br>
6
cbo.flush 0(x0)
7
```
8
9
QEMU would segfault.
10
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
12
allocated.
13
14
In order to fix this let's use the existing get_address()
15
helper. This also has the benefit of performing pointer mask
16
calculations on the address specified in rs1.
17
18
The pointer masking specificiation specifically states:
19
20
"""
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
10
Message-Id: <20220610165517.47517-1-victor.colombo@eldorado.org.br>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
12
---
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
13
target/riscv/insn_trans/trans_rvi.c.inc | 8 ++------
36
1 file changed, 12 insertions(+), 4 deletions(-)
14
1 file changed, 2 insertions(+), 6 deletions(-)
37
15
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
16
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
39
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
18
--- a/target/riscv/insn_trans/trans_rvi.c.inc
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
42
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static bool trans_c64_illegal(DisasContext *ctx, arg_empty *a)
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
21
22
static bool trans_lui(DisasContext *ctx, arg_lui *a)
44
{
23
{
45
REQUIRE_ZICBOM(ctx);
24
- if (a->rd != 0) {
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
25
- gen_set_gpri(ctx, a->rd, a->imm);
47
+ TCGv src = get_address(ctx, a->rs1, 0);
26
- }
48
+
27
+ gen_set_gpri(ctx, a->rd, a->imm);
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
50
return true;
28
return true;
51
}
29
}
52
30
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
31
static bool trans_auipc(DisasContext *ctx, arg_auipc *a)
54
{
32
{
55
REQUIRE_ZICBOM(ctx);
33
- if (a->rd != 0) {
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
34
- gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
57
+ TCGv src = get_address(ctx, a->rs1, 0);
35
- }
58
+
36
+ gen_set_gpri(ctx, a->rd, a->imm + ctx->base.pc_next);
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
60
return true;
37
return true;
61
}
38
}
62
39
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
64
{
65
REQUIRE_ZICBOM(ctx);
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
67
+ TCGv src = get_address(ctx, a->rs1, 0);
68
+
69
+ gen_helper_cbo_inval(tcg_env, src);
70
return true;
71
}
72
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
74
{
75
REQUIRE_ZICBOZ(ctx);
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
77
+ TCGv src = get_address(ctx, a->rs1, 0);
78
+
79
+ gen_helper_cbo_zero(tcg_env, src);
80
return true;
81
}
82
--
40
--
83
2.45.1
41
2.36.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
3
While we set env->bins when unwinding for ILLEGAL_INST,
4
instructions will be affected by Zvfhmin extension.
4
from e.g. csrrw, we weren't setting it for immediately
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
5
illegal instructions.
6
conversions of
7
6
8
* From 1*SEW(16/32) to 2*SEW(32/64)
7
Add a testcase for mtval via both exception paths.
9
* From 2*SEW(32/64) to 1*SEW(16/32)
10
8
11
Signed-off-by: Max Chou <max.chou@sifive.com>
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1060
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
12
Message-Id: <20220604231004.49990-2-richard.henderson@linaro.org>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
14
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
15
target/riscv/translate.c | 2 +
18
1 file changed, 18 insertions(+), 2 deletions(-)
16
tests/tcg/riscv64/Makefile.softmmu-target | 21 +++++++++
17
tests/tcg/riscv64/issue1060.S | 53 +++++++++++++++++++++++
18
tests/tcg/riscv64/semihost.ld | 21 +++++++++
19
4 files changed, 97 insertions(+)
20
create mode 100644 tests/tcg/riscv64/Makefile.softmmu-target
21
create mode 100644 tests/tcg/riscv64/issue1060.S
22
create mode 100644 tests/tcg/riscv64/semihost.ld
19
23
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
24
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
21
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
26
--- a/target/riscv/translate.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
27
+++ b/target/riscv/translate.c
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
28
@@ -XXX,XX +XXX,XX @@ static void generate_exception_mtval(DisasContext *ctx, int excp)
25
}
29
30
static void gen_exception_illegal(DisasContext *ctx)
31
{
32
+ tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
33
+ offsetof(CPURISCVState, bins));
34
generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
26
}
35
}
27
36
28
+static bool require_rvfmin(DisasContext *s)
37
diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/tests/tcg/riscv64/Makefile.softmmu-target
42
@@ -XXX,XX +XXX,XX @@
43
+#
44
+# RISC-V system tests
45
+#
46
+
47
+TEST_SRC = $(SRC_PATH)/tests/tcg/riscv64
48
+VPATH += $(TEST_SRC)
49
+
50
+LINK_SCRIPT = $(TEST_SRC)/semihost.ld
51
+LDFLAGS = -T $(LINK_SCRIPT)
52
+CFLAGS += -g -Og
53
+
54
+%.o: %.S
55
+    $(CC) $(CFLAGS) $< -c -o $@
56
+%: %.o $(LINK_SCRIPT)
57
+    $(LD) $(LDFLAGS) $< -o $@
58
+
59
+QEMU_OPTS += -M virt -display none -semihosting -device loader,file=
60
+
61
+EXTRA_RUNS += run-issue1060
62
+run-issue1060: issue1060
63
+    $(call run-test, $<, $(QEMU) $(QEMU_OPTS)$<)
64
diff --git a/tests/tcg/riscv64/issue1060.S b/tests/tcg/riscv64/issue1060.S
65
new file mode 100644
66
index XXXXXXX..XXXXXXX
67
--- /dev/null
68
+++ b/tests/tcg/riscv64/issue1060.S
69
@@ -XXX,XX +XXX,XX @@
70
+    .option    norvc
71
+
72
+    .text
73
+    .global _start
74
+_start:
75
+    lla    t0, trap
76
+    csrw    mtvec, t0
77
+
78
+    # These are all illegal instructions
79
+    csrw    time, x0
80
+    .insn    i CUSTOM_0, 0, x0, x0, 0x321
81
+    csrw    time, x0
82
+    .insn    i CUSTOM_0, 0, x0, x0, 0x123
83
+    csrw    cycle, x0
84
+
85
+    # Success!
86
+    li    a0, 0
87
+    j    _exit
88
+
89
+trap:
90
+    # When an instruction traps, compare it to the insn in memory.
91
+    csrr    t0, mepc
92
+    csrr    t1, mtval
93
+    lwu    t2, 0(t0)
94
+    bne    t1, t2, fail
95
+
96
+    # Skip the insn and continue.
97
+    addi    t0, t0, 4
98
+    csrw    mepc, t0
99
+    mret
100
+
101
+fail:
102
+    li    a0, 1
103
+
104
+# Exit code in a0
105
+_exit:
106
+    lla    a1, semiargs
107
+    li    t0, 0x20026    # ADP_Stopped_ApplicationExit
108
+    sd    t0, 0(a1)
109
+    sd    a0, 8(a1)
110
+    li    a0, 0x20    # TARGET_SYS_EXIT_EXTENDED
111
+
112
+    # Semihosting call sequence
113
+    .balign    16
114
+    slli    zero, zero, 0x1f
115
+    ebreak
116
+    srai    zero, zero, 0x7
117
+    j    .
118
+
119
+    .data
120
+    .balign    16
121
+semiargs:
122
+    .space    16
123
diff --git a/tests/tcg/riscv64/semihost.ld b/tests/tcg/riscv64/semihost.ld
124
new file mode 100644
125
index XXXXXXX..XXXXXXX
126
--- /dev/null
127
+++ b/tests/tcg/riscv64/semihost.ld
128
@@ -XXX,XX +XXX,XX @@
129
+ENTRY(_start)
130
+
131
+SECTIONS
29
+{
132
+{
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
133
+ /* virt machine, RAM starts at 2gb */
31
+ return false;
134
+ . = 0x80000000;
135
+ .text : {
136
+ *(.text)
32
+ }
137
+ }
33
+
138
+ .rodata : {
34
+ switch (s->sew) {
139
+ *(.rodata)
35
+ case MO_16:
140
+ }
36
+ return s->cfg_ptr->ext_zvfhmin;
141
+ /* align r/w section to next 2mb */
37
+ case MO_32:
142
+ . = ALIGN(1 << 21);
38
+ return s->cfg_ptr->ext_zve32f;
143
+ .data : {
39
+ default:
144
+ *(.data)
40
+ return false;
145
+ }
146
+ .bss : {
147
+ *(.bss)
41
+ }
148
+ }
42
+}
149
+}
43
+
44
static bool require_scale_rvf(DisasContext *s)
45
{
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
48
}
49
50
switch (s->sew) {
51
- case MO_8:
52
- return s->cfg_ptr->ext_zvfhmin;
53
case MO_16:
54
return s->cfg_ptr->ext_zve32f;
55
case MO_32:
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
58
{
59
return opfv_widen_check(s, a) &&
60
+ require_rvfmin(s) &&
61
require_scale_rvfmin(s) &&
62
(s->sew != MO_8);
63
}
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
66
{
67
return opfv_narrow_check(s, a) &&
68
+ require_rvfmin(s) &&
69
require_scale_rvfmin(s) &&
70
(s->sew != MO_8);
71
}
72
--
150
--
73
2.45.1
151
2.36.1
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Implementing wrs.nto to always just return is consistent with the
3
The function doesn't set mtval, it sets badaddr. Move the set
4
specification, as the instruction is permitted to terminate the
4
of badaddr directly into gen_exception_inst_addr_mis and use
5
stall for any reason, but it's not useful for virtualization, where
5
generate_exception.
6
we'd like the guest to trap to the hypervisor in order to allow
7
scheduling of the lock holding VCPU. Change to always immediately
8
raise exceptions when the appropriate conditions are present,
9
otherwise continue to just return. Note, immediately raising
10
exceptions is also consistent with the specification since the
11
time limit that should expire prior to the exception is
12
implementation-specific.
13
6
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
9
Message-Id: <20220604231004.49990-3-richard.henderson@linaro.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
11
---
21
target/riscv/helper.h | 1 +
12
target/riscv/translate.c | 11 ++---------
22
target/riscv/op_helper.c | 11 ++++++++
13
1 file changed, 2 insertions(+), 9 deletions(-)
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
24
3 files changed, 32 insertions(+), 9 deletions(-)
25
14
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
15
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
27
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/helper.h
17
--- a/target/riscv/translate.c
29
+++ b/target/riscv/helper.h
18
+++ b/target/riscv/translate.c
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
19
@@ -XXX,XX +XXX,XX @@ static void generate_exception(DisasContext *ctx, int excp)
31
DEF_HELPER_1(sret, tl, env)
20
ctx->base.is_jmp = DISAS_NORETURN;
32
DEF_HELPER_1(mret, tl, env)
33
DEF_HELPER_1(wfi, void, env)
34
+DEF_HELPER_1(wrs_nto, void, env)
35
DEF_HELPER_1(tlb_flush, void, env)
36
DEF_HELPER_1(tlb_flush_all, void, env)
37
/* Native Debug */
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/op_helper.c
41
+++ b/target/riscv/op_helper.c
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
43
}
44
}
21
}
45
22
46
+void helper_wrs_nto(CPURISCVState *env)
23
-static void generate_exception_mtval(DisasContext *ctx, int excp)
47
+{
24
-{
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
25
- gen_set_pc_imm(ctx, ctx->base.pc_next);
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
26
- tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
27
- gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
28
- ctx->base.is_jmp = DISAS_NORETURN;
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
29
-}
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
30
-
54
+ }
31
static void gen_exception_illegal(DisasContext *ctx)
55
+}
56
+
57
void helper_tlb_flush(CPURISCVState *env)
58
{
32
{
59
CPUState *cs = env_cpu(env);
33
tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
34
@@ -XXX,XX +XXX,XX @@ static void gen_exception_illegal(DisasContext *ctx)
61
index XXXXXXX..XXXXXXX 100644
35
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
36
static void gen_exception_inst_addr_mis(DisasContext *ctx)
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
64
@@ -XXX,XX +XXX,XX @@
65
* this program. If not, see <http://www.gnu.org/licenses/>.
66
*/
67
68
-static bool trans_wrs(DisasContext *ctx)
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
70
{
37
{
71
if (!ctx->cfg_ptr->ext_zawrs) {
38
- generate_exception_mtval(ctx, RISCV_EXCP_INST_ADDR_MIS);
72
return false;
39
+ tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
40
+ generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
74
return true;
75
}
41
}
76
42
77
-#define GEN_TRANS_WRS(insn) \
43
static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
79
-{ \
80
- (void)a; \
81
- return trans_wrs(ctx); \
82
-}
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
84
+{
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
86
+ return false;
87
+ }
88
89
-GEN_TRANS_WRS(wrs_nto)
90
-GEN_TRANS_WRS(wrs_sto)
91
+ /*
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
93
+ * should raise an exception when the implementation-specific bounded time
94
+ * limit has expired. Our time limit is zero, so we either return
95
+ * immediately, as does our implementation of wrs.sto, or raise an
96
+ * exception, as handled by the wrs.nto helper.
97
+ */
98
+#ifndef CONFIG_USER_ONLY
99
+ gen_helper_wrs_nto(tcg_env);
100
+#endif
101
+
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
103
+ return trans_wrs_sto(ctx, NULL);
104
+}
105
--
44
--
106
2.45.1
45
2.36.1
107
108
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
3
The set of instructions that require decode_save_opc for
4
the legacy console putchar and getchar SBI extensions.
4
unwinding is really fairly small -- only insns that can
5
raise ILLEGAL_INSN at runtime. This includes CSR, anything
6
that uses a *new* fp rounding mode, and many privileged insns.
5
7
6
The appeal of the DBCN extension is that it allows multiple bytes to be
8
Since unwind info is stored as the difference from the
7
read/written in the SBI console in a single SBI call.
9
previous insn, storing a 0 for most insns minimizes the
10
size of the unwind info.
8
11
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
12
Booting a debian kernel image to the missing rootfs panic yields
10
module to userspace. But this will only happens if the KVM module
11
actually supports this SBI extension and we activate it.
12
13
13
We'll check for DBCN support during init time, checking if get-reg-list
14
- gen code size 22226819/1026886656
14
is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
15
+ gen code size 21601907/1026886656
15
kvm_set_one_reg() during kvm_arch_init_vcpu().
16
16
17
Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
17
on 41k TranslationBlocks, a savings of 610kB or a bit less than 3%.
18
SBI_EXT_DBCN, reading and writing as required.
19
18
20
A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
19
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
21
host, takes around 20 seconds to boot without using DBCN. With this
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
patch we're taking around 14 seconds to boot due to the speed-up in the
21
Message-Id: <20220604231004.49990-4-richard.henderson@linaro.org>
23
terminal output. There's no change in boot time if the guest isn't
24
using earlycon.
25
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
27
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
28
Message-ID: <20240425155012.581366-1-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
23
---
31
target/riscv/sbi_ecall_interface.h | 17 +++++
24
target/riscv/translate.c | 18 +++++++++---------
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
25
target/riscv/insn_trans/trans_privileged.c.inc | 4 ++++
33
2 files changed, 128 insertions(+)
26
target/riscv/insn_trans/trans_rvh.c.inc | 2 ++
27
target/riscv/insn_trans/trans_rvi.c.inc | 2 ++
28
4 files changed, 17 insertions(+), 9 deletions(-)
34
29
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
30
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
36
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/sbi_ecall_interface.h
32
--- a/target/riscv/translate.c
38
+++ b/target/riscv/sbi_ecall_interface.h
33
+++ b/target/riscv/translate.c
39
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ static void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
40
35
tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
41
/* clang-format off */
42
43
+#define SBI_SUCCESS 0
44
+#define SBI_ERR_FAILED -1
45
+#define SBI_ERR_NOT_SUPPORTED -2
46
+#define SBI_ERR_INVALID_PARAM -3
47
+#define SBI_ERR_DENIED -4
48
+#define SBI_ERR_INVALID_ADDRESS -5
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
50
+#define SBI_ERR_ALREADY_STARTED -7
51
+#define SBI_ERR_ALREADY_STOPPED -8
52
+#define SBI_ERR_NO_SHMEM -9
53
+
54
/* SBI Extension IDs */
55
#define SBI_EXT_0_1_SET_TIMER 0x0
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
57
@@ -XXX,XX +XXX,XX @@
58
#define SBI_EXT_IPI 0x735049
59
#define SBI_EXT_RFENCE 0x52464E43
60
#define SBI_EXT_HSM 0x48534D
61
+#define SBI_EXT_DBCN 0x4442434E
62
63
/* SBI function IDs for BASE extension */
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
65
@@ -XXX,XX +XXX,XX @@
66
#define SBI_EXT_HSM_HART_STOP 0x1
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
68
69
+/* SBI function IDs for DBCN extension */
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
73
+
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/kvm/kvm-cpu.c
80
+++ b/target/riscv/kvm/kvm-cpu.c
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
83
};
84
85
+static KVMCPUConfig kvm_sbi_dbcn = {
86
+ .name = "sbi_dbcn",
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
89
+};
90
+
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
92
{
93
CPURISCVState *env = &cpu->env;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
95
return 0;
96
}
36
}
97
37
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
38
+static void decode_save_opc(DisasContext *ctx)
99
+ KVMScratchCPU *kvmcpu,
100
+ struct kvm_reg_list *reglist)
101
+{
39
+{
102
+ struct kvm_reg_list *reg_search;
40
+ assert(ctx->insn_start != NULL);
103
+
41
+ tcg_set_insn_start_param(ctx->insn_start, 1, ctx->opcode);
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
42
+ ctx->insn_start = NULL;
105
+ sizeof(uint64_t), uint64_cmp);
106
+
107
+ if (reg_search) {
108
+ kvm_sbi_dbcn.supported = true;
109
+ }
110
+}
43
+}
111
+
44
+
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
45
static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
113
struct kvm_reg_list *reglist)
114
{
46
{
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
47
if (get_xl(ctx) == MXL_RV32) {
116
if (riscv_has_ext(&cpu->env, RVV)) {
48
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
49
return;
118
}
50
}
119
+
51
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
52
+ /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
53
+ decode_save_opc(ctx);
54
gen_helper_set_rounding_mode(cpu_env, tcg_constant_i32(rm));
121
}
55
}
122
56
123
static void riscv_init_kvm_registers(Object *cpu_obj)
57
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
58
/* Include decoders for factored-out extensions */
125
return ret;
59
#include "decode-XVentanaCondOps.c.inc"
126
}
60
127
61
-static inline void decode_save_opc(DisasContext *ctx, target_ulong opc)
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
62
-{
129
+{
63
- assert(ctx->insn_start != NULL);
130
+ target_ulong reg = 1;
64
- tcg_set_insn_start_param(ctx->insn_start, 1, opc);
131
+
65
- ctx->insn_start = NULL;
132
+ if (!kvm_sbi_dbcn.supported) {
66
-}
133
+ return 0;
67
-
134
+ }
68
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
135
+
136
+ return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
137
+}
138
+
139
int kvm_arch_init_vcpu(CPUState *cs)
140
{
69
{
141
int ret = 0;
70
/*
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
71
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
72
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
73
/* Check for compressed insn */
145
74
if (extract16(opcode, 0, 2) != 3) {
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
75
- decode_save_opc(ctx, opcode);
147
+
76
if (!has_ext(ctx, RVC)) {
148
return ret;
77
gen_exception_illegal(ctx);
149
}
78
} else {
150
79
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
80
opcode32 = deposit32(opcode32, 16, 16,
81
translator_lduw(env, &ctx->base,
82
ctx->base.pc_next + 2));
83
- decode_save_opc(ctx, opcode32);
84
ctx->opcode = opcode32;
85
ctx->pc_succ_insn = ctx->base.pc_next + 4;
86
87
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
88
index XXXXXXX..XXXXXXX 100644
89
--- a/target/riscv/insn_trans/trans_privileged.c.inc
90
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
91
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
92
{
93
#ifndef CONFIG_USER_ONLY
94
if (has_ext(ctx, RVS)) {
95
+ decode_save_opc(ctx);
96
gen_helper_sret(cpu_pc, cpu_env);
97
tcg_gen_exit_tb(NULL, 0); /* no chaining */
98
ctx->base.is_jmp = DISAS_NORETURN;
99
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
100
static bool trans_mret(DisasContext *ctx, arg_mret *a)
101
{
102
#ifndef CONFIG_USER_ONLY
103
+ decode_save_opc(ctx);
104
gen_helper_mret(cpu_pc, cpu_env);
105
tcg_gen_exit_tb(NULL, 0); /* no chaining */
106
ctx->base.is_jmp = DISAS_NORETURN;
107
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
108
static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
109
{
110
#ifndef CONFIG_USER_ONLY
111
+ decode_save_opc(ctx);
112
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
113
gen_helper_wfi(cpu_env);
152
return true;
114
return true;
153
}
115
@@ -XXX,XX +XXX,XX @@ static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
154
116
static bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a)
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
156
+{
157
+ g_autofree uint8_t *buf = NULL;
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
159
+ target_ulong num_bytes;
160
+ uint64_t addr;
161
+ unsigned char ch;
162
+ int ret;
163
+
164
+ switch (run->riscv_sbi.function_id) {
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
167
+ num_bytes = run->riscv_sbi.args[0];
168
+
169
+ if (num_bytes == 0) {
170
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
171
+ run->riscv_sbi.ret[1] = 0;
172
+ break;
173
+ }
174
+
175
+ addr = run->riscv_sbi.args[1];
176
+
177
+ /*
178
+ * Handle the case where a 32 bit CPU is running in a
179
+ * 64 bit addressing env.
180
+ */
181
+ if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
182
+ addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
183
+ }
184
+
185
+ buf = g_malloc0(num_bytes);
186
+
187
+ if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) {
188
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes);
189
+ if (ret < 0) {
190
+ error_report("SBI_EXT_DBCN_CONSOLE_READ: error when "
191
+ "reading chardev");
192
+ exit(1);
193
+ }
194
+
195
+ cpu_physical_memory_write(addr, buf, ret);
196
+ } else {
197
+ cpu_physical_memory_read(addr, buf, num_bytes);
198
+
199
+ ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes);
200
+ if (ret < 0) {
201
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when "
202
+ "writing chardev");
203
+ exit(1);
204
+ }
205
+ }
206
+
207
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
208
+ run->riscv_sbi.ret[1] = ret;
209
+ break;
210
+ case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
211
+ ch = run->riscv_sbi.args[0];
212
+ ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
213
+
214
+ if (ret < 0) {
215
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when "
216
+ "writing chardev");
217
+ exit(1);
218
+ }
219
+
220
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
221
+ run->riscv_sbi.ret[1] = 0;
222
+ break;
223
+ default:
224
+ run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
225
+ }
226
+}
227
+
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
229
{
117
{
230
int ret = 0;
118
#ifndef CONFIG_USER_ONLY
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
119
+ decode_save_opc(ctx);
232
}
120
gen_helper_tlb_flush(cpu_env);
233
ret = 0;
121
return true;
234
break;
122
#endif
235
+ case SBI_EXT_DBCN:
123
diff --git a/target/riscv/insn_trans/trans_rvh.c.inc b/target/riscv/insn_trans/trans_rvh.c.inc
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
124
index XXXXXXX..XXXXXXX 100644
237
+ break;
125
--- a/target/riscv/insn_trans/trans_rvh.c.inc
238
default:
126
+++ b/target/riscv/insn_trans/trans_rvh.c.inc
239
qemu_log_mask(LOG_UNIMP,
127
@@ -XXX,XX +XXX,XX @@ static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
128
{
129
REQUIRE_EXT(ctx, RVH);
130
#ifndef CONFIG_USER_ONLY
131
+ decode_save_opc(ctx);
132
gen_helper_hyp_gvma_tlb_flush(cpu_env);
133
return true;
134
#endif
135
@@ -XXX,XX +XXX,XX @@ static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
136
{
137
REQUIRE_EXT(ctx, RVH);
138
#ifndef CONFIG_USER_ONLY
139
+ decode_save_opc(ctx);
140
gen_helper_hyp_tlb_flush(cpu_env);
141
return true;
142
#endif
143
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
144
index XXXXXXX..XXXXXXX 100644
145
--- a/target/riscv/insn_trans/trans_rvi.c.inc
146
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
147
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
148
149
static bool do_csr_post(DisasContext *ctx)
150
{
151
+ /* The helper may raise ILLEGAL_INSN -- record binv for unwind. */
152
+ decode_save_opc(ctx);
153
/* We may have changed important cpu state -- exit to main loop. */
154
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
155
tcg_gen_exit_tb(NULL, 0);
241
--
156
--
242
2.45.1
157
2.36.1
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Nicolas Pitre <nico@fluxnic.net>
2
2
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
3
For a TOR entry to match, the stard address must be lower than the end
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
4
address. Normally this is always the case, but correct code might still
5
CSRs are part of the disassembly.
5
run into the following scenario:
6
6
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
7
Initial state:
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
9
Fixes: ea10325917 ("RISC-V Disassembler")
9
    pmpaddr3 = 0x2000    pmp3cfg = OFF
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
    pmpaddr4 = 0x3000    pmp4cfg = TOR
11
Cc: qemu-stable <qemu-stable@nongnu.org>
11
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
12
Execution:
13
14
    1. write 0x40ff to pmpaddr3
15
    2. write 0x32ff to pmpaddr4
16
    3. set pmp3cfg to NAPOT with a read-modify-write on pmpcfg0
17
    4. set pmp4cfg to NAPOT with a read-modify-write on pmpcfg1
18
19
When (2) is emulated, a call to pmp_update_rule() creates a negative
20
range for pmp4 as pmp4cfg is still set to TOR. And when (3) is emulated,
21
a call to tlb_flush() is performed, causing pmp_get_tlb_size() to return
22
a very creatively large TLB size for pmp4. This, in turn, may result in
23
accesses to non-existent/unitialized memory regions and a fault, so that
24
(4) ends up never being executed.
25
26
This is in m-mode with MPRV unset, meaning that unlocked PMP entries
27
should have no effect. Therefore such a behavior based on PMP content
28
is very unexpected.
29
30
Make sure no negative PMP range can be created, whether explicitly by
31
the emulated code or implicitly like the above.
32
33
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
34
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
35
Message-Id: <3oq0sqs1-67o0-145-5n1s-453o118804q@syhkavp.arg>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
36
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
37
---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
38
target/riscv/pmp.c | 3 +++
16
1 file changed, 64 insertions(+), 1 deletion(-)
39
1 file changed, 3 insertions(+)
17
40
18
diff --git a/disas/riscv.c b/disas/riscv.c
41
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
19
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.c
43
--- a/target/riscv/pmp.c
21
+++ b/disas/riscv.c
44
+++ b/target/riscv/pmp.c
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
45
@@ -XXX,XX +XXX,XX @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index)
23
case 0x0383: return "mibound";
46
case PMP_AMATCH_TOR:
24
case 0x0384: return "mdbase";
47
sa = prev_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
25
case 0x0385: return "mdbound";
48
ea = (this_addr << 2) - 1u;
26
- case 0x03a0: return "pmpcfg3";
49
+ if (sa > ea) {
27
+ case 0x03a0: return "pmpcfg0";
50
+ sa = ea = 0u;
28
+ case 0x03a1: return "pmpcfg1";
51
+ }
29
+ case 0x03a2: return "pmpcfg2";
52
break;
30
+ case 0x03a3: return "pmpcfg3";
53
31
+ case 0x03a4: return "pmpcfg4";
54
case PMP_AMATCH_NA4:
32
+ case 0x03a5: return "pmpcfg5";
33
+ case 0x03a6: return "pmpcfg6";
34
+ case 0x03a7: return "pmpcfg7";
35
+ case 0x03a8: return "pmpcfg8";
36
+ case 0x03a9: return "pmpcfg9";
37
+ case 0x03aa: return "pmpcfg10";
38
+ case 0x03ab: return "pmpcfg11";
39
+ case 0x03ac: return "pmpcfg12";
40
+ case 0x03ad: return "pmpcfg13";
41
+ case 0x03ae: return "pmpcfg14";
42
+ case 0x03af: return "pmpcfg15";
43
case 0x03b0: return "pmpaddr0";
44
case 0x03b1: return "pmpaddr1";
45
case 0x03b2: return "pmpaddr2";
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
47
case 0x03bd: return "pmpaddr13";
48
case 0x03be: return "pmpaddr14";
49
case 0x03bf: return "pmpaddr15";
50
+ case 0x03c0: return "pmpaddr16";
51
+ case 0x03c1: return "pmpaddr17";
52
+ case 0x03c2: return "pmpaddr18";
53
+ case 0x03c3: return "pmpaddr19";
54
+ case 0x03c4: return "pmpaddr20";
55
+ case 0x03c5: return "pmpaddr21";
56
+ case 0x03c6: return "pmpaddr22";
57
+ case 0x03c7: return "pmpaddr23";
58
+ case 0x03c8: return "pmpaddr24";
59
+ case 0x03c9: return "pmpaddr25";
60
+ case 0x03ca: return "pmpaddr26";
61
+ case 0x03cb: return "pmpaddr27";
62
+ case 0x03cc: return "pmpaddr28";
63
+ case 0x03cd: return "pmpaddr29";
64
+ case 0x03ce: return "pmpaddr30";
65
+ case 0x03cf: return "pmpaddr31";
66
+ case 0x03d0: return "pmpaddr32";
67
+ case 0x03d1: return "pmpaddr33";
68
+ case 0x03d2: return "pmpaddr34";
69
+ case 0x03d3: return "pmpaddr35";
70
+ case 0x03d4: return "pmpaddr36";
71
+ case 0x03d5: return "pmpaddr37";
72
+ case 0x03d6: return "pmpaddr38";
73
+ case 0x03d7: return "pmpaddr39";
74
+ case 0x03d8: return "pmpaddr40";
75
+ case 0x03d9: return "pmpaddr41";
76
+ case 0x03da: return "pmpaddr42";
77
+ case 0x03db: return "pmpaddr43";
78
+ case 0x03dc: return "pmpaddr44";
79
+ case 0x03dd: return "pmpaddr45";
80
+ case 0x03de: return "pmpaddr46";
81
+ case 0x03df: return "pmpaddr47";
82
+ case 0x03e0: return "pmpaddr48";
83
+ case 0x03e1: return "pmpaddr49";
84
+ case 0x03e2: return "pmpaddr50";
85
+ case 0x03e3: return "pmpaddr51";
86
+ case 0x03e4: return "pmpaddr52";
87
+ case 0x03e5: return "pmpaddr53";
88
+ case 0x03e6: return "pmpaddr54";
89
+ case 0x03e7: return "pmpaddr55";
90
+ case 0x03e8: return "pmpaddr56";
91
+ case 0x03e9: return "pmpaddr57";
92
+ case 0x03ea: return "pmpaddr58";
93
+ case 0x03eb: return "pmpaddr59";
94
+ case 0x03ec: return "pmpaddr60";
95
+ case 0x03ed: return "pmpaddr61";
96
+ case 0x03ee: return "pmpaddr62";
97
+ case 0x03ef: return "pmpaddr63";
98
case 0x0780: return "mtohost";
99
case 0x0781: return "mfromhost";
100
case 0x0782: return "mreset";
101
--
55
--
102
2.45.1
56
2.36.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Atish Patra <atish.patra@wdc.com>
2
2
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
3
The predicate function calculates the counter index incorrectly for
4
in bytes, when in this context we want 'reg_width' as the length in
4
hpmcounterx. Fix the counter index to reflect correct CSR number.
5
bits.
6
5
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
6
Fixes: e39a8320b088 ("target/riscv: Support the Virtual Instruction fault")
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
9
beforehand.
10
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
12
clarity about what the variable represents. 'bitsize' is also used in
13
riscv_gen_dynamic_csr_feature() with the same purpose, i.e. as an input to
14
gdb_feature_builder_append_reg().
15
16
Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
17
Cc: Alex Bennée <alex.bennee@linaro.org>
18
Reported-by: Robin Dapp <rdapp.gcc@gmail.com>
19
Fixes: 33a24910ae ("target/riscv: Use GDBFeature for dynamic XML")
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Acked-by: Alex Bennée <alex.bennee@linaro.org>
23
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
9
Signed-off-by: Atish Patra <atish.patra@wdc.com>
10
Signed-off-by: Atish Patra <atishp@rivosinc.com>
11
Message-Id: <20220620231603.2547260-2-atishp@rivosinc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
13
---
29
target/riscv/gdbstub.c | 6 +++---
14
target/riscv/csr.c | 11 +++++++----
30
1 file changed, 3 insertions(+), 3 deletions(-)
15
1 file changed, 7 insertions(+), 4 deletions(-)
31
16
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
17
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
33
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/gdbstub.c
19
--- a/target/riscv/csr.c
35
+++ b/target/riscv/gdbstub.c
20
+++ b/target/riscv/csr.c
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
21
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
22
#if !defined(CONFIG_USER_ONLY)
38
{
23
CPUState *cs = env_cpu(env);
39
RISCVCPU *cpu = RISCV_CPU(cs);
24
RISCVCPU *cpu = RISCV_CPU(cs);
40
- int reg_width = cpu->cfg.vlenb;
25
+ int ctr_index;
41
+ int bitsize = cpu->cfg.vlenb << 3;
26
42
GDBFeatureBuilder builder;
27
if (!cpu->cfg.ext_counters) {
43
int i;
28
/* The Counters extensions is not enabled */
44
29
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
30
}
46
31
break;
47
/* First define types and totals in a whole VL */
32
case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
33
- if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3)) &&
49
- int count = reg_width / vec_lanes[i].size;
34
- get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3))) {
50
+ int count = bitsize / vec_lanes[i].size;
35
+ ctr_index = csrno - CSR_CYCLE;
51
gdb_feature_builder_append_tag(
36
+ if (!get_field(env->hcounteren, 1 << ctr_index) &&
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
37
+ get_field(env->mcounteren, 1 << ctr_index)) {
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
38
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
39
}
55
/* Define vector registers */
40
break;
56
for (i = 0; i < 32; i++) {
41
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
42
}
58
- reg_width, i, "riscv_vector", "vector");
43
break;
59
+ bitsize, i, "riscv_vector", "vector");
44
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
60
}
45
- if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
61
46
- get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
62
gdb_feature_builder_end(&builder);
47
+ ctr_index = csrno - CSR_CYCLEH;
48
+ if (!get_field(env->hcounteren, 1 << ctr_index) &&
49
+ get_field(env->mcounteren, 1 << ctr_index)) {
50
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
51
}
52
break;
63
--
53
--
64
2.45.1
54
2.36.1
65
66
diff view generated by jsdifflib
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
From: Atish Patra <atish.patra@wdc.com>
2
2
3
In AIA spec, each hart (or each hart within a group) has a unique hart
3
Currently, the predicate function for PMU related CSRs only works if
4
number to locate the memory pages of interrupt files in the address
4
virtualization is enabled. It also does not check mcounteren bits before
5
space. The number of bits required to represent any hart number is equal
5
before cycle/minstret/hpmcounterx access.
6
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
7
groups.
8
6
9
However, if the largest hart number among groups is a power of 2, QEMU
7
Support supervisor mode access in the predicate function as well.
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
13
updated to ensure accurate hart-index-bit settings.
14
8
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
17
11
Signed-off-by: Atish Patra <atish.patra@wdc.com>
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
12
Signed-off-by: Atish Patra <atishp@rivosinc.com>
19
13
Message-Id: <20220620231603.2547260-3-atishp@rivosinc.com>
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
15
---
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
16
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++
27
1 file changed, 8 insertions(+), 1 deletion(-)
17
1 file changed, 51 insertions(+)
28
18
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
30
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/kvm/kvm-cpu.c
21
--- a/target/riscv/csr.c
32
+++ b/target/riscv/kvm/kvm-cpu.c
22
+++ b/target/riscv/csr.c
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
23
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
34
}
24
return RISCV_EXCP_ILLEGAL_INST;
35
}
25
}
36
26
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
27
+ if (env->priv == PRV_S) {
38
+
28
+ switch (csrno) {
39
+ if (max_hart_per_socket > 1) {
29
+ case CSR_CYCLE:
40
+ max_hart_per_socket--;
30
+ if (!get_field(env->mcounteren, COUNTEREN_CY)) {
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
31
+ return RISCV_EXCP_ILLEGAL_INST;
42
+ } else {
32
+ }
43
+ hart_bits = 0;
33
+ break;
34
+ case CSR_TIME:
35
+ if (!get_field(env->mcounteren, COUNTEREN_TM)) {
36
+ return RISCV_EXCP_ILLEGAL_INST;
37
+ }
38
+ break;
39
+ case CSR_INSTRET:
40
+ if (!get_field(env->mcounteren, COUNTEREN_IR)) {
41
+ return RISCV_EXCP_ILLEGAL_INST;
42
+ }
43
+ break;
44
+ case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
45
+ ctr_index = csrno - CSR_CYCLE;
46
+ if (!get_field(env->mcounteren, 1 << ctr_index)) {
47
+ return RISCV_EXCP_ILLEGAL_INST;
48
+ }
49
+ break;
50
+ }
51
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
52
+ switch (csrno) {
53
+ case CSR_CYCLEH:
54
+ if (!get_field(env->mcounteren, COUNTEREN_CY)) {
55
+ return RISCV_EXCP_ILLEGAL_INST;
56
+ }
57
+ break;
58
+ case CSR_TIMEH:
59
+ if (!get_field(env->mcounteren, COUNTEREN_TM)) {
60
+ return RISCV_EXCP_ILLEGAL_INST;
61
+ }
62
+ break;
63
+ case CSR_INSTRETH:
64
+ if (!get_field(env->mcounteren, COUNTEREN_IR)) {
65
+ return RISCV_EXCP_ILLEGAL_INST;
66
+ }
67
+ break;
68
+ case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
69
+ ctr_index = csrno - CSR_CYCLEH;
70
+ if (!get_field(env->mcounteren, 1 << ctr_index)) {
71
+ return RISCV_EXCP_ILLEGAL_INST;
72
+ }
73
+ break;
74
+ }
75
+ }
44
+ }
76
+ }
45
+
77
+
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
78
if (riscv_cpu_virt_enabled(env)) {
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
79
switch (csrno) {
48
&hart_bits, true, NULL);
80
case CSR_CYCLE:
49
--
81
--
50
2.45.1
82
2.36.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Atish Patra <atish.patra@wdc.com>
2
2
3
Add support for Zve32x extension and replace some checks for Zve32f with
3
The PMU counters are supported via cpu config "Counters" which doesn't
4
Zve32x, since Zve32f depends on Zve32x.
4
indicate the correct purpose of those counters.
5
5
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
Rename the config property to pmu to indicate that these counters
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
are performance monitoring counters. This aligns with cpu options for
8
Reviewed-by: Max Chou <max.chou@sifive.com>
8
ARM architecture as well.
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Atish Patra <atish.patra@wdc.com>
13
Signed-off-by: Atish Patra <atishp@rivosinc.com>
14
Message-Id: <20220620231603.2547260-4-atishp@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
16
---
13
target/riscv/cpu_cfg.h | 1 +
17
target/riscv/cpu.h | 2 +-
14
target/riscv/cpu.c | 2 ++
18
target/riscv/cpu.c | 4 ++--
15
target/riscv/cpu_helper.c | 2 +-
19
target/riscv/csr.c | 4 ++--
16
target/riscv/csr.c | 2 +-
20
3 files changed, 5 insertions(+), 5 deletions(-)
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
19
6 files changed, 15 insertions(+), 12 deletions(-)
20
21
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_cfg.h
24
--- a/target/riscv/cpu.h
24
+++ b/target/riscv/cpu_cfg.h
25
+++ b/target/riscv/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_zhinx;
27
bool ext_zksed;
27
bool ext_zhinxmin;
28
bool ext_zksh;
28
bool ext_zve32f;
29
bool ext_zkt;
29
+ bool ext_zve32x;
30
- bool ext_counters;
30
bool ext_zve64f;
31
+ bool ext_pmu;
31
bool ext_zve64d;
32
bool ext_ifencei;
32
bool ext_zvbb;
33
bool ext_icsr;
34
bool ext_svinval;
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
35
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
37
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
38
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
39
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_init(Object *obj)
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
40
{
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
41
RISCVCPU *cpu = RISCV_CPU(obj);
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
42
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
43
- cpu->cfg.ext_counters = true;
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
44
+ cpu->cfg.ext_pmu = true;
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
45
cpu->cfg.ext_ifencei = true;
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
46
cpu->cfg.ext_icsr = true;
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
47
cpu->cfg.mmu = true;
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
48
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
49
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
50
DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
51
DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
52
- DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
53
+ DEFINE_PROP_BOOL("pmu", RISCVCPU, cfg.ext_pmu, true),
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
54
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
55
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
54
index XXXXXXX..XXXXXXX 100644
56
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
55
--- a/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
59
*cs_base = 0;
60
61
- if (cpu->cfg.ext_zve32f) {
62
+ if (cpu->cfg.ext_zve32x) {
63
/*
64
* If env->vl equals to VLMAX, we can use generic vector operation
65
* expanders (GVEC) to accerlate the vector operations.
66
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
57
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
67
index XXXXXXX..XXXXXXX 100644
58
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/csr.c
59
--- a/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
60
+++ b/target/riscv/csr.c
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
61
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
71
62
RISCVCPU *cpu = RISCV_CPU(cs);
72
static RISCVException vs(CPURISCVState *env, int csrno)
63
int ctr_index;
73
{
64
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
65
- if (!cpu->cfg.ext_counters) {
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
66
- /* The Counters extensions is not enabled */
76
#if !defined(CONFIG_USER_ONLY)
67
+ if (!cpu->cfg.ext_pmu) {
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
68
+ /* The PMU extension is not enabled */
78
return RISCV_EXCP_ILLEGAL_INST;
69
return RISCV_EXCP_ILLEGAL_INST;
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/riscv/tcg/tcg-cpu.c
82
+++ b/target/riscv/tcg/tcg-cpu.c
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
84
return;
85
}
70
}
86
71
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
89
- return;
90
+ /* The Zve32f extension depends on the Zve32x extension */
91
+ if (cpu->cfg.ext_zve32f) {
92
+ if (!riscv_has_ext(env, RVF)) {
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
94
+ return;
95
+ }
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
97
}
98
99
if (cpu->cfg.ext_zvfh) {
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
102
}
103
104
- /*
105
- * In principle Zve*x would also suffice here, were they supported
106
- * in qemu
107
- */
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
109
cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
110
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
111
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
112
error_setg(errp,
113
"Vector crypto extensions require V or Zve* extensions");
114
return;
115
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/insn_trans/trans_rvv.c.inc
118
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
119
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
120
{
121
TCGv s1, dst;
122
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
129
{
130
TCGv dst;
131
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
134
return false;
135
}
136
137
--
72
--
138
2.45.1
73
2.36.1
diff view generated by jsdifflib
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
In this patch, we modify the decoder to be a freely composable data
3
The RISC-V privilege specification provides flexibility to implement
4
structure instead of a hardcoded one. It can be dynamically builded up
4
any number of counters from 29 programmable counters. However, the QEMU
5
according to the extensions.
5
implements all the counters.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
20
6
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
7
Make it configurable through pmu config parameter which now will indicate
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
8
how many programmable counters should be implemented by the cpu.
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
12
Signed-off-by: Atish Patra <atish.patra@wdc.com>
13
Signed-off-by: Atish Patra <atishp@rivosinc.com>
14
Message-Id: <20220620231603.2547260-5-atishp@rivosinc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
16
---
29
target/riscv/cpu.h | 1 +
17
target/riscv/cpu.h | 2 +-
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
18
target/riscv/cpu.c | 3 +-
31
target/riscv/cpu.c | 1 +
19
target/riscv/csr.c | 94 ++++++++++++++++++++++++++++++----------------
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
20
3 files changed, 63 insertions(+), 36 deletions(-)
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
35
21
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
37
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu.h
24
--- a/target/riscv/cpu.h
39
+++ b/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
26
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
41
uint32_t pmu_avail_ctrs;
27
bool ext_zksed;
42
/* Mapping of events to counters */
28
bool ext_zksh;
43
GHashTable *pmu_event_ctr_map;
29
bool ext_zkt;
44
+ const GPtrArray *decoders;
30
- bool ext_pmu;
45
};
31
bool ext_ifencei;
46
32
bool ext_icsr;
47
/**
33
bool ext_svinval;
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
34
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
49
index XXXXXXX..XXXXXXX 100644
35
/* Vendor-specific custom extensions */
50
--- a/target/riscv/tcg/tcg-cpu.h
36
bool ext_XVentanaCondOps;
51
+++ b/target/riscv/tcg/tcg-cpu.h
37
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
38
+ uint8_t pmu_num;
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
39
char *priv_spec;
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
40
char *user_spec;
55
41
char *bext_spec;
56
+struct DisasContext;
57
+struct RISCVCPUConfig;
58
+typedef struct RISCVDecoder {
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
61
+} RISCVDecoder;
62
+
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
64
+
65
+extern const size_t decoder_table_size;
66
+
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
42
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
73
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu.c
44
--- a/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
45
+++ b/target/riscv/cpu.c
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
46
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_init(Object *obj)
77
error_propagate(errp, local_err);
47
{
78
return;
48
RISCVCPU *cpu = RISCV_CPU(obj);
49
50
- cpu->cfg.ext_pmu = true;
51
cpu->cfg.ext_ifencei = true;
52
cpu->cfg.ext_icsr = true;
53
cpu->cfg.mmu = true;
54
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
55
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
56
DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
57
DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
58
- DEFINE_PROP_BOOL("pmu", RISCVCPU, cfg.ext_pmu, true),
59
+ DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
60
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
61
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
62
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
63
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/riscv/csr.c
66
+++ b/target/riscv/csr.c
67
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
68
CPUState *cs = env_cpu(env);
69
RISCVCPU *cpu = RISCV_CPU(cs);
70
int ctr_index;
71
+ int base_csrno = CSR_HPMCOUNTER3;
72
+ bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
73
74
- if (!cpu->cfg.ext_pmu) {
75
- /* The PMU extension is not enabled */
76
+ if (rv32 && csrno >= CSR_CYCLEH) {
77
+ /* Offset for RV32 hpmcounternh counters */
78
+ base_csrno += 0x80;
79
+ }
80
+ ctr_index = csrno - base_csrno;
81
+
82
+ if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) {
83
+ /* No counter is enabled in PMU or the counter is out of range */
84
return RISCV_EXCP_ILLEGAL_INST;
85
}
86
87
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
88
}
89
break;
79
}
90
}
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
91
- if (riscv_cpu_mxl(env) == MXL_RV32) {
81
} else if (kvm_enabled()) {
92
+ if (rv32) {
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
93
switch (csrno) {
83
if (local_err != NULL) {
94
case CSR_CYCLEH:
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
95
if (!get_field(env->mcounteren, COUNTEREN_CY)) {
85
index XXXXXXX..XXXXXXX 100644
96
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
86
--- a/target/riscv/tcg/tcg-cpu.c
97
}
87
+++ b/target/riscv/tcg/tcg-cpu.c
98
break;
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
99
}
89
}
100
- if (riscv_cpu_mxl(env) == MXL_RV32) {
101
+ if (rv32) {
102
switch (csrno) {
103
case CSR_CYCLEH:
104
if (!get_field(env->hcounteren, COUNTEREN_CY) &&
105
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr32(CPURISCVState *env, int csrno)
90
}
106
}
91
107
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
108
#if !defined(CONFIG_USER_ONLY)
109
+static RISCVException mctr(CPURISCVState *env, int csrno)
93
+{
110
+{
94
+ GPtrArray *dynamic_decoders;
111
+ CPUState *cs = env_cpu(env);
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
112
+ RISCVCPU *cpu = RISCV_CPU(cs);
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
113
+ int ctr_index;
97
+ if (decoder_table[i].guard_func &&
114
+ int base_csrno = CSR_MHPMCOUNTER3;
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
115
+
99
+ g_ptr_array_add(dynamic_decoders,
116
+ if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) {
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
117
+ /* Offset for RV32 mhpmcounternh counters */
101
+ }
118
+ base_csrno += 0x80;
119
+ }
120
+ ctr_index = csrno - base_csrno;
121
+ if (!cpu->cfg.pmu_num || ctr_index >= cpu->cfg.pmu_num) {
122
+ /* The PMU is not enabled or counter is out of range*/
123
+ return RISCV_EXCP_ILLEGAL_INST;
102
+ }
124
+ }
103
+
125
+
104
+ cpu->decoders = dynamic_decoders;
126
+ return RISCV_EXCP_NONE;
105
+}
127
+}
106
+
128
+
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
129
static RISCVException any(CPURISCVState *env, int csrno)
108
{
130
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
131
return RISCV_EXCP_NONE;
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
132
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
111
index XXXXXXX..XXXXXXX 100644
133
[CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero },
112
--- a/target/riscv/translate.c
134
[CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero },
113
+++ b/target/riscv/translate.c
135
114
@@ -XXX,XX +XXX,XX @@
136
- [CSR_MHPMCOUNTER3] = { "mhpmcounter3", any, read_zero },
115
#include "exec/helper-info.c.inc"
137
- [CSR_MHPMCOUNTER4] = { "mhpmcounter4", any, read_zero },
116
#undef HELPER_H
138
- [CSR_MHPMCOUNTER5] = { "mhpmcounter5", any, read_zero },
117
139
- [CSR_MHPMCOUNTER6] = { "mhpmcounter6", any, read_zero },
118
+#include "tcg/tcg-cpu.h"
140
- [CSR_MHPMCOUNTER7] = { "mhpmcounter7", any, read_zero },
119
+
141
- [CSR_MHPMCOUNTER8] = { "mhpmcounter8", any, read_zero },
120
/* global register indices */
142
- [CSR_MHPMCOUNTER9] = { "mhpmcounter9", any, read_zero },
121
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
143
- [CSR_MHPMCOUNTER10] = { "mhpmcounter10", any, read_zero },
122
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
144
- [CSR_MHPMCOUNTER11] = { "mhpmcounter11", any, read_zero },
123
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
145
- [CSR_MHPMCOUNTER12] = { "mhpmcounter12", any, read_zero },
124
/* FRM is known to contain a valid value. */
146
- [CSR_MHPMCOUNTER13] = { "mhpmcounter13", any, read_zero },
125
bool frm_valid;
147
- [CSR_MHPMCOUNTER14] = { "mhpmcounter14", any, read_zero },
126
bool insn_start_updated;
148
- [CSR_MHPMCOUNTER15] = { "mhpmcounter15", any, read_zero },
127
+ const GPtrArray *decoders;
149
- [CSR_MHPMCOUNTER16] = { "mhpmcounter16", any, read_zero },
128
} DisasContext;
150
- [CSR_MHPMCOUNTER17] = { "mhpmcounter17", any, read_zero },
129
151
- [CSR_MHPMCOUNTER18] = { "mhpmcounter18", any, read_zero },
130
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
152
- [CSR_MHPMCOUNTER19] = { "mhpmcounter19", any, read_zero },
131
@@ -XXX,XX +XXX,XX @@ static inline int insn_len(uint16_t first_word)
153
- [CSR_MHPMCOUNTER20] = { "mhpmcounter20", any, read_zero },
132
return (first_word & 3) == 3 ? 4 : 2;
154
- [CSR_MHPMCOUNTER21] = { "mhpmcounter21", any, read_zero },
133
}
155
- [CSR_MHPMCOUNTER22] = { "mhpmcounter22", any, read_zero },
134
156
- [CSR_MHPMCOUNTER23] = { "mhpmcounter23", any, read_zero },
135
+const RISCVDecoder decoder_table[] = {
157
- [CSR_MHPMCOUNTER24] = { "mhpmcounter24", any, read_zero },
136
+ { always_true_p, decode_insn32 },
158
- [CSR_MHPMCOUNTER25] = { "mhpmcounter25", any, read_zero },
137
+ { has_xthead_p, decode_xthead},
159
- [CSR_MHPMCOUNTER26] = { "mhpmcounter26", any, read_zero },
138
+ { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
160
- [CSR_MHPMCOUNTER27] = { "mhpmcounter27", any, read_zero },
139
+};
161
- [CSR_MHPMCOUNTER28] = { "mhpmcounter28", any, read_zero },
140
+
162
- [CSR_MHPMCOUNTER29] = { "mhpmcounter29", any, read_zero },
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
163
- [CSR_MHPMCOUNTER30] = { "mhpmcounter30", any, read_zero },
142
+
164
- [CSR_MHPMCOUNTER31] = { "mhpmcounter31", any, read_zero },
143
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
165
+ [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_zero },
144
{
166
+ [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_zero },
145
- /*
167
+ [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_zero },
146
- * A table with predicate (i.e., guard) functions and decoder functions
168
+ [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_zero },
147
- * that are tested in-order until a decoder matches onto the opcode.
169
+ [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_zero },
148
- */
170
+ [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_zero },
149
- static const struct {
171
+ [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_zero },
150
- bool (*guard_func)(const RISCVCPUConfig *);
172
+ [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_zero },
151
- bool (*decode_func)(DisasContext *, uint32_t);
173
+ [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_zero },
152
- } decoders[] = {
174
+ [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_zero },
153
- { always_true_p, decode_insn32 },
175
+ [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_zero },
154
- { has_xthead_p, decode_xthead },
176
+ [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_zero },
155
- { has_XVentanaCondOps_p, decode_XVentanaCodeOps },
177
+ [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_zero },
156
- };
178
+ [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_zero },
157
-
179
+ [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_zero },
158
ctx->virt_inst_excp = false;
180
+ [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_zero },
159
ctx->cur_insn_len = insn_len(opcode);
181
+ [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_zero },
160
/* Check for compressed insn */
182
+ [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_zero },
161
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
183
+ [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_zero },
162
ctx->base.pc_next + 2));
184
+ [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_zero },
163
ctx->opcode = opcode32;
185
+ [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_zero },
164
186
+ [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_zero },
165
- for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
187
+ [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_zero },
166
- if (decoders[i].guard_func(ctx->cfg_ptr) &&
188
+ [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_zero },
167
- decoders[i].decode_func(ctx, opcode32)) {
189
+ [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_zero },
168
+ for (guint i = 0; i < ctx->decoders->len; ++i) {
190
+ [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_zero },
169
+ riscv_cpu_decode_fn func = g_ptr_array_index(ctx->decoders, i);
191
+ [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_zero },
170
+ if (func(ctx, opcode32)) {
192
+ [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_zero },
171
return;
193
+ [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_zero },
172
}
194
173
}
195
[CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero },
174
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
196
[CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero },
175
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
176
ctx->zero = tcg_constant_tl(0);
177
ctx->virt_inst_excp = false;
178
+ ctx->decoders = cpu->decoders;
179
}
180
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
182
--
197
--
183
2.45.1
198
2.36.1
diff view generated by jsdifflib
1
From: Yu-Ming Chang <yumin686@andestech.com>
1
From: Atish Patra <atish.patra@wdc.com>
2
2
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
3
As per the privilege specification v1.11, mcountinhibit allows to start/stop
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
4
a pmu counter selectively.
5
holding a zero value other than x0, the instruction will still attempt to write
6
the unmodified value back to the CSR and will cause any attendant side effects.
7
5
8
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
a register holding a zero value, an illegal instruction exception should be
10
raised.
11
12
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
8
Signed-off-by: Atish Patra <atish.patra@wdc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <20220620231603.2547260-6-atishp@rivosinc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
12
---
17
target/riscv/cpu.h | 4 ++++
13
target/riscv/cpu.h | 2 ++
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
14
target/riscv/cpu_bits.h | 4 ++++
19
target/riscv/op_helper.c | 6 ++---
15
target/riscv/csr.c | 25 +++++++++++++++++++++++++
20
3 files changed, 53 insertions(+), 8 deletions(-)
16
target/riscv/machine.c | 1 +
17
4 files changed, 32 insertions(+)
21
18
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.h
21
--- a/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
23
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
27
void riscv_cpu_update_mask(CPURISCVState *env);
24
target_ulong scounteren;
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
25
target_ulong mcounteren;
29
26
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
27
+ target_ulong mcountinhibit;
31
+ target_ulong *ret_value);
28
+
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
29
target_ulong sscratch;
33
target_ulong *ret_value,
30
target_ulong mscratch;
34
target_ulong new_value, target_ulong write_mask);
31
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
32
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
36
target_ulong new_value,
33
index XXXXXXX..XXXXXXX 100644
37
target_ulong write_mask);
34
--- a/target/riscv/cpu_bits.h
38
35
+++ b/target/riscv/cpu_bits.h
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
36
@@ -XXX,XX +XXX,XX @@
40
+ Int128 *ret_value);
37
#define CSR_MHPMCOUNTER29 0xb1d
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
38
#define CSR_MHPMCOUNTER30 0xb1e
42
Int128 *ret_value,
39
#define CSR_MHPMCOUNTER31 0xb1f
43
Int128 new_value, Int128 write_mask);
40
+
41
+/* Machine counter-inhibit register */
42
+#define CSR_MCOUNTINHIBIT 0x320
43
+
44
#define CSR_MHPMEVENT3 0x323
45
#define CSR_MHPMEVENT4 0x324
46
#define CSR_MHPMEVENT5 0x325
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
47
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
45
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/csr.c
49
--- a/target/riscv/csr.c
47
+++ b/target/riscv/csr.c
50
+++ b/target/riscv/csr.c
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
51
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mtvec(CPURISCVState *env, int csrno,
49
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
51
int csrno,
52
- bool write_mask)
53
+ bool write)
54
{
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
56
bool read_only = get_field(csrno, 0xC00) == 3;
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
58
}
59
60
/* read / write check */
61
- if (write_mask && read_only) {
62
+ if (write && read_only) {
63
return RISCV_EXCP_ILLEGAL_INST;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
67
return RISCV_EXCP_NONE;
52
return RISCV_EXCP_NONE;
68
}
53
}
69
54
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
55
+static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
71
+ target_ulong *ret_value)
56
+ target_ulong *val)
72
+{
57
+{
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
58
+ if (env->priv_ver < PRIV_VERSION_1_11_0) {
74
+ if (ret != RISCV_EXCP_NONE) {
59
+ return RISCV_EXCP_ILLEGAL_INST;
75
+ return ret;
76
+ }
60
+ }
77
+
61
+
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
62
+ *val = env->mcountinhibit;
63
+ return RISCV_EXCP_NONE;
79
+}
64
+}
80
+
65
+
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
66
+static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
82
target_ulong *ret_value,
67
+ target_ulong val)
83
target_ulong new_value, target_ulong write_mask)
84
{
85
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
86
+ RISCVException ret = riscv_csrrw_check(env, csrno, true);
87
if (ret != RISCV_EXCP_NONE) {
88
return ret;
89
}
90
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
91
return RISCV_EXCP_NONE;
92
}
93
94
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
95
+ Int128 *ret_value)
96
+{
68
+{
97
+ RISCVException ret;
69
+ if (env->priv_ver < PRIV_VERSION_1_11_0) {
98
+
70
+ return RISCV_EXCP_ILLEGAL_INST;
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
102
+ }
71
+ }
103
+
72
+
104
+ if (csr_ops[csrno].read128) {
73
+ env->mcountinhibit = val;
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
74
+ return RISCV_EXCP_NONE;
106
+ int128_zero(), int128_zero());
107
+ }
108
+
109
+ /*
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
111
+ * at all defined.
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
113
+ * significant), for those, this fallback is correctly handling the
114
+ * accesses
115
+ */
116
+ target_ulong old_value;
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
118
+ (target_ulong)0,
119
+ (target_ulong)0);
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
121
+ *ret_value = int128_make64(old_value);
122
+ }
123
+ return ret;
124
+}
75
+}
125
+
76
+
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
77
static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
127
Int128 *ret_value,
78
target_ulong *val)
128
Int128 new_value, Int128 write_mask)
129
{
79
{
130
RISCVException ret;
80
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
131
81
[CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_zero },
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
82
[CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_zero },
133
+ ret = riscv_csrrw_check(env, csrno, true);
83
134
if (ret != RISCV_EXCP_NONE) {
84
+ [CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
135
return ret;
85
+ write_mcountinhibit },
136
}
86
+
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
87
[CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero },
88
[CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero },
89
[CSR_MHPMEVENT5] = { "mhpmevent5", any, read_zero },
90
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
138
index XXXXXXX..XXXXXXX 100644
91
index XXXXXXX..XXXXXXX 100644
139
--- a/target/riscv/op_helper.c
92
--- a/target/riscv/machine.c
140
+++ b/target/riscv/op_helper.c
93
+++ b/target/riscv/machine.c
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
94
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
142
}
95
VMSTATE_UINTTL(env.siselect, RISCVCPU),
143
96
VMSTATE_UINTTL(env.scounteren, RISCVCPU),
144
target_ulong val = 0;
97
VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
98
+ VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
99
VMSTATE_UINTTL(env.sscratch, RISCVCPU),
147
100
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
148
if (ret != RISCV_EXCP_NONE) {
101
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
149
riscv_raise_exception(env, ret, GETPC());
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
152
{
153
Int128 rv = int128_zero();
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
155
- int128_zero(),
156
- int128_zero());
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
158
159
if (ret != RISCV_EXCP_NONE) {
160
riscv_raise_exception(env, ret, GETPC());
161
--
102
--
162
2.45.1
103
2.36.1
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Atish Patra <atish.patra@wdc.com>
2
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
3
With SBI PMU extension, user can use any of the available hpmcounters to
4
implements the SEED CSR. Use the same implementation as TCG.
4
track any perf events based on the value written to mhpmevent csr.
5
Add read/write functionality for these csrs.
5
6
6
Without this patch, running with a KVM which does not forward the
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
SEED CSR access to QEMU will result in an ILL exception being
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
injected into the guest (this results in Linux guests crashing on
9
Signed-off-by: Atish Patra <atish.patra@wdc.com>
9
boot). And, when running with a KVM which does forward the access,
10
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
QEMU will crash, since QEMU doesn't know what to do with the exit.
11
Message-Id: <20220620231603.2547260-7-atishp@rivosinc.com>
11
12
Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
13
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Cc: qemu-stable <qemu-stable@nongnu.org>
16
Message-ID: <20240422134605.534207-2-ajones@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
13
---
19
target/riscv/cpu.h | 3 +++
14
target/riscv/cpu.h | 11 +
20
target/riscv/csr.c | 18 ++++++++++++++----
15
target/riscv/csr.c | 469 ++++++++++++++++++++++++++++-------------
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
16
target/riscv/machine.c | 3 +
22
3 files changed, 42 insertions(+), 4 deletions(-)
17
3 files changed, 331 insertions(+), 152 deletions(-)
23
18
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
21
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
23
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState CPURISCVState;
29
24
#endif
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
25
31
26
#define RV_VLEN_MAX 1024
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
27
+#define RV_MAX_MHPMEVENTS 29
33
+ target_ulong write_mask);
28
+#define RV_MAX_MHPMCOUNTERS 32
34
+
29
35
uint8_t satp_mode_max_from_map(uint32_t map);
30
FIELD(VTYPE, VLMUL, 0, 3)
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
31
FIELD(VTYPE, VSEW, 3, 3)
32
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
33
34
target_ulong mcountinhibit;
35
36
+ /* PMU counter configured values */
37
+ target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS];
38
+
39
+ /* for RV32 */
40
+ target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS];
41
+
42
+ /* PMU event selector configured values */
43
+ target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
44
+
45
target_ulong sscratch;
46
target_ulong mscratch;
37
47
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
48
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
39
index XXXXXXX..XXXXXXX 100644
49
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/csr.c
50
--- a/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
51
+++ b/target/riscv/csr.c
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
52
@@ -XXX,XX +XXX,XX @@ static RISCVException mctr(CPURISCVState *env, int csrno)
43
#endif
53
return RISCV_EXCP_NONE;
44
54
}
45
/* Crypto Extension */
55
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
56
+static RISCVException mctr32(CPURISCVState *env, int csrno)
47
- target_ulong *ret_value,
57
+{
48
- target_ulong new_value,
58
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
49
- target_ulong write_mask)
59
+ return RISCV_EXCP_ILLEGAL_INST;
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
60
+ }
51
+ target_ulong write_mask)
61
+
62
+ return mctr(env, csrno);
63
+}
64
+
65
static RISCVException any(CPURISCVState *env, int csrno)
52
{
66
{
53
uint16_t random_v;
67
return RISCV_EXCP_NONE;
54
Error *random_e = NULL;
68
@@ -XXX,XX +XXX,XX @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
69
56
rval = random_v | SEED_OPST_ES16;
70
#else /* CONFIG_USER_ONLY */
57
}
71
58
72
+static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
59
+ return rval;
73
+{
60
+}
74
+ int evt_index = csrno - CSR_MHPMEVENT3;
61
+
75
+
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
76
+ *val = env->mhpmevent_val[evt_index];
63
+ target_ulong *ret_value,
77
+
64
+ target_ulong new_value,
78
+ return RISCV_EXCP_NONE;
65
+ target_ulong write_mask)
79
+}
66
+{
80
+
67
+ target_ulong rval;
81
+static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
68
+
82
+{
69
+ rval = riscv_new_csr_seed(new_value, write_mask);
83
+ int evt_index = csrno - CSR_MHPMEVENT3;
70
+
84
+
71
if (ret_value) {
85
+ env->mhpmevent_val[evt_index] = val;
72
*ret_value = rval;
86
+
73
}
87
+ return RISCV_EXCP_NONE;
74
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
88
+}
89
+
90
+static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
91
+{
92
+ int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
93
+
94
+ env->mhpmcounter_val[ctr_index] = val;
95
+
96
+ return RISCV_EXCP_NONE;
97
+}
98
+
99
+static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
100
+{
101
+ int ctr_index = csrno - CSR_MHPMCOUNTER3H + 3;
102
+
103
+ env->mhpmcounterh_val[ctr_index] = val;
104
+
105
+ return RISCV_EXCP_NONE;
106
+}
107
+
108
+static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
109
+{
110
+ int ctr_index;
111
+
112
+ if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
113
+ ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
114
+ } else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
115
+ ctr_index = csrno - CSR_HPMCOUNTER3 + 3;
116
+ } else {
117
+ return RISCV_EXCP_ILLEGAL_INST;
118
+ }
119
+ *val = env->mhpmcounter_val[ctr_index];
120
+
121
+ return RISCV_EXCP_NONE;
122
+}
123
+
124
+static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
125
+{
126
+ int ctr_index;
127
+
128
+ if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
129
+ ctr_index = csrno - CSR_MHPMCOUNTER3H + 3;
130
+ } else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
131
+ ctr_index = csrno - CSR_HPMCOUNTER3H + 3;
132
+ } else {
133
+ return RISCV_EXCP_ILLEGAL_INST;
134
+ }
135
+ *val = env->mhpmcounterh_val[ctr_index];
136
+
137
+ return RISCV_EXCP_NONE;
138
+}
139
+
140
+
141
static RISCVException read_time(CPURISCVState *env, int csrno,
142
target_ulong *val)
143
{
144
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
145
[CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase, write_spmbase },
146
147
/* Performance Counters */
148
- [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_zero },
149
- [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_zero },
150
- [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_zero },
151
- [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_zero },
152
- [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_zero },
153
- [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_zero },
154
- [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_zero },
155
- [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_zero },
156
- [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_zero },
157
- [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_zero },
158
- [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_zero },
159
- [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_zero },
160
- [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_zero },
161
- [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_zero },
162
- [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_zero },
163
- [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_zero },
164
- [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_zero },
165
- [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_zero },
166
- [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_zero },
167
- [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_zero },
168
- [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_zero },
169
- [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_zero },
170
- [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_zero },
171
- [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_zero },
172
- [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_zero },
173
- [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_zero },
174
- [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_zero },
175
- [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_zero },
176
- [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_zero },
177
-
178
- [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_zero },
179
- [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_zero },
180
- [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_zero },
181
- [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_zero },
182
- [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_zero },
183
- [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_zero },
184
- [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_zero },
185
- [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_zero },
186
- [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_zero },
187
- [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_zero },
188
- [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_zero },
189
- [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_zero },
190
- [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_zero },
191
- [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_zero },
192
- [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_zero },
193
- [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_zero },
194
- [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_zero },
195
- [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_zero },
196
- [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_zero },
197
- [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_zero },
198
- [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_zero },
199
- [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_zero },
200
- [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_zero },
201
- [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_zero },
202
- [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_zero },
203
- [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_zero },
204
- [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_zero },
205
- [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_zero },
206
- [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_zero },
207
-
208
- [CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
209
- write_mcountinhibit },
210
-
211
- [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_zero },
212
- [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_zero },
213
- [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_zero },
214
- [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_zero },
215
- [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_zero },
216
- [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_zero },
217
- [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_zero },
218
- [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_zero },
219
- [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_zero },
220
- [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_zero },
221
- [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_zero },
222
- [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_zero },
223
- [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_zero },
224
- [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_zero },
225
- [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_zero },
226
- [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_zero },
227
- [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_zero },
228
- [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_zero },
229
- [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_zero },
230
- [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_zero },
231
- [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_zero },
232
- [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_zero },
233
- [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_zero },
234
- [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_zero },
235
- [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_zero },
236
- [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_zero },
237
- [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_zero },
238
- [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_zero },
239
- [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_zero },
240
-
241
- [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_zero },
242
- [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_zero },
243
- [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_zero },
244
- [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_zero },
245
- [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_zero },
246
- [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_zero },
247
- [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_zero },
248
- [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_zero },
249
- [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_zero },
250
- [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_zero },
251
- [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_zero },
252
- [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_zero },
253
- [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_zero },
254
- [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_zero },
255
- [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_zero },
256
- [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_zero },
257
- [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_zero },
258
- [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_zero },
259
- [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_zero },
260
- [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_zero },
261
- [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_zero },
262
- [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_zero },
263
- [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_zero },
264
- [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_zero },
265
- [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_zero },
266
- [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_zero },
267
- [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_zero },
268
- [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_zero },
269
- [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_zero },
270
-
271
- [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", any32, read_zero },
272
- [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", any32, read_zero },
273
- [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", any32, read_zero },
274
- [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", any32, read_zero },
275
- [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", any32, read_zero },
276
- [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", any32, read_zero },
277
- [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", any32, read_zero },
278
- [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", any32, read_zero },
279
- [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", any32, read_zero },
280
- [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", any32, read_zero },
281
- [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", any32, read_zero },
282
- [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", any32, read_zero },
283
- [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", any32, read_zero },
284
- [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", any32, read_zero },
285
- [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", any32, read_zero },
286
- [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", any32, read_zero },
287
- [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", any32, read_zero },
288
- [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", any32, read_zero },
289
- [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", any32, read_zero },
290
- [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", any32, read_zero },
291
- [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", any32, read_zero },
292
- [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", any32, read_zero },
293
- [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", any32, read_zero },
294
- [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", any32, read_zero },
295
- [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", any32, read_zero },
296
- [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", any32, read_zero },
297
- [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", any32, read_zero },
298
- [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", any32, read_zero },
299
- [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", any32, read_zero },
300
+ [CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter },
301
+ [CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_hpmcounter },
302
+ [CSR_HPMCOUNTER5] = { "hpmcounter5", ctr, read_hpmcounter },
303
+ [CSR_HPMCOUNTER6] = { "hpmcounter6", ctr, read_hpmcounter },
304
+ [CSR_HPMCOUNTER7] = { "hpmcounter7", ctr, read_hpmcounter },
305
+ [CSR_HPMCOUNTER8] = { "hpmcounter8", ctr, read_hpmcounter },
306
+ [CSR_HPMCOUNTER9] = { "hpmcounter9", ctr, read_hpmcounter },
307
+ [CSR_HPMCOUNTER10] = { "hpmcounter10", ctr, read_hpmcounter },
308
+ [CSR_HPMCOUNTER11] = { "hpmcounter11", ctr, read_hpmcounter },
309
+ [CSR_HPMCOUNTER12] = { "hpmcounter12", ctr, read_hpmcounter },
310
+ [CSR_HPMCOUNTER13] = { "hpmcounter13", ctr, read_hpmcounter },
311
+ [CSR_HPMCOUNTER14] = { "hpmcounter14", ctr, read_hpmcounter },
312
+ [CSR_HPMCOUNTER15] = { "hpmcounter15", ctr, read_hpmcounter },
313
+ [CSR_HPMCOUNTER16] = { "hpmcounter16", ctr, read_hpmcounter },
314
+ [CSR_HPMCOUNTER17] = { "hpmcounter17", ctr, read_hpmcounter },
315
+ [CSR_HPMCOUNTER18] = { "hpmcounter18", ctr, read_hpmcounter },
316
+ [CSR_HPMCOUNTER19] = { "hpmcounter19", ctr, read_hpmcounter },
317
+ [CSR_HPMCOUNTER20] = { "hpmcounter20", ctr, read_hpmcounter },
318
+ [CSR_HPMCOUNTER21] = { "hpmcounter21", ctr, read_hpmcounter },
319
+ [CSR_HPMCOUNTER22] = { "hpmcounter22", ctr, read_hpmcounter },
320
+ [CSR_HPMCOUNTER23] = { "hpmcounter23", ctr, read_hpmcounter },
321
+ [CSR_HPMCOUNTER24] = { "hpmcounter24", ctr, read_hpmcounter },
322
+ [CSR_HPMCOUNTER25] = { "hpmcounter25", ctr, read_hpmcounter },
323
+ [CSR_HPMCOUNTER26] = { "hpmcounter26", ctr, read_hpmcounter },
324
+ [CSR_HPMCOUNTER27] = { "hpmcounter27", ctr, read_hpmcounter },
325
+ [CSR_HPMCOUNTER28] = { "hpmcounter28", ctr, read_hpmcounter },
326
+ [CSR_HPMCOUNTER29] = { "hpmcounter29", ctr, read_hpmcounter },
327
+ [CSR_HPMCOUNTER30] = { "hpmcounter30", ctr, read_hpmcounter },
328
+ [CSR_HPMCOUNTER31] = { "hpmcounter31", ctr, read_hpmcounter },
329
+
330
+ [CSR_MHPMCOUNTER3] = { "mhpmcounter3", mctr, read_hpmcounter,
331
+ write_mhpmcounter },
332
+ [CSR_MHPMCOUNTER4] = { "mhpmcounter4", mctr, read_hpmcounter,
333
+ write_mhpmcounter },
334
+ [CSR_MHPMCOUNTER5] = { "mhpmcounter5", mctr, read_hpmcounter,
335
+ write_mhpmcounter },
336
+ [CSR_MHPMCOUNTER6] = { "mhpmcounter6", mctr, read_hpmcounter,
337
+ write_mhpmcounter },
338
+ [CSR_MHPMCOUNTER7] = { "mhpmcounter7", mctr, read_hpmcounter,
339
+ write_mhpmcounter },
340
+ [CSR_MHPMCOUNTER8] = { "mhpmcounter8", mctr, read_hpmcounter,
341
+ write_mhpmcounter },
342
+ [CSR_MHPMCOUNTER9] = { "mhpmcounter9", mctr, read_hpmcounter,
343
+ write_mhpmcounter },
344
+ [CSR_MHPMCOUNTER10] = { "mhpmcounter10", mctr, read_hpmcounter,
345
+ write_mhpmcounter },
346
+ [CSR_MHPMCOUNTER11] = { "mhpmcounter11", mctr, read_hpmcounter,
347
+ write_mhpmcounter },
348
+ [CSR_MHPMCOUNTER12] = { "mhpmcounter12", mctr, read_hpmcounter,
349
+ write_mhpmcounter },
350
+ [CSR_MHPMCOUNTER13] = { "mhpmcounter13", mctr, read_hpmcounter,
351
+ write_mhpmcounter },
352
+ [CSR_MHPMCOUNTER14] = { "mhpmcounter14", mctr, read_hpmcounter,
353
+ write_mhpmcounter },
354
+ [CSR_MHPMCOUNTER15] = { "mhpmcounter15", mctr, read_hpmcounter,
355
+ write_mhpmcounter },
356
+ [CSR_MHPMCOUNTER16] = { "mhpmcounter16", mctr, read_hpmcounter,
357
+ write_mhpmcounter },
358
+ [CSR_MHPMCOUNTER17] = { "mhpmcounter17", mctr, read_hpmcounter,
359
+ write_mhpmcounter },
360
+ [CSR_MHPMCOUNTER18] = { "mhpmcounter18", mctr, read_hpmcounter,
361
+ write_mhpmcounter },
362
+ [CSR_MHPMCOUNTER19] = { "mhpmcounter19", mctr, read_hpmcounter,
363
+ write_mhpmcounter },
364
+ [CSR_MHPMCOUNTER20] = { "mhpmcounter20", mctr, read_hpmcounter,
365
+ write_mhpmcounter },
366
+ [CSR_MHPMCOUNTER21] = { "mhpmcounter21", mctr, read_hpmcounter,
367
+ write_mhpmcounter },
368
+ [CSR_MHPMCOUNTER22] = { "mhpmcounter22", mctr, read_hpmcounter,
369
+ write_mhpmcounter },
370
+ [CSR_MHPMCOUNTER23] = { "mhpmcounter23", mctr, read_hpmcounter,
371
+ write_mhpmcounter },
372
+ [CSR_MHPMCOUNTER24] = { "mhpmcounter24", mctr, read_hpmcounter,
373
+ write_mhpmcounter },
374
+ [CSR_MHPMCOUNTER25] = { "mhpmcounter25", mctr, read_hpmcounter,
375
+ write_mhpmcounter },
376
+ [CSR_MHPMCOUNTER26] = { "mhpmcounter26", mctr, read_hpmcounter,
377
+ write_mhpmcounter },
378
+ [CSR_MHPMCOUNTER27] = { "mhpmcounter27", mctr, read_hpmcounter,
379
+ write_mhpmcounter },
380
+ [CSR_MHPMCOUNTER28] = { "mhpmcounter28", mctr, read_hpmcounter,
381
+ write_mhpmcounter },
382
+ [CSR_MHPMCOUNTER29] = { "mhpmcounter29", mctr, read_hpmcounter,
383
+ write_mhpmcounter },
384
+ [CSR_MHPMCOUNTER30] = { "mhpmcounter30", mctr, read_hpmcounter,
385
+ write_mhpmcounter },
386
+ [CSR_MHPMCOUNTER31] = { "mhpmcounter31", mctr, read_hpmcounter,
387
+ write_mhpmcounter },
388
+
389
+ [CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
390
+ write_mcountinhibit },
391
+
392
+ [CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent,
393
+ write_mhpmevent },
394
+ [CSR_MHPMEVENT4] = { "mhpmevent4", any, read_mhpmevent,
395
+ write_mhpmevent },
396
+ [CSR_MHPMEVENT5] = { "mhpmevent5", any, read_mhpmevent,
397
+ write_mhpmevent },
398
+ [CSR_MHPMEVENT6] = { "mhpmevent6", any, read_mhpmevent,
399
+ write_mhpmevent },
400
+ [CSR_MHPMEVENT7] = { "mhpmevent7", any, read_mhpmevent,
401
+ write_mhpmevent },
402
+ [CSR_MHPMEVENT8] = { "mhpmevent8", any, read_mhpmevent,
403
+ write_mhpmevent },
404
+ [CSR_MHPMEVENT9] = { "mhpmevent9", any, read_mhpmevent,
405
+ write_mhpmevent },
406
+ [CSR_MHPMEVENT10] = { "mhpmevent10", any, read_mhpmevent,
407
+ write_mhpmevent },
408
+ [CSR_MHPMEVENT11] = { "mhpmevent11", any, read_mhpmevent,
409
+ write_mhpmevent },
410
+ [CSR_MHPMEVENT12] = { "mhpmevent12", any, read_mhpmevent,
411
+ write_mhpmevent },
412
+ [CSR_MHPMEVENT13] = { "mhpmevent13", any, read_mhpmevent,
413
+ write_mhpmevent },
414
+ [CSR_MHPMEVENT14] = { "mhpmevent14", any, read_mhpmevent,
415
+ write_mhpmevent },
416
+ [CSR_MHPMEVENT15] = { "mhpmevent15", any, read_mhpmevent,
417
+ write_mhpmevent },
418
+ [CSR_MHPMEVENT16] = { "mhpmevent16", any, read_mhpmevent,
419
+ write_mhpmevent },
420
+ [CSR_MHPMEVENT17] = { "mhpmevent17", any, read_mhpmevent,
421
+ write_mhpmevent },
422
+ [CSR_MHPMEVENT18] = { "mhpmevent18", any, read_mhpmevent,
423
+ write_mhpmevent },
424
+ [CSR_MHPMEVENT19] = { "mhpmevent19", any, read_mhpmevent,
425
+ write_mhpmevent },
426
+ [CSR_MHPMEVENT20] = { "mhpmevent20", any, read_mhpmevent,
427
+ write_mhpmevent },
428
+ [CSR_MHPMEVENT21] = { "mhpmevent21", any, read_mhpmevent,
429
+ write_mhpmevent },
430
+ [CSR_MHPMEVENT22] = { "mhpmevent22", any, read_mhpmevent,
431
+ write_mhpmevent },
432
+ [CSR_MHPMEVENT23] = { "mhpmevent23", any, read_mhpmevent,
433
+ write_mhpmevent },
434
+ [CSR_MHPMEVENT24] = { "mhpmevent24", any, read_mhpmevent,
435
+ write_mhpmevent },
436
+ [CSR_MHPMEVENT25] = { "mhpmevent25", any, read_mhpmevent,
437
+ write_mhpmevent },
438
+ [CSR_MHPMEVENT26] = { "mhpmevent26", any, read_mhpmevent,
439
+ write_mhpmevent },
440
+ [CSR_MHPMEVENT27] = { "mhpmevent27", any, read_mhpmevent,
441
+ write_mhpmevent },
442
+ [CSR_MHPMEVENT28] = { "mhpmevent28", any, read_mhpmevent,
443
+ write_mhpmevent },
444
+ [CSR_MHPMEVENT29] = { "mhpmevent29", any, read_mhpmevent,
445
+ write_mhpmevent },
446
+ [CSR_MHPMEVENT30] = { "mhpmevent30", any, read_mhpmevent,
447
+ write_mhpmevent },
448
+ [CSR_MHPMEVENT31] = { "mhpmevent31", any, read_mhpmevent,
449
+ write_mhpmevent },
450
+
451
+ [CSR_HPMCOUNTER3H] = { "hpmcounter3h", ctr32, read_hpmcounterh },
452
+ [CSR_HPMCOUNTER4H] = { "hpmcounter4h", ctr32, read_hpmcounterh },
453
+ [CSR_HPMCOUNTER5H] = { "hpmcounter5h", ctr32, read_hpmcounterh },
454
+ [CSR_HPMCOUNTER6H] = { "hpmcounter6h", ctr32, read_hpmcounterh },
455
+ [CSR_HPMCOUNTER7H] = { "hpmcounter7h", ctr32, read_hpmcounterh },
456
+ [CSR_HPMCOUNTER8H] = { "hpmcounter8h", ctr32, read_hpmcounterh },
457
+ [CSR_HPMCOUNTER9H] = { "hpmcounter9h", ctr32, read_hpmcounterh },
458
+ [CSR_HPMCOUNTER10H] = { "hpmcounter10h", ctr32, read_hpmcounterh },
459
+ [CSR_HPMCOUNTER11H] = { "hpmcounter11h", ctr32, read_hpmcounterh },
460
+ [CSR_HPMCOUNTER12H] = { "hpmcounter12h", ctr32, read_hpmcounterh },
461
+ [CSR_HPMCOUNTER13H] = { "hpmcounter13h", ctr32, read_hpmcounterh },
462
+ [CSR_HPMCOUNTER14H] = { "hpmcounter14h", ctr32, read_hpmcounterh },
463
+ [CSR_HPMCOUNTER15H] = { "hpmcounter15h", ctr32, read_hpmcounterh },
464
+ [CSR_HPMCOUNTER16H] = { "hpmcounter16h", ctr32, read_hpmcounterh },
465
+ [CSR_HPMCOUNTER17H] = { "hpmcounter17h", ctr32, read_hpmcounterh },
466
+ [CSR_HPMCOUNTER18H] = { "hpmcounter18h", ctr32, read_hpmcounterh },
467
+ [CSR_HPMCOUNTER19H] = { "hpmcounter19h", ctr32, read_hpmcounterh },
468
+ [CSR_HPMCOUNTER20H] = { "hpmcounter20h", ctr32, read_hpmcounterh },
469
+ [CSR_HPMCOUNTER21H] = { "hpmcounter21h", ctr32, read_hpmcounterh },
470
+ [CSR_HPMCOUNTER22H] = { "hpmcounter22h", ctr32, read_hpmcounterh },
471
+ [CSR_HPMCOUNTER23H] = { "hpmcounter23h", ctr32, read_hpmcounterh },
472
+ [CSR_HPMCOUNTER24H] = { "hpmcounter24h", ctr32, read_hpmcounterh },
473
+ [CSR_HPMCOUNTER25H] = { "hpmcounter25h", ctr32, read_hpmcounterh },
474
+ [CSR_HPMCOUNTER26H] = { "hpmcounter26h", ctr32, read_hpmcounterh },
475
+ [CSR_HPMCOUNTER27H] = { "hpmcounter27h", ctr32, read_hpmcounterh },
476
+ [CSR_HPMCOUNTER28H] = { "hpmcounter28h", ctr32, read_hpmcounterh },
477
+ [CSR_HPMCOUNTER29H] = { "hpmcounter29h", ctr32, read_hpmcounterh },
478
+ [CSR_HPMCOUNTER30H] = { "hpmcounter30h", ctr32, read_hpmcounterh },
479
+ [CSR_HPMCOUNTER31H] = { "hpmcounter31h", ctr32, read_hpmcounterh },
480
+
481
+ [CSR_MHPMCOUNTER3H] = { "mhpmcounter3h", mctr32, read_hpmcounterh,
482
+ write_mhpmcounterh },
483
+ [CSR_MHPMCOUNTER4H] = { "mhpmcounter4h", mctr32, read_hpmcounterh,
484
+ write_mhpmcounterh },
485
+ [CSR_MHPMCOUNTER5H] = { "mhpmcounter5h", mctr32, read_hpmcounterh,
486
+ write_mhpmcounterh },
487
+ [CSR_MHPMCOUNTER6H] = { "mhpmcounter6h", mctr32, read_hpmcounterh,
488
+ write_mhpmcounterh },
489
+ [CSR_MHPMCOUNTER7H] = { "mhpmcounter7h", mctr32, read_hpmcounterh,
490
+ write_mhpmcounterh },
491
+ [CSR_MHPMCOUNTER8H] = { "mhpmcounter8h", mctr32, read_hpmcounterh,
492
+ write_mhpmcounterh },
493
+ [CSR_MHPMCOUNTER9H] = { "mhpmcounter9h", mctr32, read_hpmcounterh,
494
+ write_mhpmcounterh },
495
+ [CSR_MHPMCOUNTER10H] = { "mhpmcounter10h", mctr32, read_hpmcounterh,
496
+ write_mhpmcounterh },
497
+ [CSR_MHPMCOUNTER11H] = { "mhpmcounter11h", mctr32, read_hpmcounterh,
498
+ write_mhpmcounterh },
499
+ [CSR_MHPMCOUNTER12H] = { "mhpmcounter12h", mctr32, read_hpmcounterh,
500
+ write_mhpmcounterh },
501
+ [CSR_MHPMCOUNTER13H] = { "mhpmcounter13h", mctr32, read_hpmcounterh,
502
+ write_mhpmcounterh },
503
+ [CSR_MHPMCOUNTER14H] = { "mhpmcounter14h", mctr32, read_hpmcounterh,
504
+ write_mhpmcounterh },
505
+ [CSR_MHPMCOUNTER15H] = { "mhpmcounter15h", mctr32, read_hpmcounterh,
506
+ write_mhpmcounterh },
507
+ [CSR_MHPMCOUNTER16H] = { "mhpmcounter16h", mctr32, read_hpmcounterh,
508
+ write_mhpmcounterh },
509
+ [CSR_MHPMCOUNTER17H] = { "mhpmcounter17h", mctr32, read_hpmcounterh,
510
+ write_mhpmcounterh },
511
+ [CSR_MHPMCOUNTER18H] = { "mhpmcounter18h", mctr32, read_hpmcounterh,
512
+ write_mhpmcounterh },
513
+ [CSR_MHPMCOUNTER19H] = { "mhpmcounter19h", mctr32, read_hpmcounterh,
514
+ write_mhpmcounterh },
515
+ [CSR_MHPMCOUNTER20H] = { "mhpmcounter20h", mctr32, read_hpmcounterh,
516
+ write_mhpmcounterh },
517
+ [CSR_MHPMCOUNTER21H] = { "mhpmcounter21h", mctr32, read_hpmcounterh,
518
+ write_mhpmcounterh },
519
+ [CSR_MHPMCOUNTER22H] = { "mhpmcounter22h", mctr32, read_hpmcounterh,
520
+ write_mhpmcounterh },
521
+ [CSR_MHPMCOUNTER23H] = { "mhpmcounter23h", mctr32, read_hpmcounterh,
522
+ write_mhpmcounterh },
523
+ [CSR_MHPMCOUNTER24H] = { "mhpmcounter24h", mctr32, read_hpmcounterh,
524
+ write_mhpmcounterh },
525
+ [CSR_MHPMCOUNTER25H] = { "mhpmcounter25h", mctr32, read_hpmcounterh,
526
+ write_mhpmcounterh },
527
+ [CSR_MHPMCOUNTER26H] = { "mhpmcounter26h", mctr32, read_hpmcounterh,
528
+ write_mhpmcounterh },
529
+ [CSR_MHPMCOUNTER27H] = { "mhpmcounter27h", mctr32, read_hpmcounterh,
530
+ write_mhpmcounterh },
531
+ [CSR_MHPMCOUNTER28H] = { "mhpmcounter28h", mctr32, read_hpmcounterh,
532
+ write_mhpmcounterh },
533
+ [CSR_MHPMCOUNTER29H] = { "mhpmcounter29h", mctr32, read_hpmcounterh,
534
+ write_mhpmcounterh },
535
+ [CSR_MHPMCOUNTER30H] = { "mhpmcounter30h", mctr32, read_hpmcounterh,
536
+ write_mhpmcounterh },
537
+ [CSR_MHPMCOUNTER31H] = { "mhpmcounter31h", mctr32, read_hpmcounterh,
538
+ write_mhpmcounterh },
539
#endif /* !CONFIG_USER_ONLY */
540
};
541
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
75
index XXXXXXX..XXXXXXX 100644
542
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/kvm/kvm-cpu.c
543
--- a/target/riscv/machine.c
77
+++ b/target/riscv/kvm/kvm-cpu.c
544
+++ b/target/riscv/machine.c
78
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
545
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
79
return ret;
546
VMSTATE_UINTTL(env.scounteren, RISCVCPU),
80
}
547
VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
81
548
VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
549
+ VMSTATE_UINTTL_ARRAY(env.mhpmcounter_val, RISCVCPU, RV_MAX_MHPMCOUNTERS),
83
+{
550
+ VMSTATE_UINTTL_ARRAY(env.mhpmcounterh_val, RISCVCPU, RV_MAX_MHPMCOUNTERS),
84
+ target_ulong csr_num = run->riscv_csr.csr_num;
551
+ VMSTATE_UINTTL_ARRAY(env.mhpmevent_val, RISCVCPU, RV_MAX_MHPMEVENTS),
85
+ target_ulong new_value = run->riscv_csr.new_value;
552
VMSTATE_UINTTL(env.sscratch, RISCVCPU),
86
+ target_ulong write_mask = run->riscv_csr.write_mask;
553
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
87
+ int ret = 0;
554
VMSTATE_UINT64(env.mfromhost, RISCVCPU),
88
+
89
+ switch (csr_num) {
90
+ case CSR_SEED:
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
92
+ break;
93
+ default:
94
+ qemu_log_mask(LOG_UNIMP,
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
96
+ __func__, csr_num);
97
+ ret = -1;
98
+ break;
99
+ }
100
+
101
+ return ret;
102
+}
103
+
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
105
{
106
int ret = 0;
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
108
case KVM_EXIT_RISCV_SBI:
109
ret = kvm_riscv_handle_sbi(cs, run);
110
break;
111
+ case KVM_EXIT_RISCV_CSR:
112
+ ret = kvm_riscv_handle_csr(cs, run);
113
+ break;
114
default:
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
116
__func__, run->exit_reason);
117
--
555
--
118
2.45.1
556
2.36.1
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Atish Patra <atish.patra@wdc.com>
2
2
3
The th.sxstatus CSR can be used to identify available custom extension
3
mcycle/minstret are actually WARL registers and can be written with any
4
on T-Head CPUs. The CSR is documented here:
4
given value. With SBI PMU extension, it will be used to store a initial
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
5
value provided from supervisor OS. The Qemu also need prohibit the counter
6
increment if mcountinhibit is set.
6
7
7
An important property of this patch is, that the th.sxstatus MAEE field
8
Support mcycle/minstret through generic counter infrastructure.
8
is not set (indicating that XTheadMae is not available).
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
11
in PTEs that are marked as reserved. QEMU maintainers prefer to not
12
implement XTheadMae, so we need give kernels a mechanism to identify
13
if XTheadMae is available in a system or not. And this patch introduces
14
this mechanism in QEMU in a way that's compatible with real HW
15
(i.e., probing the th.sxstatus.MAEE bit).
16
9
17
Further context can be found on the list:
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
19
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
11
Signed-off-by: Atish Patra <atish.patra@wdc.com>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
12
Signed-off-by: Atish Patra <atishp@rivosinc.com>
13
Message-Id: <20220620231603.2547260-8-atishp@rivosinc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
15
---
26
MAINTAINERS | 1 +
16
target/riscv/cpu.h | 23 ++++--
27
target/riscv/cpu.h | 3 ++
17
target/riscv/pmu.h | 28 +++++++
28
target/riscv/cpu.c | 1 +
18
target/riscv/csr.c | 155 ++++++++++++++++++++++++++++-----------
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
19
target/riscv/machine.c | 25 ++++++-
30
target/riscv/meson.build | 1 +
20
target/riscv/pmu.c | 32 ++++++++
31
5 files changed, 85 insertions(+)
21
target/riscv/meson.build | 3 +-
32
create mode 100644 target/riscv/th_csr.c
22
6 files changed, 213 insertions(+), 53 deletions(-)
23
create mode 100644 target/riscv/pmu.h
24
create mode 100644 target/riscv/pmu.c
33
25
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
39
S: Supported
40
F: target/riscv/insn_trans/trans_xthead.c.inc
41
F: target/riscv/xthead*.decode
42
+F: target/riscv/th_*
43
F: disas/riscv-xthead*
44
45
RISC-V XVentanaCondOps extension
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
26
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
47
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
28
--- a/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
29
+++ b/target/riscv/cpu.h
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
30
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState CPURISCVState;
51
uint8_t satp_mode_max_from_map(uint32_t map);
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
53
54
+/* Implemented in th_csr.c */
55
+void th_register_custom_csrs(RISCVCPU *cpu);
56
+
57
#endif /* RISCV_CPU_H */
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
64
#ifndef CONFIG_USER_ONLY
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
66
+ th_register_custom_csrs(cpu);
67
#endif
31
#endif
68
32
69
/* inherited from parent obj via riscv_cpu_init() */
33
#define RV_VLEN_MAX 1024
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
34
-#define RV_MAX_MHPMEVENTS 29
35
+#define RV_MAX_MHPMEVENTS 32
36
#define RV_MAX_MHPMCOUNTERS 32
37
38
FIELD(VTYPE, VLMUL, 0, 3)
39
@@ -XXX,XX +XXX,XX @@ FIELD(VTYPE, VMA, 7, 1)
40
FIELD(VTYPE, VEDIV, 8, 2)
41
FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
42
43
+typedef struct PMUCTRState {
44
+ /* Current value of a counter */
45
+ target_ulong mhpmcounter_val;
46
+ /* Current value of a counter in RV32*/
47
+ target_ulong mhpmcounterh_val;
48
+ /* Snapshot values of counter */
49
+ target_ulong mhpmcounter_prev;
50
+ /* Snapshort value of a counter in RV32 */
51
+ target_ulong mhpmcounterh_prev;
52
+ bool started;
53
+} PMUCTRState;
54
+
55
struct CPUArchState {
56
target_ulong gpr[32];
57
target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
58
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
59
60
target_ulong mcountinhibit;
61
62
- /* PMU counter configured values */
63
- target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS];
64
-
65
- /* for RV32 */
66
- target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS];
67
+ /* PMU counter state */
68
+ PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
69
70
- /* PMU event selector configured values */
71
+ /* PMU event selector configured values. First three are unused*/
72
target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
73
74
target_ulong sscratch;
75
diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
71
new file mode 100644
76
new file mode 100644
72
index XXXXXXX..XXXXXXX
77
index XXXXXXX..XXXXXXX
73
--- /dev/null
78
--- /dev/null
74
+++ b/target/riscv/th_csr.c
79
+++ b/target/riscv/pmu.h
75
@@ -XXX,XX +XXX,XX @@
80
@@ -XXX,XX +XXX,XX @@
76
+/*
81
+/*
77
+ * T-Head-specific CSRs.
82
+ * RISC-V PMU header file.
78
+ *
83
+ *
79
+ * Copyright (c) 2024 VRULL GmbH
84
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
80
+ *
85
+ *
81
+ * This program is free software; you can redistribute it and/or modify it
86
+ * This program is free software; you can redistribute it and/or modify it
82
+ * under the terms and conditions of the GNU General Public License,
87
+ * under the terms and conditions of the GNU General Public License,
83
+ * version 2 or later, as published by the Free Software Foundation.
88
+ * version 2 or later, as published by the Free Software Foundation.
84
+ *
89
+ *
...
...
90
+ * You should have received a copy of the GNU General Public License along with
95
+ * You should have received a copy of the GNU General Public License along with
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
96
+ * this program. If not, see <http://www.gnu.org/licenses/>.
92
+ */
97
+ */
93
+
98
+
94
+#include "qemu/osdep.h"
99
+#include "qemu/osdep.h"
100
+#include "qemu/log.h"
95
+#include "cpu.h"
101
+#include "cpu.h"
96
+#include "cpu_vendorid.h"
102
+#include "qemu/main-loop.h"
97
+
103
+#include "exec/exec-all.h"
98
+#define CSR_TH_SXSTATUS 0x5c0
104
+
99
+
105
+bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
100
+/* TH_SXSTATUS bits */
106
+ uint32_t target_ctr);
101
+#define TH_SXSTATUS_UCME BIT(16)
107
+bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
102
+#define TH_SXSTATUS_MAEE BIT(21)
108
+ uint32_t target_ctr);
103
+#define TH_SXSTATUS_THEADISAEE BIT(22)
109
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
104
+
110
index XXXXXXX..XXXXXXX 100644
105
+typedef struct {
111
--- a/target/riscv/csr.c
106
+ int csrno;
112
+++ b/target/riscv/csr.c
107
+ int (*insertion_test)(RISCVCPU *cpu);
113
@@ -XXX,XX +XXX,XX @@
108
+ riscv_csr_operations csr_ops;
114
#include "qemu/log.h"
109
+} riscv_csr;
115
#include "qemu/timer.h"
110
+
116
#include "cpu.h"
111
+static RISCVException smode(CPURISCVState *env, int csrno)
117
+#include "pmu.h"
112
+{
118
#include "qemu/main-loop.h"
113
+ if (riscv_has_ext(env, RVS)) {
119
#include "exec/exec-all.h"
114
+ return RISCV_EXCP_NONE;
120
#include "sysemu/cpu-timers.h"
115
+ }
121
@@ -XXX,XX +XXX,XX @@ static int write_vcsr(CPURISCVState *env, int csrno, target_ulong val)
116
+
122
}
117
+ return RISCV_EXCP_ILLEGAL_INST;
123
118
+}
124
/* User Timers and Counters */
119
+
125
-static RISCVException read_instret(CPURISCVState *env, int csrno,
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
126
- target_ulong *val)
121
+{
127
+static target_ulong get_ticks(bool shift)
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
128
{
123
+ return -1;
129
+ int64_t val;
124
+ }
130
+ target_ulong result;
125
+
131
+
126
+ return 0;
132
#if !defined(CONFIG_USER_ONLY)
127
+}
133
if (icount_enabled()) {
128
+
134
- *val = icount_get();
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
135
+ val = icount_get();
130
+ target_ulong *val)
136
} else {
131
+{
137
- *val = cpu_get_host_ticks();
132
+ /* We don't set MAEE here, because QEMU does not implement MAEE. */
138
+ val = cpu_get_host_ticks();
133
+ *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
139
}
140
#else
141
- *val = cpu_get_host_ticks();
142
+ val = cpu_get_host_ticks();
143
#endif
144
- return RISCV_EXCP_NONE;
145
-}
146
147
-static RISCVException read_instreth(CPURISCVState *env, int csrno,
148
- target_ulong *val)
149
-{
150
-#if !defined(CONFIG_USER_ONLY)
151
- if (icount_enabled()) {
152
- *val = icount_get() >> 32;
153
+ if (shift) {
154
+ result = val >> 32;
155
} else {
156
- *val = cpu_get_host_ticks() >> 32;
157
+ result = val;
158
}
159
-#else
160
- *val = cpu_get_host_ticks() >> 32;
161
-#endif
162
- return RISCV_EXCP_NONE;
163
+
164
+ return result;
165
}
166
167
#if defined(CONFIG_USER_ONLY)
168
@@ -XXX,XX +XXX,XX @@ static RISCVException read_timeh(CPURISCVState *env, int csrno,
169
return RISCV_EXCP_NONE;
170
}
171
172
+static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
173
+{
174
+ *val = get_ticks(false);
134
+ return RISCV_EXCP_NONE;
175
+ return RISCV_EXCP_NONE;
135
+}
176
+}
136
+
177
+
137
+static riscv_csr th_csr_list[] = {
178
+static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
138
+ {
179
+{
139
+ .csrno = CSR_TH_SXSTATUS,
180
+ *val = get_ticks(true);
140
+ .insertion_test = test_thead_mvendorid,
181
+ return RISCV_EXCP_NONE;
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
182
+}
183
+
184
#else /* CONFIG_USER_ONLY */
185
186
static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
187
{
188
- int evt_index = csrno - CSR_MHPMEVENT3;
189
+ int evt_index = csrno - CSR_MCOUNTINHIBIT;
190
191
*val = env->mhpmevent_val[evt_index];
192
193
@@ -XXX,XX +XXX,XX @@ static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
194
195
static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
196
{
197
- int evt_index = csrno - CSR_MHPMEVENT3;
198
+ int evt_index = csrno - CSR_MCOUNTINHIBIT;
199
200
env->mhpmevent_val[evt_index] = val;
201
202
@@ -XXX,XX +XXX,XX @@ static int write_mhpmevent(CPURISCVState *env, int csrno, target_ulong val)
203
204
static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
205
{
206
- int ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
207
+ int ctr_idx = csrno - CSR_MCYCLE;
208
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
209
210
- env->mhpmcounter_val[ctr_index] = val;
211
+ counter->mhpmcounter_val = val;
212
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
213
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
214
+ counter->mhpmcounter_prev = get_ticks(false);
215
+ } else {
216
+ /* Other counters can keep incrementing from the given value */
217
+ counter->mhpmcounter_prev = val;
218
+ }
219
220
return RISCV_EXCP_NONE;
221
}
222
223
static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
224
{
225
- int ctr_index = csrno - CSR_MHPMCOUNTER3H + 3;
226
+ int ctr_idx = csrno - CSR_MCYCLEH;
227
+ PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
228
229
- env->mhpmcounterh_val[ctr_index] = val;
230
+ counter->mhpmcounterh_val = val;
231
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
232
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
233
+ counter->mhpmcounterh_prev = get_ticks(true);
234
+ } else {
235
+ counter->mhpmcounterh_prev = val;
236
+ }
237
+
238
+ return RISCV_EXCP_NONE;
239
+}
240
+
241
+static RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
242
+ bool upper_half, uint32_t ctr_idx)
243
+{
244
+ PMUCTRState counter = env->pmu_ctrs[ctr_idx];
245
+ target_ulong ctr_prev = upper_half ? counter.mhpmcounterh_prev :
246
+ counter.mhpmcounter_prev;
247
+ target_ulong ctr_val = upper_half ? counter.mhpmcounterh_val :
248
+ counter.mhpmcounter_val;
249
+
250
+ if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
251
+ /**
252
+ * Counter should not increment if inhibit bit is set. We can't really
253
+ * stop the icount counting. Just return the counter value written by
254
+ * the supervisor to indicate that counter was not incremented.
255
+ */
256
+ if (!counter.started) {
257
+ *val = ctr_val;
258
+ return RISCV_EXCP_NONE;
259
+ } else {
260
+ /* Mark that the counter has been stopped */
261
+ counter.started = false;
262
+ }
263
+ }
264
+
265
+ /**
266
+ * The kernel computes the perf delta by subtracting the current value from
267
+ * the value it initialized previously (ctr_val).
268
+ */
269
+ if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
270
+ riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
271
+ *val = get_ticks(upper_half) - ctr_prev + ctr_val;
272
+ } else {
273
+ *val = ctr_val;
274
+ }
275
276
return RISCV_EXCP_NONE;
277
}
278
279
static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
280
{
281
- int ctr_index;
282
+ uint16_t ctr_index;
283
284
if (csrno >= CSR_MCYCLE && csrno <= CSR_MHPMCOUNTER31) {
285
- ctr_index = csrno - CSR_MHPMCOUNTER3 + 3;
286
+ ctr_index = csrno - CSR_MCYCLE;
287
} else if (csrno >= CSR_CYCLE && csrno <= CSR_HPMCOUNTER31) {
288
- ctr_index = csrno - CSR_HPMCOUNTER3 + 3;
289
+ ctr_index = csrno - CSR_CYCLE;
290
} else {
291
return RISCV_EXCP_ILLEGAL_INST;
292
}
293
- *val = env->mhpmcounter_val[ctr_index];
294
295
- return RISCV_EXCP_NONE;
296
+ return riscv_pmu_read_ctr(env, val, false, ctr_index);
297
}
298
299
static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong *val)
300
{
301
- int ctr_index;
302
+ uint16_t ctr_index;
303
304
if (csrno >= CSR_MCYCLEH && csrno <= CSR_MHPMCOUNTER31H) {
305
- ctr_index = csrno - CSR_MHPMCOUNTER3H + 3;
306
+ ctr_index = csrno - CSR_MCYCLEH;
307
} else if (csrno >= CSR_CYCLEH && csrno <= CSR_HPMCOUNTER31H) {
308
- ctr_index = csrno - CSR_HPMCOUNTER3H + 3;
309
+ ctr_index = csrno - CSR_CYCLEH;
310
} else {
311
return RISCV_EXCP_ILLEGAL_INST;
312
}
313
- *val = env->mhpmcounterh_val[ctr_index];
314
315
- return RISCV_EXCP_NONE;
316
+ return riscv_pmu_read_ctr(env, val, true, ctr_index);
317
}
318
319
-
320
static RISCVException read_time(CPURISCVState *env, int csrno,
321
target_ulong *val)
322
{
323
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
324
static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
325
target_ulong val)
326
{
327
+ int cidx;
328
+ PMUCTRState *counter;
329
+
330
if (env->priv_ver < PRIV_VERSION_1_11_0) {
331
return RISCV_EXCP_ILLEGAL_INST;
332
}
333
334
env->mcountinhibit = val;
335
+
336
+ /* Check if any other counter is also monitoring cycles/instructions */
337
+ for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
338
+ if (!get_field(env->mcountinhibit, BIT(cidx))) {
339
+ counter = &env->pmu_ctrs[cidx];
340
+ counter->started = true;
341
+ }
342
+ }
343
+
344
return RISCV_EXCP_NONE;
345
}
346
347
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
348
[CSR_VLENB] = { "vlenb", vs, read_vlenb,
349
.min_priv_ver = PRIV_VERSION_1_12_0 },
350
/* User Timers and Counters */
351
- [CSR_CYCLE] = { "cycle", ctr, read_instret },
352
- [CSR_INSTRET] = { "instret", ctr, read_instret },
353
- [CSR_CYCLEH] = { "cycleh", ctr32, read_instreth },
354
- [CSR_INSTRETH] = { "instreth", ctr32, read_instreth },
355
+ [CSR_CYCLE] = { "cycle", ctr, read_hpmcounter },
356
+ [CSR_INSTRET] = { "instret", ctr, read_hpmcounter },
357
+ [CSR_CYCLEH] = { "cycleh", ctr32, read_hpmcounterh },
358
+ [CSR_INSTRETH] = { "instreth", ctr32, read_hpmcounterh },
359
360
/*
361
* In privileged mode, the monitor will have to emulate TIME CSRs only if
362
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
363
364
#if !defined(CONFIG_USER_ONLY)
365
/* Machine Timers and Counters */
366
- [CSR_MCYCLE] = { "mcycle", any, read_instret },
367
- [CSR_MINSTRET] = { "minstret", any, read_instret },
368
- [CSR_MCYCLEH] = { "mcycleh", any32, read_instreth },
369
- [CSR_MINSTRETH] = { "minstreth", any32, read_instreth },
370
+ [CSR_MCYCLE] = { "mcycle", any, read_hpmcounter, write_mhpmcounter},
371
+ [CSR_MINSTRET] = { "minstret", any, read_hpmcounter, write_mhpmcounter},
372
+ [CSR_MCYCLEH] = { "mcycleh", any32, read_hpmcounterh, write_mhpmcounterh},
373
+ [CSR_MINSTRETH] = { "minstreth", any32, read_hpmcounterh, write_mhpmcounterh},
374
375
/* Machine Information Registers */
376
[CSR_MVENDORID] = { "mvendorid", any, read_mvendorid },
377
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
378
index XXXXXXX..XXXXXXX 100644
379
--- a/target/riscv/machine.c
380
+++ b/target/riscv/machine.c
381
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_envcfg = {
382
VMSTATE_UINT64(env.menvcfg, RISCVCPU),
383
VMSTATE_UINTTL(env.senvcfg, RISCVCPU),
384
VMSTATE_UINT64(env.henvcfg, RISCVCPU),
385
+ VMSTATE_END_OF_LIST()
142
+ }
386
+ }
143
+};
387
+};
144
+
388
+
145
+void th_register_custom_csrs(RISCVCPU *cpu)
389
+static bool pmu_needed(void *opaque)
146
+{
390
+{
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
391
+ RISCVCPU *cpu = opaque;
148
+ int csrno = th_csr_list[i].csrno;
392
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
393
+ return cpu->cfg.pmu_num;
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
394
+}
151
+ riscv_set_csr_ops(csrno, csr_ops);
395
+
152
+ }
396
+static const VMStateDescription vmstate_pmu_ctr_state = {
153
+ }
397
+ .name = "cpu/pmu",
398
+ .version_id = 1,
399
+ .minimum_version_id = 1,
400
+ .needed = pmu_needed,
401
+ .fields = (VMStateField[]) {
402
+ VMSTATE_UINTTL(mhpmcounter_val, PMUCTRState),
403
+ VMSTATE_UINTTL(mhpmcounterh_val, PMUCTRState),
404
+ VMSTATE_UINTTL(mhpmcounter_prev, PMUCTRState),
405
+ VMSTATE_UINTTL(mhpmcounterh_prev, PMUCTRState),
406
+ VMSTATE_BOOL(started, PMUCTRState),
407
VMSTATE_END_OF_LIST()
408
}
409
};
410
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
411
VMSTATE_UINTTL(env.scounteren, RISCVCPU),
412
VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
413
VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
414
- VMSTATE_UINTTL_ARRAY(env.mhpmcounter_val, RISCVCPU, RV_MAX_MHPMCOUNTERS),
415
- VMSTATE_UINTTL_ARRAY(env.mhpmcounterh_val, RISCVCPU, RV_MAX_MHPMCOUNTERS),
416
+ VMSTATE_STRUCT_ARRAY(env.pmu_ctrs, RISCVCPU, RV_MAX_MHPMCOUNTERS, 0,
417
+ vmstate_pmu_ctr_state, PMUCTRState),
418
VMSTATE_UINTTL_ARRAY(env.mhpmevent_val, RISCVCPU, RV_MAX_MHPMEVENTS),
419
VMSTATE_UINTTL(env.sscratch, RISCVCPU),
420
VMSTATE_UINTTL(env.mscratch, RISCVCPU),
421
diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
422
new file mode 100644
423
index XXXXXXX..XXXXXXX
424
--- /dev/null
425
+++ b/target/riscv/pmu.c
426
@@ -XXX,XX +XXX,XX @@
427
+/*
428
+ * RISC-V PMU file.
429
+ *
430
+ * Copyright (c) 2021 Western Digital Corporation or its affiliates.
431
+ *
432
+ * This program is free software; you can redistribute it and/or modify it
433
+ * under the terms and conditions of the GNU General Public License,
434
+ * version 2 or later, as published by the Free Software Foundation.
435
+ *
436
+ * This program is distributed in the hope it will be useful, but WITHOUT
437
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
438
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
439
+ * more details.
440
+ *
441
+ * You should have received a copy of the GNU General Public License along with
442
+ * this program. If not, see <http://www.gnu.org/licenses/>.
443
+ */
444
+
445
+#include "qemu/osdep.h"
446
+#include "cpu.h"
447
+#include "pmu.h"
448
+
449
+bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
450
+ uint32_t target_ctr)
451
+{
452
+ return (target_ctr == 0) ? true : false;
453
+}
454
+
455
+bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env, uint32_t target_ctr)
456
+{
457
+ return (target_ctr == 2) ? true : false;
154
+}
458
+}
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
459
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
156
index XXXXXXX..XXXXXXX 100644
460
index XXXXXXX..XXXXXXX 100644
157
--- a/target/riscv/meson.build
461
--- a/target/riscv/meson.build
158
+++ b/target/riscv/meson.build
462
+++ b/target/riscv/meson.build
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
463
@@ -XXX,XX +XXX,XX @@ riscv_softmmu_ss.add(files(
464
'pmp.c',
465
'debug.c',
160
'monitor.c',
466
'monitor.c',
161
'machine.c',
467
- 'machine.c'
162
'pmu.c',
468
+ 'machine.c',
163
+ 'th_csr.c',
469
+ 'pmu.c'
164
'time_helper.c',
165
'riscv-qmp-cmds.c',
166
))
470
))
471
472
target_arch += {'riscv': riscv_ss}
167
--
473
--
168
2.45.1
474
2.36.1
169
170
diff view generated by jsdifflib
1
From: Rob Bradford <rbradford@rivosinc.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
This extension has now been ratified:
3
There is nothing in the RISC-V spec that mandates version 1.12 is
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
4
required for ePMP and there is currently hardware [1] that implements
5
removed.
5
ePMP (a draft version though) with the 1.11 priv spec.
6
6
7
Since this is now a ratified extension add it to the list of extensions
7
1: https://ibex-core.readthedocs.io/en/latest/01_overview/compliance.html
8
included in the "max" CPU variant.
9
8
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
9
Fixes: a4b2fa433125 ("target/riscv: Introduce privilege version field in the CSR ops.")
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
12
Message-Id: <20220629233102.275181-2-alistair.francis@opensource.wdc.com>
17
---
13
---
18
target/riscv/cpu.c | 2 +-
14
target/riscv/csr.c | 2 +-
19
target/riscv/tcg/tcg-cpu.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
20
2 files changed, 2 insertions(+), 2 deletions(-)
21
16
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
23
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.c
19
--- a/target/riscv/csr.c
25
+++ b/target/riscv/cpu.c
20
+++ b/target/riscv/csr.c
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
21
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
22
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
23
/* Physical Memory Protection */
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
24
[CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg,
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
25
- .min_priv_ver = PRIV_VERSION_1_12_0 },
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
26
+ .min_priv_ver = PRIV_VERSION_1_11_0 },
32
};
27
[CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
33
28
[CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
29
[CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/tcg/tcg-cpu.c
38
+++ b/target/riscv/tcg/tcg-cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
40
const RISCVCPUMultiExtConfig *prop;
41
42
/* Enable RVG, RVJ and RVV that are disabled by default */
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
45
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
47
isa_ext_update_enabled(cpu, prop->offset, true);
48
--
30
--
49
2.45.1
31
2.36.1
diff view generated by jsdifflib
1
From: Yangyu Chen <cyy@cyyself.name>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
This code has a typo that writes zvkb to zvkg, causing users can't
3
The Ibex CPU supports version 1.11 of the priv spec [1], so let's
4
enable zvkb through the config. This patch gets this fixed.
4
correct that in QEMU as well.
5
5
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
6
1: https://ibex-core.readthedocs.io/en/latest/01_overview/compliance.html
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
7
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
10
Message-Id: <20220629233102.275181-3-alistair.francis@opensource.wdc.com>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
12
---
16
target/riscv/cpu.c | 2 +-
13
target/riscv/cpu.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
18
15
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
18
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
20
@@ -XXX,XX +XXX,XX @@ static void rv32_ibex_cpu_init(Object *obj)
24
/* Vector cryptography extensions */
21
RISCVCPU *cpu = RISCV_CPU(obj);
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
22
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
23
set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
24
- set_priv_version(env, PRIV_VERSION_1_10_0);
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
25
+ set_priv_version(env, PRIV_VERSION_1_11_0);
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
26
cpu->cfg.mmu = false;
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
27
cpu->cfg.epmp = true;
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
28
}
32
--
29
--
33
2.45.1
30
2.36.1
34
35
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Anup Patel <apatel@ventanamicro.com>
2
2
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
3
The riscv_cpu_realize() sets priv spec version to v1.12 when it is
4
enabling Zve64x enables Zve32x according to their dependency.
4
when "env->priv_ver == 0" (i.e. default v1.10) because the enum
5
value of priv spec v1.10 is zero.
5
6
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
7
Due to above issue, the sifive_u machine will see priv spec v1.12
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
instead of priv spec v1.10.
9
10
To fix this issue, we set latest priv spec version (i.e. v1.12)
11
for base rv64/rv32 cpu and riscv_cpu_realize() will override priv
12
spec version only when "cpu->cfg.priv_spec != NULL".
13
14
Fixes: 7100fe6c2441 ("target/riscv: Enable privileged spec version 1.12")
15
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
16
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Max Chou <max.chou@sifive.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
18
Reviewed-by: Atish Patra <atishp@rivosinc.com>
11
Message-ID: <20240328022343.6871-3-jason.chien@sifive.com>
19
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
20
Message-Id: <20220611080107.391981-2-apatel@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
22
---
14
target/riscv/cpu_cfg.h | 1 +
23
target/riscv/cpu.c | 12 ++++++++----
15
target/riscv/cpu.c | 2 ++
24
1 file changed, 8 insertions(+), 4 deletions(-)
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
17
3 files changed, 14 insertions(+), 6 deletions(-)
18
25
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_zve32x;
25
bool ext_zve64f;
26
bool ext_zve64d;
27
+ bool ext_zve64x;
28
bool ext_zvbb;
29
bool ext_zvbc;
30
bool ext_zvkb;
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
26
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu.c
28
--- a/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
29
+++ b/target/riscv/cpu.c
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
30
@@ -XXX,XX +XXX,XX @@ static void rv64_base_cpu_init(Object *obj)
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
31
/* We set this in the realise function */
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
32
set_misa(env, MXL_RV64, 0);
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
33
register_cpu_props(DEVICE(obj));
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
34
+ /* Set latest version of privileged specification */
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
35
+ set_priv_version(env, PRIV_VERSION_1_12_0);
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
36
}
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
37
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
38
static void rv64_sifive_u_cpu_init(Object *obj)
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
39
@@ -XXX,XX +XXX,XX @@ static void rv128_base_cpu_init(Object *obj)
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
40
/* We set this in the realise function */
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
41
set_misa(env, MXL_RV128, 0);
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
42
register_cpu_props(DEVICE(obj));
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
43
+ /* Set latest version of privileged specification */
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
44
+ set_priv_version(env, PRIV_VERSION_1_12_0);
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
45
}
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
46
#else
52
index XXXXXXX..XXXXXXX 100644
47
static void rv32_base_cpu_init(Object *obj)
53
--- a/target/riscv/tcg/tcg-cpu.c
48
@@ -XXX,XX +XXX,XX @@ static void rv32_base_cpu_init(Object *obj)
54
+++ b/target/riscv/tcg/tcg-cpu.c
49
/* We set this in the realise function */
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
50
set_misa(env, MXL_RV32, 0);
56
51
register_cpu_props(DEVICE(obj));
57
/* The Zve64d extension depends on the Zve64f extension */
52
+ /* Set latest version of privileged specification */
58
if (cpu->cfg.ext_zve64d) {
53
+ set_priv_version(env, PRIV_VERSION_1_12_0);
59
+ if (!riscv_has_ext(env, RVD)) {
54
}
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
55
61
+ return;
56
static void rv32_sifive_u_cpu_init(Object *obj)
62
+ }
57
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
58
CPURISCVState *env = &cpu->env;
59
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
60
CPUClass *cc = CPU_CLASS(mcc);
61
- int priv_version = 0;
62
+ int priv_version = -1;
63
Error *local_err = NULL;
64
65
cpu_exec_realizefn(cs, &local_err);
66
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
67
}
64
}
68
}
65
69
66
- /* The Zve64f extension depends on the Zve32f extension */
70
- if (priv_version) {
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
71
+ if (priv_version >= PRIV_VERSION_1_10_0) {
68
if (cpu->cfg.ext_zve64f) {
72
set_priv_version(env, priv_version);
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
73
- } else if (!env->priv_ver) {
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
74
- set_priv_version(env, PRIV_VERSION_1_12_0);
71
}
75
}
72
76
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
77
if (cpu->cfg.mmu) {
74
- error_setg(errp, "Zve64d/V extensions require D extension");
75
- return;
76
+ /* The Zve64x extension depends on the Zve32x extension */
77
+ if (cpu->cfg.ext_zve64x) {
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
79
}
80
81
/* The Zve32f extension depends on the Zve32x extension */
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
83
return;
84
}
85
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
88
error_setg(
89
errp,
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
92
return;
93
}
94
95
--
78
--
96
2.45.1
79
2.36.1
diff view generated by jsdifflib
1
From: Cheng Yang <yangcheng.work@foxmail.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
3
We previously stored the device tree at a 16MB alignment from the end of
4
to set the address of initrd in FDT to support 64-bit address.
4
memory (or 3GB). This means we need at least 16MB of memory to be able
5
to do this. We don't actually need the FDT to be 16MB aligned, so let's
6
drop it down to 2MB so that we can support systems with less memory,
7
while also allowing FDT size expansion.
5
8
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/992
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
11
Reviewed-by: Atish Patra <atishp@rivosinc.com>
12
Reviewed-by: Bin Meng <bin.meng@windriver.com>
13
Tested-by: Bin Meng <bin.meng@windriver.com>
14
Message-Id: <20220608062015.317894-1-alistair.francis@opensource.wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
16
---
11
hw/riscv/boot.c | 4 ++--
17
hw/riscv/boot.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
18
1 file changed, 2 insertions(+), 2 deletions(-)
13
19
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
20
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
22
--- a/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
23
+++ b/hw/riscv/boot.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
24
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
25
/*
20
if (fdt) {
26
* We should put fdt as far as possible to avoid kernel/initrd overwriting
21
end = start + size;
27
* its content. But it should be addressable by 32 bit system as well.
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
28
- * Thus, put it at an 16MB aligned address that less than fdt size from the
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
29
+ * Thus, put it at an 2MB aligned address that less than fdt size from the
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
30
* end of dram or 3GB whichever is lesser.
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
31
*/
26
}
32
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
27
}
33
- fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB);
28
34
+ fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
35
36
ret = fdt_pack(fdt);
37
/* Should only fail if we've built a corrupted tree */
29
--
38
--
30
2.45.1
39
2.36.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Anup Patel <apatel@ventanamicro.com>
2
2
3
In current implementation, the gdbstub allows reading vector registers
3
The minimum priv spec versino for mcountinhibit to v1.11 so that it
4
only if V extension is supported. However, all vector extensions and
4
is not available for v1.10 (or lower).
5
vector crypto extensions have the vector registers and they all depend
6
on Zve32x. The gdbstub should check for Zve32x instead.
7
5
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
Fixes: eab4776b2bad ("target/riscv: Add support for hpmcounters/hpmevents")
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
9
Message-Id: <20220628101737.786681-3-apatel@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
target/riscv/gdbstub.c | 2 +-
12
target/riscv/csr.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
16
14
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
17
--- a/target/riscv/csr.c
20
+++ b/target/riscv/gdbstub.c
18
+++ b/target/riscv/csr.c
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
19
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
20
write_mhpmcounter },
23
0);
21
24
}
22
[CSR_MCOUNTINHIBIT] = { "mcountinhibit", any, read_mcountinhibit,
25
- if (env->misa_ext & RVV) {
23
- write_mcountinhibit },
26
+ if (cpu->cfg.ext_zve32x) {
24
+ write_mcountinhibit, .min_priv_ver = PRIV_VERSION_1_11_0 },
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
25
28
riscv_gdb_set_vector,
26
[CSR_MHPMEVENT3] = { "mhpmevent3", any, read_mhpmevent,
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
27
write_mhpmevent },
30
--
28
--
31
2.45.1
29
2.36.1
diff view generated by jsdifflib
1
From: Clément Léger <cleger@rivosinc.com>
1
From: Anup Patel <apatel@ventanamicro.com>
2
2
3
The current semihost exception number (16) is a reserved number (range
3
Based on architecture review committee feedback, the [m|s|vs]seteienum,
4
[16-17]). The upcoming double trap specification uses that number for
4
[m|s|vs]clreienum, [m|s|vs]seteipnum, and [m|s|vs]clreipnum CSRs are
5
the double trap exception. Since the privileged spec (Table 22) defines
5
removed in the latest AIA draft v0.3.0 specification.
6
ranges for custom uses change the semihosting exception number to 63
6
(Refer, https://github.com/riscv/riscv-aia/releases/tag/0.3.0-draft.31)
7
which belongs to the range [48-63] in order to avoid any future
7
8
collisions with reserved exception.
8
These CSRs were mostly for software convenience and software can always
9
9
use [m|s|vs]iselect and [m|s|vs]ireg CSRs to update the IMSIC interrupt
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
10
file bits.
11
11
12
We update the IMSIC CSR emulation as-per above to match the latest AIA
13
draft specification.
14
15
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
17
Message-Id: <20220616031543.953776-2-apatel@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
19
---
16
target/riscv/cpu_bits.h | 2 +-
20
target/riscv/cpu_bits.h | 24 +------
17
1 file changed, 1 insertion(+), 1 deletion(-)
21
target/riscv/csr.c | 150 +---------------------------------------
22
2 files changed, 6 insertions(+), 168 deletions(-)
18
23
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
24
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
20
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_bits.h
26
--- a/target/riscv/cpu_bits.h
22
+++ b/target/riscv/cpu_bits.h
27
+++ b/target/riscv/cpu_bits.h
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
28
@@ -XXX,XX +XXX,XX @@
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
29
#define CSR_MIREG 0x351
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
30
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
31
/* Machine-Level Interrupts (AIA) */
27
- RISCV_EXCP_SEMIHOST = 0x10,
32
-#define CSR_MTOPI 0xfb0
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
33
-
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
34
-/* Machine-Level IMSIC Interface (AIA) */
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
35
-#define CSR_MSETEIPNUM 0x358
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
36
-#define CSR_MCLREIPNUM 0x359
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
37
-#define CSR_MSETEIENUM 0x35a
33
} RISCVException;
38
-#define CSR_MCLREIENUM 0x35b
34
39
#define CSR_MTOPEI 0x35c
35
#define RISCV_EXCP_INT_FLAG 0x80000000
40
+#define CSR_MTOPI 0xfb0
41
42
/* Virtual Interrupts for Supervisor Level (AIA) */
43
#define CSR_MVIEN 0x308
44
@@ -XXX,XX +XXX,XX @@
45
#define CSR_SIREG 0x151
46
47
/* Supervisor-Level Interrupts (AIA) */
48
-#define CSR_STOPI 0xdb0
49
-
50
-/* Supervisor-Level IMSIC Interface (AIA) */
51
-#define CSR_SSETEIPNUM 0x158
52
-#define CSR_SCLREIPNUM 0x159
53
-#define CSR_SSETEIENUM 0x15a
54
-#define CSR_SCLREIENUM 0x15b
55
#define CSR_STOPEI 0x15c
56
+#define CSR_STOPI 0xdb0
57
58
/* Supervisor-Level High-Half CSRs (AIA) */
59
#define CSR_SIEH 0x114
60
@@ -XXX,XX +XXX,XX @@
61
#define CSR_VSIREG 0x251
62
63
/* VS-Level Interrupts (H-extension with AIA) */
64
-#define CSR_VSTOPI 0xeb0
65
-
66
-/* VS-Level IMSIC Interface (H-extension with AIA) */
67
-#define CSR_VSSETEIPNUM 0x258
68
-#define CSR_VSCLREIPNUM 0x259
69
-#define CSR_VSSETEIENUM 0x25a
70
-#define CSR_VSCLREIENUM 0x25b
71
#define CSR_VSTOPEI 0x25c
72
+#define CSR_VSTOPI 0xeb0
73
74
/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
75
#define CSR_HIDELEGH 0x613
76
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/target/riscv/csr.c
79
+++ b/target/riscv/csr.c
80
@@ -XXX,XX +XXX,XX @@ static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
81
return CSR_VSISELECT;
82
case CSR_SIREG:
83
return CSR_VSIREG;
84
- case CSR_SSETEIPNUM:
85
- return CSR_VSSETEIPNUM;
86
- case CSR_SCLREIPNUM:
87
- return CSR_VSCLREIPNUM;
88
- case CSR_SSETEIENUM:
89
- return CSR_VSSETEIENUM;
90
- case CSR_SCLREIENUM:
91
- return CSR_VSCLREIENUM;
92
case CSR_STOPEI:
93
return CSR_VSTOPEI;
94
default:
95
@@ -XXX,XX +XXX,XX @@ done:
96
return RISCV_EXCP_NONE;
97
}
98
99
-static int rmw_xsetclreinum(CPURISCVState *env, int csrno, target_ulong *val,
100
- target_ulong new_val, target_ulong wr_mask)
101
-{
102
- int ret = -EINVAL;
103
- bool set, pend, virt;
104
- target_ulong priv, isel, vgein, xlen, nval, wmask;
105
-
106
- /* Translate CSR number for VS-mode */
107
- csrno = aia_xlate_vs_csrno(env, csrno);
108
-
109
- /* Decode register details from CSR number */
110
- virt = set = pend = false;
111
- switch (csrno) {
112
- case CSR_MSETEIPNUM:
113
- priv = PRV_M;
114
- set = true;
115
- pend = true;
116
- break;
117
- case CSR_MCLREIPNUM:
118
- priv = PRV_M;
119
- pend = true;
120
- break;
121
- case CSR_MSETEIENUM:
122
- priv = PRV_M;
123
- set = true;
124
- break;
125
- case CSR_MCLREIENUM:
126
- priv = PRV_M;
127
- break;
128
- case CSR_SSETEIPNUM:
129
- priv = PRV_S;
130
- set = true;
131
- pend = true;
132
- break;
133
- case CSR_SCLREIPNUM:
134
- priv = PRV_S;
135
- pend = true;
136
- break;
137
- case CSR_SSETEIENUM:
138
- priv = PRV_S;
139
- set = true;
140
- break;
141
- case CSR_SCLREIENUM:
142
- priv = PRV_S;
143
- break;
144
- case CSR_VSSETEIPNUM:
145
- priv = PRV_S;
146
- virt = true;
147
- set = true;
148
- pend = true;
149
- break;
150
- case CSR_VSCLREIPNUM:
151
- priv = PRV_S;
152
- virt = true;
153
- pend = true;
154
- break;
155
- case CSR_VSSETEIENUM:
156
- priv = PRV_S;
157
- virt = true;
158
- set = true;
159
- break;
160
- case CSR_VSCLREIENUM:
161
- priv = PRV_S;
162
- virt = true;
163
- break;
164
- default:
165
- goto done;
166
- };
167
-
168
- /* IMSIC CSRs only available when machine implements IMSIC. */
169
- if (!env->aia_ireg_rmw_fn[priv]) {
170
- goto done;
171
- }
172
-
173
- /* Find the selected guest interrupt file */
174
- vgein = (virt) ? get_field(env->hstatus, HSTATUS_VGEIN) : 0;
175
-
176
- /* Selected guest interrupt file should be valid */
177
- if (virt && (!vgein || env->geilen < vgein)) {
178
- goto done;
179
- }
180
-
181
- /* Set/Clear CSRs always read zero */
182
- if (val) {
183
- *val = 0;
184
- }
185
-
186
- if (wr_mask) {
187
- /* Get interrupt number */
188
- new_val &= wr_mask;
189
-
190
- /* Find target interrupt pending/enable register */
191
- xlen = riscv_cpu_mxl_bits(env);
192
- isel = (new_val / xlen);
193
- isel *= (xlen / IMSIC_EIPx_BITS);
194
- isel += (pend) ? ISELECT_IMSIC_EIP0 : ISELECT_IMSIC_EIE0;
195
-
196
- /* Find the interrupt bit to be set/clear */
197
- wmask = ((target_ulong)1) << (new_val % xlen);
198
- nval = (set) ? wmask : 0;
199
-
200
- /* Call machine specific IMSIC register emulation */
201
- ret = env->aia_ireg_rmw_fn[priv](env->aia_ireg_rmw_fn_arg[priv],
202
- AIA_MAKE_IREG(isel, priv, virt,
203
- vgein, xlen),
204
- NULL, nval, wmask);
205
- } else {
206
- ret = 0;
207
- }
208
-
209
-done:
210
- if (ret) {
211
- return (riscv_cpu_virt_enabled(env) && virt) ?
212
- RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
213
- }
214
- return RISCV_EXCP_NONE;
215
-}
216
-
217
static int rmw_xtopei(CPURISCVState *env, int csrno, target_ulong *val,
218
target_ulong new_val, target_ulong wr_mask)
219
{
220
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
221
[CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
222
223
/* Machine-Level Interrupts (AIA) */
224
- [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
225
-
226
- /* Machine-Level IMSIC Interface (AIA) */
227
- [CSR_MSETEIPNUM] = { "mseteipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
228
- [CSR_MCLREIPNUM] = { "mclreipnum", aia_any, NULL, NULL, rmw_xsetclreinum },
229
- [CSR_MSETEIENUM] = { "mseteienum", aia_any, NULL, NULL, rmw_xsetclreinum },
230
- [CSR_MCLREIENUM] = { "mclreienum", aia_any, NULL, NULL, rmw_xsetclreinum },
231
[CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
232
+ [CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
233
234
/* Virtual Interrupts for Supervisor Level (AIA) */
235
[CSR_MVIEN] = { "mvien", aia_any, read_zero, write_ignore },
236
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
237
[CSR_SIREG] = { "sireg", aia_smode, NULL, NULL, rmw_xireg },
238
239
/* Supervisor-Level Interrupts (AIA) */
240
- [CSR_STOPI] = { "stopi", aia_smode, read_stopi },
241
-
242
- /* Supervisor-Level IMSIC Interface (AIA) */
243
- [CSR_SSETEIPNUM] = { "sseteipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
244
- [CSR_SCLREIPNUM] = { "sclreipnum", aia_smode, NULL, NULL, rmw_xsetclreinum },
245
- [CSR_SSETEIENUM] = { "sseteienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
246
- [CSR_SCLREIENUM] = { "sclreienum", aia_smode, NULL, NULL, rmw_xsetclreinum },
247
[CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei },
248
+ [CSR_STOPI] = { "stopi", aia_smode, read_stopi },
249
250
/* Supervisor-Level High-Half CSRs (AIA) */
251
[CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh },
252
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
253
[CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
254
255
/* VS-Level Interrupts (H-extension with AIA) */
256
- [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
257
-
258
- /* VS-Level IMSIC Interface (H-extension with AIA) */
259
- [CSR_VSSETEIPNUM] = { "vsseteipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
260
- [CSR_VSCLREIPNUM] = { "vsclreipnum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
261
- [CSR_VSSETEIENUM] = { "vsseteienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
262
- [CSR_VSCLREIENUM] = { "vsclreienum", aia_hmode, NULL, NULL, rmw_xsetclreinum },
263
[CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
264
+ [CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
265
266
/* Hypervisor and VS-Level High-Half CSRs (H-extension with AIA) */
267
[CSR_HIDELEGH] = { "hidelegh", aia_hmode32, NULL, NULL, rmw_hidelegh },
36
--
268
--
37
2.45.1
269
2.36.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
1
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
4
enabled, will fail with a kernel oops SIGILL right at the start. The
5
reason is that we can't expose zkr without implementing the SEED CSR.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
8
9
In hindsight this is too strict. If we keep proceeding, despite not
10
disabling the extension in the KVM vcpu, we'll not add the extension in
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
14
15
Change our current logic to not error out if we fail to disable an
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
17
is important to throw a warning because we must make the user aware that
18
the extension is still available in the vcpu, meaning that an
19
ill-behaved guest can ignore the riscv,isa settings and use the
20
extension.
21
22
The case we're handling happens with an EINVAL error code. If we fail to
23
disable the extension in KVM for any other reason, error out.
24
25
We'll also keep erroring out when we fail to enable an extension in KVM,
26
since adding the extension in riscv,isa at this point will cause a guest
27
malfunction because the extension isn't enabled in the vcpu.
28
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
37
1 file changed, 8 insertions(+), 4 deletions(-)
38
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
45
ret = kvm_set_one_reg(cs, id, &reg);
46
if (ret != 0) {
47
- error_report("Unable to %s extension %s in KVM, error %d",
48
- reg ? "enable" : "disable",
49
- multi_ext_cfg->name, ret);
50
- exit(EXIT_FAILURE);
51
+ if (!reg && ret == -EINVAL) {
52
+ warn_report("KVM cannot disable extension %s",
53
+ multi_ext_cfg->name);
54
+ } else {
55
+ error_report("Unable to enable extension %s in KVM, error %d",
56
+ multi_ext_cfg->name, ret);
57
+ exit(EXIT_FAILURE);
58
+ }
59
}
60
}
61
}
62
--
63
2.45.1
diff view generated by jsdifflib
Deleted patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
1
3
We're not setting (s/m)tval when triggering breakpoints of type 2
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
5
5.7.12, "Match Control Type 6":
6
7
"The Privileged Spec says that breakpoint exceptions that occur on
8
instruction fetches, loads, or stores update the tval CSR with either
9
zero or the faulting virtual address. The faulting virtual address for
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
which caused that trigger to fire."
12
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
14
mcontrol.
15
16
Note that what we're doing ATM is not violating the spec, but it's
17
simple enough to set mtval/stval and it makes life easier for any
18
software that relies on this info.
19
20
Given that we always use action = 0, save the faulting address for the
21
mcontrol and mcontrol6 trigger breakpoints into env->badaddr, which is
22
used as as scratch area for traps with address information. 'tval' is
23
then set during riscv_cpu_do_interrupt().
24
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
31
target/riscv/cpu_helper.c | 1 +
32
target/riscv/debug.c | 3 +++
33
2 files changed, 4 insertions(+)
34
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
40
tval = env->bins;
41
break;
42
case RISCV_EXCP_BREAKPOINT:
43
+ tval = env->badaddr;
44
if (cs->watchpoint_hit) {
45
tval = cs->watchpoint_hit->hitaddr;
46
cs->watchpoint_hit = NULL;
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/debug.c
50
+++ b/target/riscv/debug.c
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
53
/* check U/S/M bit against current privilege level */
54
if ((ctrl >> 3) & BIT(env->priv)) {
55
+ env->badaddr = pc;
56
return true;
57
}
58
}
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
60
if (env->virt_enabled) {
61
/* check VU/VS bit against current privilege level */
62
if ((ctrl >> 23) & BIT(env->priv)) {
63
+ env->badaddr = pc;
64
return true;
65
}
66
} else {
67
/* check U/S/M bit against current privilege level */
68
if ((ctrl >> 3) & BIT(env->priv)) {
69
+ env->badaddr = pc;
70
return true;
71
}
72
}
73
--
74
2.45.1
diff view generated by jsdifflib
Deleted patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
1
3
Privileged spec section 4.1.9 mentions:
4
5
"When a trap is taken into S-mode, stval is written with
6
exception-specific information to assist software in handling the trap.
7
(...)
8
9
If stval is written with a nonzero value when a breakpoint,
10
address-misaligned, access-fault, or page-fault exception occurs on an
11
instruction fetch, load, or store, then stval will contain the faulting
12
virtual address."
13
14
A similar text is found for mtval in section 3.1.16.
15
16
Setting mtval/stval in this scenario is optional, but some softwares read
17
these regs when handling ebreaks.
18
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
20
'tval' during riscv_do_cpu_interrrupt().
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
30
1 file changed, 2 insertions(+)
31
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
39
} else {
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
41
+ offsetof(CPURISCVState, badaddr));
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
43
}
44
return true;
45
--
46
2.45.1
diff view generated by jsdifflib
Deleted patch
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
1
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
5
agnostic policy.
6
7
However, this function can't deal the big endian situation. This patch fixes
8
the problem by adding handling of such case.
9
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
18
1 file changed, 22 insertions(+)
19
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/vector_internals.c
23
+++ b/target/riscv/vector_internals.c
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
25
if (tot - cnt == 0) {
26
return ;
27
}
28
+
29
+ if (HOST_BIG_ENDIAN) {
30
+ /*
31
+ * Deal the situation when the elements are insdie
32
+ * only one uint64 block including setting the
33
+ * masked-off element.
34
+ */
35
+ if (((tot - 1) ^ cnt) < 8) {
36
+ memset(base + H1(tot - 1), -1, tot - cnt);
37
+ return;
38
+ }
39
+ /*
40
+ * Otherwise, at least cross two uint64_t blocks.
41
+ * Set first unaligned block.
42
+ */
43
+ if (cnt % 8 != 0) {
44
+ uint32_t j = ROUND_UP(cnt, 8);
45
+ memset(base + H1(j - 1), -1, j - cnt);
46
+ cnt = j;
47
+ }
48
+ /* Set other 64bit aligend blocks */
49
+ }
50
memset(base + cnt, -1, tot - cnt);
51
}
52
53
--
54
2.45.1
diff view generated by jsdifflib
Deleted patch
1
From: Max Chou <max.chou@sifive.com>
2
1
3
The require_scale_rvf function only checks the double width operator for
4
the vector floating point widen instructions, so most of the widen
5
checking functions need to add require_rvf for single width operator.
6
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
8
integer to double width float, so the opfxv_widen_check function doesn’t
9
need require_rvf for the single width operator(integer).
10
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
18
1 file changed, 5 insertions(+)
19
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
26
{
27
return require_rvv(s) &&
28
+ require_rvf(s) &&
29
require_scale_rvf(s) &&
30
(s->sew != MO_8) &&
31
vext_check_isa_ill(s) &&
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
34
{
35
return require_rvv(s) &&
36
+ require_rvf(s) &&
37
require_scale_rvf(s) &&
38
(s->sew != MO_8) &&
39
vext_check_isa_ill(s) &&
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
42
{
43
return require_rvv(s) &&
44
+ require_rvf(s) &&
45
require_scale_rvf(s) &&
46
(s->sew != MO_8) &&
47
vext_check_isa_ill(s) &&
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
50
{
51
return require_rvv(s) &&
52
+ require_rvf(s) &&
53
require_scale_rvf(s) &&
54
(s->sew != MO_8) &&
55
vext_check_isa_ill(s) &&
56
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
57
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
58
{
59
return reduction_widen_check(s, a) &&
60
+ require_rvf(s) &&
61
require_scale_rvf(s) &&
62
(s->sew != MO_8);
63
}
64
--
65
2.45.1
66
67
diff view generated by jsdifflib
Deleted patch
1
From: Max Chou <max.chou@sifive.com>
2
1
3
The opfv_narrow_check needs to check the single width float operator by
4
require_rvf.
5
6
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
21
{
22
return opfv_narrow_check(s, a) &&
23
+ require_rvf(s) &&
24
require_scale_rvf(s) &&
25
(s->sew != MO_8);
26
}
27
--
28
2.45.1
diff view generated by jsdifflib
Deleted patch
1
From: Max Chou <max.chou@sifive.com>
2
1
3
If the checking functions check both the single and double width
4
operators at the same time, then the single width operator checking
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
14
1 file changed, 4 insertions(+), 12 deletions(-)
15
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
21
return require_rvv(s) &&
22
require_rvf(s) &&
23
require_scale_rvf(s) &&
24
- (s->sew != MO_8) &&
25
vext_check_isa_ill(s) &&
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
27
}
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
29
return require_rvv(s) &&
30
require_rvf(s) &&
31
require_scale_rvf(s) &&
32
- (s->sew != MO_8) &&
33
vext_check_isa_ill(s) &&
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
37
return require_rvv(s) &&
38
require_rvf(s) &&
39
require_scale_rvf(s) &&
40
- (s->sew != MO_8) &&
41
vext_check_isa_ill(s) &&
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
45
return require_rvv(s) &&
46
require_rvf(s) &&
47
require_scale_rvf(s) &&
48
- (s->sew != MO_8) &&
49
vext_check_isa_ill(s) &&
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
53
{
54
return opfv_widen_check(s, a) &&
55
require_rvfmin(s) &&
56
- require_scale_rvfmin(s) &&
57
- (s->sew != MO_8);
58
+ require_scale_rvfmin(s);
59
}
60
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
63
{
64
return opfv_narrow_check(s, a) &&
65
require_rvfmin(s) &&
66
- require_scale_rvfmin(s) &&
67
- (s->sew != MO_8);
68
+ require_scale_rvfmin(s);
69
}
70
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
72
{
73
return opfv_narrow_check(s, a) &&
74
require_rvf(s) &&
75
- require_scale_rvf(s) &&
76
- (s->sew != MO_8);
77
+ require_scale_rvf(s);
78
}
79
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
82
{
83
return reduction_widen_check(s, a) &&
84
require_rvf(s) &&
85
- require_scale_rvf(s) &&
86
- (s->sew != MO_8);
87
+ require_scale_rvf(s);
88
}
89
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
91
--
92
2.45.1
diff view generated by jsdifflib
Deleted patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
1
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
4
checking first if virt_enabled && !first_stage, and then considering the
5
regular inst/load/store faults.
6
7
There's no mention in the spec about guest page fault being a higher
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
9
10
"Attempting to fetch an instruction from a PMP region that does not have
11
execute permissions raises an instruction access-fault exception.
12
Attempting to execute a load or load-reserved instruction which accesses
13
a physical address within a PMP region without read permissions raises a
14
load access-fault exception. Attempting to execute a store,
15
store-conditional, or AMO instruction which accesses a physical address
16
within a PMP region without write permissions raises a store
17
access-fault exception."
18
19
So, in fact, we're doing it wrong - PMP faults should always be thrown,
20
regardless of also being a first or second stage fault.
21
22
The way riscv_cpu_tlb_fill() and get_physical_address() work is
23
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
24
reflected in the 'pmp_violation' flag. What we need is to change
25
raise_mmu_exception() to prioritize it.
26
27
Reported-by: Joseph Chan <jchan@ventanamicro.com>
28
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
29
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
36
1 file changed, 12 insertions(+), 10 deletions(-)
37
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
43
44
switch (access_type) {
45
case MMU_INST_FETCH:
46
- if (env->virt_enabled && !first_stage) {
47
+ if (pmp_violation) {
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
49
+ } else if (env->virt_enabled && !first_stage) {
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
51
} else {
52
- cs->exception_index = pmp_violation ?
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
55
}
56
break;
57
case MMU_DATA_LOAD:
58
- if (two_stage && !first_stage) {
59
+ if (pmp_violation) {
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
61
+ } else if (two_stage && !first_stage) {
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
63
} else {
64
- cs->exception_index = pmp_violation ?
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
67
}
68
break;
69
case MMU_DATA_STORE:
70
- if (two_stage && !first_stage) {
71
+ if (pmp_violation) {
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
73
+ } else if (two_stage && !first_stage) {
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
75
} else {
76
- cs->exception_index = pmp_violation ?
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
78
- RISCV_EXCP_STORE_PAGE_FAULT;
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
80
}
81
break;
82
default:
83
--
84
2.45.1
diff view generated by jsdifflib
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
1
From: Anup Patel <apatel@ventanamicro.com>
2
2
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
3
The latest AIA draft v0.3.0 defines a relatively simpler scheme for
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
4
default priority assignments where:
5
translation part, mtval2 will be set in case of successes 2 stage translation but
5
1) local interrupts 24 to 31 and 48 to 63 are reserved for custom use
6
failed pmp check.
6
and have implementation specific default priority.
7
7
2) remaining local interrupts 0 to 23 and 32 to 47 have a recommended
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
8
(not mandatory) priority assignments.
9
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
9
10
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
10
We update the default priority table and hviprio mapping as-per above.
11
page-fault is taken into M-mode, mtval2 is written with either zero or guest
11
12
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
12
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
13
is set to zero...*
14
15
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
14
Message-Id: <20220616031543.953776-3-apatel@ventanamicro.com>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
16
---
22
target/riscv/cpu_helper.c | 12 ++++++------
17
target/riscv/cpu_bits.h | 2 +-
23
1 file changed, 6 insertions(+), 6 deletions(-)
18
target/riscv/cpu_helper.c | 134 ++++++++++++++++++--------------------
24
19
2 files changed, 66 insertions(+), 70 deletions(-)
20
21
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_bits.h
24
+++ b/target/riscv/cpu_bits.h
25
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
26
#define IPRIO_IRQ_BITS 8
27
#define IPRIO_MMAXIPRIO 255
28
#define IPRIO_DEFAULT_UPPER 4
29
-#define IPRIO_DEFAULT_MIDDLE (IPRIO_DEFAULT_UPPER + 24)
30
+#define IPRIO_DEFAULT_MIDDLE (IPRIO_DEFAULT_UPPER + 12)
31
#define IPRIO_DEFAULT_M IPRIO_DEFAULT_MIDDLE
32
#define IPRIO_DEFAULT_S (IPRIO_DEFAULT_M + 3)
33
#define IPRIO_DEFAULT_SGEXT (IPRIO_DEFAULT_S + 3)
25
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
34
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/cpu_helper.c
36
--- a/target/riscv/cpu_helper.c
28
+++ b/target/riscv/cpu_helper.c
37
+++ b/target/riscv/cpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
38
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_update_mask(CPURISCVState *env)
30
__func__, pa, ret, prot_pmp, tlb_size);
39
* 14 "
31
40
* 15 "
32
prot &= prot_pmp;
41
* 16 "
33
- }
42
- * 18 Debug/trace interrupt
34
-
43
- * 20 (Reserved interrupt)
35
- if (ret != TRANSLATE_SUCCESS) {
44
+ * 17 "
36
+ } else {
45
+ * 18 "
37
/*
46
+ * 19 "
38
* Guest physical address translation failed, this is a HS
47
+ * 20 "
39
* level exception
48
+ * 21 "
40
*/
49
* 22 "
41
first_stage_error = false;
50
- * 24 "
42
- env->guest_phys_fault_addr = (im_address |
51
- * 26 "
43
- (address &
52
- * 28 "
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
53
- * 30 (Reserved for standard reporting of bus or system errors)
45
+ if (ret != TRANSLATE_PMP_FAIL) {
54
+ * 23 "
46
+ env->guest_phys_fault_addr = (im_address |
55
*/
47
+ (address &
56
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
57
static const int hviprio_index2irq[] = {
49
+ }
58
- 0, 1, 4, 5, 8, 13, 14, 15, 16, 18, 20, 22, 24, 26, 28, 30 };
50
}
59
+ 0, 1, 4, 5, 8, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 };
51
}
60
static const int hviprio_index2rdzero[] = {
52
} else {
61
1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
62
63
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_hviprio_index2irq(int index, int *out_irq, int *out_rdzero)
64
* Default |
65
* Priority | Major Interrupt Numbers
66
* ----------------------------------------------------------------
67
- * Highest | 63 (3f), 62 (3e), 31 (1f), 30 (1e), 61 (3d), 60 (3c),
68
- * | 59 (3b), 58 (3a), 29 (1d), 28 (1c), 57 (39), 56 (38),
69
- * | 55 (37), 54 (36), 27 (1b), 26 (1a), 53 (35), 52 (34),
70
- * | 51 (33), 50 (32), 25 (19), 24 (18), 49 (31), 48 (30)
71
+ * Highest | 47, 23, 46, 45, 22, 44,
72
+ * | 43, 21, 42, 41, 20, 40
73
* |
74
* | 11 (0b), 3 (03), 7 (07)
75
* | 9 (09), 1 (01), 5 (05)
76
* | 12 (0c)
77
* | 10 (0a), 2 (02), 6 (06)
78
* |
79
- * | 47 (2f), 46 (2e), 23 (17), 22 (16), 45 (2d), 44 (2c),
80
- * | 43 (2b), 42 (2a), 21 (15), 20 (14), 41 (29), 40 (28),
81
- * | 39 (27), 38 (26), 19 (13), 18 (12), 37 (25), 36 (24),
82
- * Lowest | 35 (23), 34 (22), 17 (11), 16 (10), 33 (21), 32 (20)
83
+ * | 39, 19, 38, 37, 18, 36,
84
+ * Lowest | 35, 17, 34, 33, 16, 32
85
* ----------------------------------------------------------------
86
*/
87
static const uint8_t default_iprio[64] = {
88
- [63] = IPRIO_DEFAULT_UPPER,
89
- [62] = IPRIO_DEFAULT_UPPER + 1,
90
- [31] = IPRIO_DEFAULT_UPPER + 2,
91
- [30] = IPRIO_DEFAULT_UPPER + 3,
92
- [61] = IPRIO_DEFAULT_UPPER + 4,
93
- [60] = IPRIO_DEFAULT_UPPER + 5,
94
-
95
- [59] = IPRIO_DEFAULT_UPPER + 6,
96
- [58] = IPRIO_DEFAULT_UPPER + 7,
97
- [29] = IPRIO_DEFAULT_UPPER + 8,
98
- [28] = IPRIO_DEFAULT_UPPER + 9,
99
- [57] = IPRIO_DEFAULT_UPPER + 10,
100
- [56] = IPRIO_DEFAULT_UPPER + 11,
101
-
102
- [55] = IPRIO_DEFAULT_UPPER + 12,
103
- [54] = IPRIO_DEFAULT_UPPER + 13,
104
- [27] = IPRIO_DEFAULT_UPPER + 14,
105
- [26] = IPRIO_DEFAULT_UPPER + 15,
106
- [53] = IPRIO_DEFAULT_UPPER + 16,
107
- [52] = IPRIO_DEFAULT_UPPER + 17,
108
-
109
- [51] = IPRIO_DEFAULT_UPPER + 18,
110
- [50] = IPRIO_DEFAULT_UPPER + 19,
111
- [25] = IPRIO_DEFAULT_UPPER + 20,
112
- [24] = IPRIO_DEFAULT_UPPER + 21,
113
- [49] = IPRIO_DEFAULT_UPPER + 22,
114
- [48] = IPRIO_DEFAULT_UPPER + 23,
115
+ /* Custom interrupts 48 to 63 */
116
+ [63] = IPRIO_MMAXIPRIO,
117
+ [62] = IPRIO_MMAXIPRIO,
118
+ [61] = IPRIO_MMAXIPRIO,
119
+ [60] = IPRIO_MMAXIPRIO,
120
+ [59] = IPRIO_MMAXIPRIO,
121
+ [58] = IPRIO_MMAXIPRIO,
122
+ [57] = IPRIO_MMAXIPRIO,
123
+ [56] = IPRIO_MMAXIPRIO,
124
+ [55] = IPRIO_MMAXIPRIO,
125
+ [54] = IPRIO_MMAXIPRIO,
126
+ [53] = IPRIO_MMAXIPRIO,
127
+ [52] = IPRIO_MMAXIPRIO,
128
+ [51] = IPRIO_MMAXIPRIO,
129
+ [50] = IPRIO_MMAXIPRIO,
130
+ [49] = IPRIO_MMAXIPRIO,
131
+ [48] = IPRIO_MMAXIPRIO,
132
+
133
+ /* Custom interrupts 24 to 31 */
134
+ [31] = IPRIO_MMAXIPRIO,
135
+ [30] = IPRIO_MMAXIPRIO,
136
+ [29] = IPRIO_MMAXIPRIO,
137
+ [28] = IPRIO_MMAXIPRIO,
138
+ [27] = IPRIO_MMAXIPRIO,
139
+ [26] = IPRIO_MMAXIPRIO,
140
+ [25] = IPRIO_MMAXIPRIO,
141
+ [24] = IPRIO_MMAXIPRIO,
142
+
143
+ [47] = IPRIO_DEFAULT_UPPER,
144
+ [23] = IPRIO_DEFAULT_UPPER + 1,
145
+ [46] = IPRIO_DEFAULT_UPPER + 2,
146
+ [45] = IPRIO_DEFAULT_UPPER + 3,
147
+ [22] = IPRIO_DEFAULT_UPPER + 4,
148
+ [44] = IPRIO_DEFAULT_UPPER + 5,
149
+
150
+ [43] = IPRIO_DEFAULT_UPPER + 6,
151
+ [21] = IPRIO_DEFAULT_UPPER + 7,
152
+ [42] = IPRIO_DEFAULT_UPPER + 8,
153
+ [41] = IPRIO_DEFAULT_UPPER + 9,
154
+ [20] = IPRIO_DEFAULT_UPPER + 10,
155
+ [40] = IPRIO_DEFAULT_UPPER + 11,
156
157
[11] = IPRIO_DEFAULT_M,
158
[3] = IPRIO_DEFAULT_M + 1,
159
@@ -XXX,XX +XXX,XX @@ static const uint8_t default_iprio[64] = {
160
[2] = IPRIO_DEFAULT_VS + 1,
161
[6] = IPRIO_DEFAULT_VS + 2,
162
163
- [47] = IPRIO_DEFAULT_LOWER,
164
- [46] = IPRIO_DEFAULT_LOWER + 1,
165
- [23] = IPRIO_DEFAULT_LOWER + 2,
166
- [22] = IPRIO_DEFAULT_LOWER + 3,
167
- [45] = IPRIO_DEFAULT_LOWER + 4,
168
- [44] = IPRIO_DEFAULT_LOWER + 5,
169
-
170
- [43] = IPRIO_DEFAULT_LOWER + 6,
171
- [42] = IPRIO_DEFAULT_LOWER + 7,
172
- [21] = IPRIO_DEFAULT_LOWER + 8,
173
- [20] = IPRIO_DEFAULT_LOWER + 9,
174
- [41] = IPRIO_DEFAULT_LOWER + 10,
175
- [40] = IPRIO_DEFAULT_LOWER + 11,
176
-
177
- [39] = IPRIO_DEFAULT_LOWER + 12,
178
- [38] = IPRIO_DEFAULT_LOWER + 13,
179
- [19] = IPRIO_DEFAULT_LOWER + 14,
180
- [18] = IPRIO_DEFAULT_LOWER + 15,
181
- [37] = IPRIO_DEFAULT_LOWER + 16,
182
- [36] = IPRIO_DEFAULT_LOWER + 17,
183
-
184
- [35] = IPRIO_DEFAULT_LOWER + 18,
185
- [34] = IPRIO_DEFAULT_LOWER + 19,
186
- [17] = IPRIO_DEFAULT_LOWER + 20,
187
- [16] = IPRIO_DEFAULT_LOWER + 21,
188
- [33] = IPRIO_DEFAULT_LOWER + 22,
189
- [32] = IPRIO_DEFAULT_LOWER + 23,
190
+ [39] = IPRIO_DEFAULT_LOWER,
191
+ [19] = IPRIO_DEFAULT_LOWER + 1,
192
+ [38] = IPRIO_DEFAULT_LOWER + 2,
193
+ [37] = IPRIO_DEFAULT_LOWER + 3,
194
+ [18] = IPRIO_DEFAULT_LOWER + 4,
195
+ [36] = IPRIO_DEFAULT_LOWER + 5,
196
+
197
+ [35] = IPRIO_DEFAULT_LOWER + 6,
198
+ [17] = IPRIO_DEFAULT_LOWER + 7,
199
+ [34] = IPRIO_DEFAULT_LOWER + 8,
200
+ [33] = IPRIO_DEFAULT_LOWER + 9,
201
+ [16] = IPRIO_DEFAULT_LOWER + 10,
202
+ [32] = IPRIO_DEFAULT_LOWER + 11,
203
};
204
205
uint8_t riscv_cpu_default_priority(int irq)
53
--
206
--
54
2.45.1
207
2.36.1
diff view generated by jsdifflib