1
The following changes since commit 4d285821c5055ed68a6f6b7693fd11a06a1aa426:
1
The following changes since commit 0e3aff9ec34059512d597eacfcf4d1b5d4570c50:
2
2
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200618' into staging (2020-06-19 11:44:03 +0100)
3
Merge tag 'pull-10.0-gdb-plugins-doc-updates-170125-1' of https://gitlab.com/stsquad/qemu into staging (2025-01-17 10:13:07 -0500)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20200619-3
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20250119-1
8
8
9
for you to fetch changes up to 3eaea6eb4e534f7b87c6eca808149bb671976800:
9
for you to fetch changes up to f04cac4f8f254931f2af9d059b2175769e576afa:
10
10
11
hw/riscv: sifive_u: Add a dummy DDR memory controller device (2020-06-19 08:25:27 -0700)
11
hw/char/riscv_htif: Convert HTIF_DEBUG() to trace events (2025-01-19 09:44:35 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
This is a range of patches for RISC-V.
14
Second RISC-V PR for 10.0
15
15
16
Some key points are:
16
* Reduce the overhead for simple RISC-V vector unit-stride loads and stores
17
- Generalise the CPU init functions
17
* Add V bit to GDB priv reg
18
- Support the SiFive revB machine
18
* Add 'sha' support
19
- Improvements to the Hypervisor implementation and error checking
19
* Add traces for exceptions in user mode
20
- Connect some OpenTitan devices
20
* Update Pointer Masking to Zjpm v1.0
21
- Changes to the sifive_u machine to support U-boot
21
* Add Smrnmi support
22
22
* Fix timebase-frequency when using KVM acceleration
23
v2:
23
* Add RISC-V Counter delegation ISA extension support
24
- Fix missing realise assert
24
* Add support for Smdbltrp and Ssdbltrp extensions
25
* Introduce a translation tag for the IOMMU page table cache
26
* Support Supm and Sspm as part of Zjpm v1.0
27
* Convert htif debug prints to trace event
25
28
26
----------------------------------------------------------------
29
----------------------------------------------------------------
27
Alistair Francis (11):
30
Alexey Baturo (8):
28
sifive_e: Support the revB machine
31
target/riscv: Remove obsolete pointer masking extension code.
29
target/riscv: Set access as data_load when validating stage-2 PTEs
32
target/riscv: Add new CSR fields for S{sn, mn, m}pm extensions as part of Zjpm v1.0
30
target/riscv: Report errors validating 2nd-stage PTEs
33
target/riscv: Add helper functions to calculate current number of masked bits for pointer masking
31
target/riscv: Move the hfence instructions to the rvh decode
34
target/riscv: Add pointer masking tb flags
32
target/riscv: Implement checks for hfence
35
target/riscv: Update address modify functions to take into account pointer masking
33
riscv/opentitan: Fix the ROM size
36
target/riscv: Apply pointer masking for virtualized memory accesses
34
hw/char: Initial commit of Ibex UART
37
target/riscv: Enable updates for pointer masking variables and thus enable pointer masking extension
35
hw/intc: Initial commit of lowRISC Ibex PLIC
38
target/riscv: Support Supm and Sspm as part of Zjpm v1.0
36
riscv/opentitan: Connect the PLIC device
37
riscv/opentitan: Connect the UART device
38
target/riscv: Use a smaller guess size for no-MMU PMP
39
39
40
Bin Meng (20):
40
Atish Patra (5):
41
riscv: Generalize CPU init routine for the base CPU
41
target/riscv: Enable S*stateen bits for AIA
42
riscv: Generalize CPU init routine for the gcsu CPU
42
target/riscv: Add properties for counter delegation ISA extensions
43
riscv: Generalize CPU init routine for the imacu CPU
43
target/riscv: Invoke pmu init after feature enable
44
riscv: Keep the CPU init routine names consistent
44
target/riscv: Add implied rule for counter delegation extensions
45
hw/riscv: sifive_e: Remove the riscv_ prefix of the machine* and soc* functions
45
target/riscv: Add configuration for S[m|s]csrind, Smcdeleg/Ssccfg
46
hw/riscv: opentitan: Remove the riscv_ prefix of the machine* and soc* functions
47
hw/riscv: sifive_u: Simplify the GEM IRQ connect code a little bit
48
hw/riscv: sifive_u: Generate device tree node for OTP
49
hw/riscv: sifive_gpio: Clean up the codes
50
hw/riscv: sifive_gpio: Add a new 'ngpio' property
51
hw/riscv: sifive_u: Hook a GPIO controller
52
hw/riscv: sifive_gpio: Do not blindly trigger output IRQs
53
hw/riscv: sifive_u: Add reset functionality
54
hw/riscv: sifive_u: Rename serial property get/set functions to a generic name
55
hw/riscv: sifive_u: Add a new property msel for MSEL pin state
56
target/riscv: Rename IBEX CPU init routine
57
hw/riscv: sifive: Change SiFive E/U CPU reset vector to 0x1004
58
hw/riscv: sifive_u: Support different boot source per MSEL pin state
59
hw/riscv: sifive_u: Sort the SoC memmap table entries
60
hw/riscv: sifive_u: Add a dummy DDR memory controller device
61
46
62
Ian Jiang (1):
47
Clément Léger (9):
63
riscv: Add helper to make NaN-boxing for FP register
48
target/riscv: Fix henvcfg potentially containing stale bits
49
target/riscv: Add Ssdbltrp CSRs handling
50
target/riscv: Implement Ssdbltrp sret, mret and mnret behavior
51
target/riscv: Implement Ssdbltrp exception handling
52
target/riscv: Add Ssdbltrp ISA extension enable switch
53
target/riscv: Add Smdbltrp CSRs handling
54
target/riscv: Implement Smdbltrp sret, mret and mnret behavior
55
target/riscv: Implement Smdbltrp behavior
56
target/riscv: Add Smdbltrp ISA extension enable switch
64
57
65
include/hw/char/ibex_uart.h | 110 ++++++
58
Craig Blackmore (2):
66
include/hw/intc/ibex_plic.h | 63 ++++
59
target/riscv: rvv: fix typo in vext continuous ldst function names
67
include/hw/riscv/opentitan.h | 16 +
60
target/riscv: rvv: speed up small unit-stride loads and stores
68
include/hw/riscv/sifive_e.h | 1 +
69
include/hw/riscv/sifive_gpio.h | 8 +-
70
include/hw/riscv/sifive_u.h | 27 ++
71
target/riscv/helper.h | 5 +
72
target/riscv/insn32.decode | 8 +-
73
hw/char/ibex_uart.c | 492 +++++++++++++++++++++++++
74
hw/intc/ibex_plic.c | 261 +++++++++++++
75
hw/riscv/opentitan.c | 71 +++-
76
hw/riscv/sifive_e.c | 60 ++-
77
hw/riscv/sifive_gpio.c | 45 ++-
78
hw/riscv/sifive_u.c | 157 ++++++--
79
target/riscv/cpu.c | 69 ++--
80
target/riscv/cpu_helper.c | 9 +-
81
target/riscv/insn_trans/trans_privileged.inc.c | 38 --
82
target/riscv/insn_trans/trans_rvf.inc.c | 17 +-
83
target/riscv/insn_trans/trans_rvh.inc.c | 37 ++
84
target/riscv/op_helper.c | 13 +
85
target/riscv/pmp.c | 14 +-
86
target/riscv/translate.c | 1 +
87
MAINTAINERS | 4 +
88
hw/char/Makefile.objs | 1 +
89
hw/intc/Makefile.objs | 1 +
90
hw/riscv/Kconfig | 4 +
91
26 files changed, 1350 insertions(+), 182 deletions(-)
92
create mode 100644 include/hw/char/ibex_uart.h
93
create mode 100644 include/hw/intc/ibex_plic.h
94
create mode 100644 hw/char/ibex_uart.c
95
create mode 100644 hw/intc/ibex_plic.c
96
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
97
61
62
Daniel Henrique Barboza (9):
63
target/riscv: add shcounterenw
64
target/riscv: add shvstvala
65
target/riscv: add shtvala
66
target/riscv: add shvstvecd
67
target/riscv: add shvsatpa
68
target/riscv: add shgatpa
69
target/riscv/tcg: add sha
70
target/riscv: use RISCVException enum in exception helpers
71
target/riscv: add trace in riscv_raise_exception()
72
73
Frank Chang (1):
74
target/riscv: Add Zicfilp support for Smrnmi
75
76
Jason Chien (1):
77
hw/riscv/riscv-iommu.c: Introduce a translation tag for the page table cache
78
79
Kaiwen Xue (6):
80
target/riscv: Add properties for Indirect CSR Access extension
81
target/riscv: Decouple AIA processing from xiselect and xireg
82
target/riscv: Support generic CSR indirect access
83
target/riscv: Add counter delegation definitions
84
target/riscv: Add select value range check for counter delegation
85
target/riscv: Add counter delegation/configuration support
86
87
Philippe Mathieu-Daudé (3):
88
target/riscv: Have kvm_riscv_get_timebase_frequency() take RISCVCPU cpu
89
hw/riscv/virt: Remove unnecessary use of &first_cpu
90
hw/char/riscv_htif: Convert HTIF_DEBUG() to trace events
91
92
Tommy Wu (5):
93
target/riscv: Add 'ext_smrnmi' in the RISCVCPUConfig
94
target/riscv: Add Smrnmi CSRs
95
target/riscv: Handle Smrnmi interrupt and exception
96
target/riscv: Add Smrnmi mnret instruction
97
target/riscv: Add Smrnmi cpu extension
98
99
Yanfeng Liu (1):
100
riscv/gdbstub: add V bit to priv reg
101
102
include/hw/riscv/riscv_hart.h | 4 +
103
target/riscv/cpu.h | 65 +-
104
target/riscv/cpu_bits.h | 157 ++-
105
target/riscv/cpu_cfg.h | 13 +
106
target/riscv/helper.h | 1 +
107
target/riscv/internals.h | 54 +
108
target/riscv/kvm/kvm_riscv.h | 4 +-
109
target/riscv/pmp.h | 1 +
110
target/riscv/insn32.decode | 3 +
111
hw/char/riscv_htif.c | 15 +-
112
hw/riscv/riscv-iommu.c | 205 +++-
113
hw/riscv/riscv_hart.c | 41 +
114
hw/riscv/virt.c | 2 +-
115
target/riscv/cpu.c | 97 +-
116
target/riscv/cpu_helper.c | 311 +++++-
117
target/riscv/csr.c | 1257 +++++++++++++++++-------
118
target/riscv/gdbstub.c | 23 +-
119
target/riscv/kvm/kvm-cpu.c | 4 +-
120
target/riscv/machine.c | 18 +-
121
target/riscv/op_helper.c | 126 ++-
122
target/riscv/pmp.c | 14 +-
123
target/riscv/tcg/tcg-cpu.c | 60 +-
124
target/riscv/translate.c | 49 +-
125
target/riscv/vector_helper.c | 31 +-
126
target/riscv/insn_trans/trans_privileged.c.inc | 20 +
127
hw/char/trace-events | 4 +
128
target/riscv/trace-events | 3 +
129
tests/data/acpi/riscv64/virt/RHCT | Bin 332 -> 390 bytes
130
28 files changed, 1862 insertions(+), 720 deletions(-)
131
diff view generated by jsdifflib
New patch
1
From: Craig Blackmore <craig.blackmore@embecosm.com>
1
2
3
Replace `continus` with `continuous`.
4
5
Signed-off-by: Craig Blackmore <craig.blackmore@embecosm.com>
6
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-ID: <20241218142353.1027938-2-craig.blackmore@embecosm.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/vector_helper.c | 10 +++++-----
13
1 file changed, 5 insertions(+), 5 deletions(-)
14
15
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/vector_helper.c
18
+++ b/target/riscv/vector_helper.c
19
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_ST_ELEM(ste_w, uint32_t, H4, stl)
20
GEN_VEXT_ST_ELEM(ste_d, uint64_t, H8, stq)
21
22
static inline QEMU_ALWAYS_INLINE void
23
-vext_continus_ldst_tlb(CPURISCVState *env, vext_ldst_elem_fn_tlb *ldst_tlb,
24
+vext_continuous_ldst_tlb(CPURISCVState *env, vext_ldst_elem_fn_tlb *ldst_tlb,
25
void *vd, uint32_t evl, target_ulong addr,
26
uint32_t reg_start, uintptr_t ra, uint32_t esz,
27
bool is_load)
28
@@ -XXX,XX +XXX,XX @@ vext_continus_ldst_tlb(CPURISCVState *env, vext_ldst_elem_fn_tlb *ldst_tlb,
29
}
30
31
static inline QEMU_ALWAYS_INLINE void
32
-vext_continus_ldst_host(CPURISCVState *env, vext_ldst_elem_fn_host *ldst_host,
33
+vext_continuous_ldst_host(CPURISCVState *env, vext_ldst_elem_fn_host *ldst_host,
34
void *vd, uint32_t evl, uint32_t reg_start, void *host,
35
uint32_t esz, bool is_load)
36
{
37
@@ -XXX,XX +XXX,XX @@ vext_page_ldst_us(CPURISCVState *env, void *vd, target_ulong addr,
38
39
if (flags == 0) {
40
if (nf == 1) {
41
- vext_continus_ldst_host(env, ldst_host, vd, evl, env->vstart, host,
42
- esz, is_load);
43
+ vext_continuous_ldst_host(env, ldst_host, vd, evl, env->vstart,
44
+ host, esz, is_load);
45
} else {
46
for (i = env->vstart; i < evl; ++i) {
47
k = 0;
48
@@ -XXX,XX +XXX,XX @@ vext_page_ldst_us(CPURISCVState *env, void *vd, target_ulong addr,
49
env->vstart += elems;
50
} else {
51
if (nf == 1) {
52
- vext_continus_ldst_tlb(env, ldst_tlb, vd, evl, addr, env->vstart,
53
+ vext_continuous_ldst_tlb(env, ldst_tlb, vd, evl, addr, env->vstart,
54
ra, esz, is_load);
55
} else {
56
/* load bytes from guest memory */
57
--
58
2.48.1
diff view generated by jsdifflib
New patch
1
From: Craig Blackmore <craig.blackmore@embecosm.com>
1
2
3
Calling `vext_continuous_ldst_tlb` for load/stores up to 6 bytes
4
significantly improves performance.
5
6
Co-authored-by: Helene CHELIN <helene.chelin@embecosm.com>
7
Co-authored-by: Paolo Savini <paolo.savini@embecosm.com>
8
Co-authored-by: Craig Blackmore <craig.blackmore@embecosm.com>
9
10
Signed-off-by: Helene CHELIN <helene.chelin@embecosm.com>
11
Signed-off-by: Paolo Savini <paolo.savini@embecosm.com>
12
Signed-off-by: Craig Blackmore <craig.blackmore@embecosm.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-ID: <20241218142353.1027938-3-craig.blackmore@embecosm.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/vector_helper.c | 16 ++++++++++++++++
19
1 file changed, 16 insertions(+)
20
21
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/vector_helper.c
24
+++ b/target/riscv/vector_helper.c
25
@@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
26
return;
27
}
28
29
+#if defined(CONFIG_USER_ONLY)
30
+ /*
31
+ * For data sizes <= 6 bytes we get better performance by simply calling
32
+ * vext_continuous_ldst_tlb
33
+ */
34
+ if (nf == 1 && (evl << log2_esz) <= 6) {
35
+ addr = base + (env->vstart << log2_esz);
36
+ vext_continuous_ldst_tlb(env, ldst_tlb, vd, evl, addr, env->vstart, ra,
37
+ esz, is_load);
38
+
39
+ env->vstart = 0;
40
+ vext_set_tail_elems_1s(evl, vd, desc, nf, esz, max_elems);
41
+ return;
42
+ }
43
+#endif
44
+
45
/* Calculate the page range of first page */
46
addr = base + ((env->vstart * nf) << log2_esz);
47
page_split = -(addr | TARGET_PAGE_MASK);
48
--
49
2.48.1
diff view generated by jsdifflib
New patch
1
From: Yanfeng Liu <yfliu2008@qq.com>
1
2
3
This adds virtualization mode (V bit) as bit(2) of register `priv`
4
per RiscV debug spec v1.0.0-rc4. Checked with gdb-multiarch v12.1.
5
6
Note that GDB may display `INVALID` tag for `priv` reg when V bit
7
is set, this doesn't affect actual access to the bit though.
8
9
Signed-off-by: Yanfeng Liu <yfliu2008@qq.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-ID: <tencent_1993B55C24DE7979BF34B200F78287002907@qq.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/gdbstub.c | 23 +++++++++++++++++++----
15
1 file changed, 19 insertions(+), 4 deletions(-)
16
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
20
+++ b/target/riscv/gdbstub.c
21
@@ -XXX,XX +XXX,XX @@ static int riscv_gdb_get_virtual(CPUState *cs, GByteArray *buf, int n)
22
RISCVCPU *cpu = RISCV_CPU(cs);
23
CPURISCVState *env = &cpu->env;
24
25
- return gdb_get_regl(buf, env->priv);
26
+ /* Per RiscV debug spec v1.0.0 rc4 */
27
+ target_ulong vbit = (env->virt_enabled) ? BIT(2) : 0;
28
+
29
+ return gdb_get_regl(buf, env->priv | vbit);
30
#endif
31
}
32
return 0;
33
@@ -XXX,XX +XXX,XX @@ static int riscv_gdb_set_virtual(CPUState *cs, uint8_t *mem_buf, int n)
34
RISCVCPU *cpu = RISCV_CPU(cs);
35
CPURISCVState *env = &cpu->env;
36
37
- env->priv = ldtul_p(mem_buf) & 0x3;
38
- if (env->priv == PRV_RESERVED) {
39
- env->priv = PRV_S;
40
+ target_ulong new_priv = ldtul_p(mem_buf) & 0x3;
41
+ bool new_virt = 0;
42
+
43
+ if (new_priv == PRV_RESERVED) {
44
+ new_priv = PRV_S;
45
+ }
46
+
47
+ if (new_priv != PRV_M) {
48
+ new_virt = (ldtul_p(mem_buf) & BIT(2)) >> 2;
49
}
50
+
51
+ if (riscv_has_ext(env, RVH) && new_virt != env->virt_enabled) {
52
+ riscv_cpu_swap_hypervisor_regs(env);
53
+ }
54
+
55
+ riscv_cpu_set_mode(env, new_priv, new_virt);
56
#endif
57
return sizeof(target_ulong);
58
}
59
--
60
2.48.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
shcounterenw is defined in RVA22 as:
4
5
"For any hpmcounter that is not read-only zero, the corresponding bit in
6
hcounteren must be writable."
7
8
This is always true in TCG so let's claim support for it.
9
10
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-ID: <20241218114026.1652352-4-dbarboza@ventanamicro.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/cpu.c | 1 +
16
tests/data/acpi/riscv64/virt/RHCT | Bin 332 -> 346 bytes
17
2 files changed, 1 insertion(+)
18
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
24
ISA_EXT_DATA_ENTRY(zvkt, PRIV_VERSION_1_12_0, ext_zvkt),
25
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
26
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
27
+ ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
28
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
29
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
30
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
31
diff --git a/tests/data/acpi/riscv64/virt/RHCT b/tests/data/acpi/riscv64/virt/RHCT
32
index XXXXXXX..XXXXXXX 100644
33
Binary files a/tests/data/acpi/riscv64/virt/RHCT and b/tests/data/acpi/riscv64/virt/RHCT differ
34
--
35
2.48.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
shvstvala is defined in RVA22 as:
4
5
"vstval must be written in all cases described above for stval."
6
7
By "cases describe above" the doc refer to the description of sstvala:
8
9
"stval must be written with the faulting virtual address for load,
10
store, and instruction page-fault, access-fault, and misaligned
11
exceptions, and for breakpoint exceptions other than those caused by
12
execution of the EBREAK or C.EBREAK instructions. For
13
virtual-instruction and illegal-instruction exceptions, stval must be
14
written with the faulting instruction."
15
16
We already have sstvala, and our vstval follows the same rules as stval,
17
so we can claim to support shvstvala too.
18
19
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-ID: <20241218114026.1652352-5-dbarboza@ventanamicro.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
target/riscv/cpu.c | 1 +
25
tests/data/acpi/riscv64/virt/RHCT | Bin 346 -> 356 bytes
26
2 files changed, 1 insertion(+)
27
28
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/cpu.c
31
+++ b/target/riscv/cpu.c
32
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
33
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
34
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
35
ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
36
+ ISA_EXT_DATA_ENTRY(shvstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
37
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
38
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
39
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
40
diff --git a/tests/data/acpi/riscv64/virt/RHCT b/tests/data/acpi/riscv64/virt/RHCT
41
index XXXXXXX..XXXXXXX 100644
42
Binary files a/tests/data/acpi/riscv64/virt/RHCT and b/tests/data/acpi/riscv64/virt/RHCT differ
43
--
44
2.48.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
shtvala is described in RVA22 as:
4
5
"htval must be written with the faulting guest physical address
6
in all circumstances permitted by the ISA."
7
8
This is the case since commit 3067553993, so claim support for shtvala.
9
10
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-ID: <20241218114026.1652352-6-dbarboza@ventanamicro.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/cpu.c | 1 +
16
tests/data/acpi/riscv64/virt/RHCT | Bin 356 -> 364 bytes
17
2 files changed, 1 insertion(+)
18
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
24
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
25
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
26
ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
27
+ ISA_EXT_DATA_ENTRY(shtvala, PRIV_VERSION_1_12_0, has_priv_1_12),
28
ISA_EXT_DATA_ENTRY(shvstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
29
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
30
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
31
diff --git a/tests/data/acpi/riscv64/virt/RHCT b/tests/data/acpi/riscv64/virt/RHCT
32
index XXXXXXX..XXXXXXX 100644
33
Binary files a/tests/data/acpi/riscv64/virt/RHCT and b/tests/data/acpi/riscv64/virt/RHCT differ
34
--
35
2.48.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
shvstvecd is defined in RVA22 as:
4
5
"vstvec.MODE must be capable of holding the value 0 (Direct).
6
When vstvec.MODE=Direct, vstvec.BASE must be capable of holding any
7
valid four-byte-aligned address."
8
9
This is always true for TCG so let's claim support for it.
10
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20241218114026.1652352-7-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/cpu.c | 1 +
17
tests/data/acpi/riscv64/virt/RHCT | Bin 364 -> 374 bytes
18
2 files changed, 1 insertion(+)
19
20
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.c
23
+++ b/target/riscv/cpu.c
24
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
25
ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
26
ISA_EXT_DATA_ENTRY(shtvala, PRIV_VERSION_1_12_0, has_priv_1_12),
27
ISA_EXT_DATA_ENTRY(shvstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
28
+ ISA_EXT_DATA_ENTRY(shvstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
29
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
30
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
31
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
32
diff --git a/tests/data/acpi/riscv64/virt/RHCT b/tests/data/acpi/riscv64/virt/RHCT
33
index XXXXXXX..XXXXXXX 100644
34
Binary files a/tests/data/acpi/riscv64/virt/RHCT and b/tests/data/acpi/riscv64/virt/RHCT differ
35
--
36
2.48.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
shvsatpa is defined in RVA22 as:
4
5
"All translation modes supported in satp must be supported in vsatp."
6
7
This is always true in TCG so let's claim support for it.
8
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-ID: <20241218114026.1652352-8-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.c | 1 +
15
tests/data/acpi/riscv64/virt/RHCT | Bin 374 -> 382 bytes
16
2 files changed, 1 insertion(+)
17
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
22
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
23
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
24
ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
25
ISA_EXT_DATA_ENTRY(shtvala, PRIV_VERSION_1_12_0, has_priv_1_12),
26
+ ISA_EXT_DATA_ENTRY(shvsatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
27
ISA_EXT_DATA_ENTRY(shvstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
28
ISA_EXT_DATA_ENTRY(shvstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
29
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
30
diff --git a/tests/data/acpi/riscv64/virt/RHCT b/tests/data/acpi/riscv64/virt/RHCT
31
index XXXXXXX..XXXXXXX 100644
32
Binary files a/tests/data/acpi/riscv64/virt/RHCT and b/tests/data/acpi/riscv64/virt/RHCT differ
33
--
34
2.48.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
shgatpa is defined in RVA22 as:
4
5
"For each supported virtual memory scheme SvNN supported in satp, the
6
corresponding hgatp SvNNx4 mode must be supported. The hgatp mode Bare
7
must also be supported."
8
9
Claim support for shgatpa since this is always true for TCG.
10
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20241218114026.1652352-9-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/cpu.c | 1 +
17
tests/data/acpi/riscv64/virt/RHCT | Bin 382 -> 390 bytes
18
2 files changed, 1 insertion(+)
19
20
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.c
23
+++ b/target/riscv/cpu.c
24
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
25
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
26
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
27
ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
28
+ ISA_EXT_DATA_ENTRY(shgatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
29
ISA_EXT_DATA_ENTRY(shtvala, PRIV_VERSION_1_12_0, has_priv_1_12),
30
ISA_EXT_DATA_ENTRY(shvsatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
31
ISA_EXT_DATA_ENTRY(shvstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
32
diff --git a/tests/data/acpi/riscv64/virt/RHCT b/tests/data/acpi/riscv64/virt/RHCT
33
index XXXXXXX..XXXXXXX 100644
34
Binary files a/tests/data/acpi/riscv64/virt/RHCT and b/tests/data/acpi/riscv64/virt/RHCT differ
35
--
36
2.48.1
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Per the SiFive manual, all E/U series CPU cores' reset vector is
3
'sha' is the augmented hypervisor extension, defined in RVA22 as a set of
4
at 0x1004. Update our codes to match the hardware.
4
the following extensions:
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
- RVH
7
- Ssstateen
8
- Shcounterenw (always present)
9
- Shvstvala (always present)
10
- Shtvala (always present)
11
- Shvstvecd (always present)
12
- Shvsatpa (always present)
13
- Shgatpa (always present)
14
15
We can claim support for 'sha' by checking if we have RVH and ssstateen.
16
17
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1592268641-7478-3-git-send-email-bmeng.cn@gmail.com
19
Message-ID: <20241218114026.1652352-10-dbarboza@ventanamicro.com>
9
Message-Id: <1592268641-7478-3-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
21
---
12
hw/riscv/sifive_e.c | 10 ++++++----
22
target/riscv/cpu_cfg.h | 1 +
13
hw/riscv/sifive_u.c | 6 +++---
23
target/riscv/cpu.c | 2 ++
14
target/riscv/cpu.c | 16 ++++++++--------
24
target/riscv/tcg/tcg-cpu.c | 8 ++++++++
15
3 files changed, 17 insertions(+), 15 deletions(-)
25
3 files changed, 11 insertions(+)
16
26
17
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
27
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
18
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/sifive_e.c
29
--- a/target/riscv/cpu_cfg.h
20
+++ b/hw/riscv/sifive_e.c
30
+++ b/target/riscv/cpu_cfg.h
21
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
31
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
22
memmap[SIFIVE_E_DTIM].base, main_mem);
32
bool ext_svade;
23
33
bool ext_zic64b;
24
/* Mask ROM reset vector */
34
bool ext_ssstateen;
25
- uint32_t reset_vec[2];
35
+ bool ext_sha;
26
+ uint32_t reset_vec[4];
36
27
37
/*
28
if (s->revb) {
38
* Always 'true' booleans for named features
29
- reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
30
+ reset_vec[1] = 0x200102b7; /* 0x1004: lui t0,0x20010 */
31
} else {
32
- reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
33
+ reset_vec[1] = 0x204002b7; /* 0x1004: lui t0,0x20400 */
34
}
35
- reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
36
+ reset_vec[2] = 0x00028067; /* 0x1008: jr t0 */
37
+
38
+ reset_vec[0] = reset_vec[3] = 0;
39
40
/* copy in the reset vector in little_endian byte order */
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
42
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/riscv/sifive_u.c
45
+++ b/hw/riscv/sifive_u.c
46
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
47
48
/* reset vector */
49
uint32_t reset_vec[8] = {
50
+ 0x00000000,
51
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
52
- 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
53
+ 0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
54
0xf1402573, /* csrr a0, mhartid */
55
#if defined(TARGET_RISCV32)
56
0x0182a283, /* lw t0, 24(t0) */
57
#elif defined(TARGET_RISCV64)
58
- 0x0182b283, /* ld t0, 24(t0) */
59
+ 0x0182e283, /* lwu t0, 24(t0) */
60
#endif
61
0x00028067, /* jr t0 */
62
0x00000000,
63
start_addr, /* start: .dword */
64
- 0x00000000,
65
/* dtb: */
66
};
67
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
69
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/cpu.c
41
--- a/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
72
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
43
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
73
set_resetvec(env, DEFAULT_RSTVEC);
44
ISA_EXT_DATA_ENTRY(zhinx, PRIV_VERSION_1_12_0, ext_zhinx),
45
ISA_EXT_DATA_ENTRY(zhinxmin, PRIV_VERSION_1_12_0, ext_zhinxmin),
46
ISA_EXT_DATA_ENTRY(shcounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
47
+ ISA_EXT_DATA_ENTRY(sha, PRIV_VERSION_1_12_0, ext_sha),
48
ISA_EXT_DATA_ENTRY(shgatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
49
ISA_EXT_DATA_ENTRY(shtvala, PRIV_VERSION_1_12_0, has_priv_1_12),
50
ISA_EXT_DATA_ENTRY(shvsatpa, PRIV_VERSION_1_12_0, has_priv_1_12),
51
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
52
const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
53
MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
54
MULTI_EXT_CFG_BOOL("ssstateen", ext_ssstateen, true),
55
+ MULTI_EXT_CFG_BOOL("sha", ext_sha, true),
56
57
{ },
58
};
59
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/riscv/tcg/tcg-cpu.c
62
+++ b/target/riscv/tcg/tcg-cpu.c
63
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset)
64
cpu->cfg.cbop_blocksize = 64;
65
cpu->cfg.cboz_blocksize = 64;
66
break;
67
+ case CPU_CFG_OFFSET(ext_sha):
68
+ if (!cpu_misa_ext_is_user_set(RVH)) {
69
+ riscv_cpu_write_misa_bit(cpu, RVH, true);
70
+ }
71
+ /* fallthrough */
72
case CPU_CFG_OFFSET(ext_ssstateen):
73
cpu->cfg.ext_smstateen = true;
74
break;
75
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
76
cpu->cfg.cboz_blocksize == 64;
77
78
cpu->cfg.ext_ssstateen = cpu->cfg.ext_smstateen;
79
+
80
+ cpu->cfg.ext_sha = riscv_has_ext(&cpu->env, RVH) &&
81
+ cpu->cfg.ext_ssstateen;
74
}
82
}
75
83
76
-static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
84
static void riscv_cpu_validate_g(RISCVCPU *cpu)
77
+static void rvxx_sifive_u_cpu_init(Object *obj)
78
{
79
CPURISCVState *env = &RISCV_CPU(obj)->env;
80
set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
81
set_priv_version(env, PRIV_VERSION_1_10_0);
82
- set_resetvec(env, DEFAULT_RSTVEC);
83
+ set_resetvec(env, 0x1004);
84
}
85
86
-static void rvxx_imacu_nommu_cpu_init(Object *obj)
87
+static void rvxx_sifive_e_cpu_init(Object *obj)
88
{
89
CPURISCVState *env = &RISCV_CPU(obj)->env;
90
set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
91
set_priv_version(env, PRIV_VERSION_1_10_0);
92
- set_resetvec(env, DEFAULT_RSTVEC);
93
+ set_resetvec(env, 0x1004);
94
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
95
}
96
97
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
98
#if defined(TARGET_RISCV32)
99
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
100
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
101
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
102
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_sifive_e_cpu_init),
103
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
104
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
105
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_sifive_u_cpu_init),
106
#elif defined(TARGET_RISCV64)
107
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
108
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
109
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
110
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_sifive_e_cpu_init),
111
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_sifive_u_cpu_init),
112
#endif
113
};
114
115
--
85
--
116
2.27.0
86
2.48.1
117
118
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
Do a cosmetic change in riscv_raise_exception() to change 'exception'
4
type from uint32_t to RISCVException, making it a bit clear that the
5
arg is directly correlated to the RISCVException enum.
6
7
As a side effect, change 'excp' type from int to RISCVException in
8
generate_exception() to guarantee that all callers of
9
riscv_raise_exception() will use the enum.
10
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-ID: <20250106173734.412353-2-dbarboza@ventanamicro.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
16
---
5
include/hw/riscv/opentitan.h | 13 +++++++++++++
17
target/riscv/cpu.h | 3 ++-
6
hw/riscv/opentitan.c | 25 +++++++++++++++++++++++--
18
target/riscv/op_helper.c | 3 ++-
7
2 files changed, 36 insertions(+), 2 deletions(-)
19
target/riscv/translate.c | 2 +-
20
3 files changed, 5 insertions(+), 3 deletions(-)
8
21
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
10
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
24
--- a/target/riscv/cpu.h
12
+++ b/include/hw/riscv/opentitan.h
25
+++ b/target/riscv/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void riscv_translate_code(CPUState *cs, TranslationBlock *tb,
27
int *max_insns, vaddr pc, void *host_pc);
28
29
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
30
- uint32_t exception, uintptr_t pc);
31
+ RISCVException exception,
32
+ uintptr_t pc);
33
34
target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
35
void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
36
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/op_helper.c
39
+++ b/target/riscv/op_helper.c
13
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@
14
41
15
#include "hw/riscv/riscv_hart.h"
42
/* Exceptions processing helpers */
16
#include "hw/intc/ibex_plic.h"
43
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
17
+#include "hw/char/ibex_uart.h"
44
- uint32_t exception, uintptr_t pc)
18
45
+ RISCVException exception,
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
46
+ uintptr_t pc)
20
#define RISCV_IBEX_SOC(obj) \
47
{
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
48
CPUState *cs = env_cpu(env);
22
/*< public >*/
49
cs->exception_index = exception;
23
RISCVHartArrayState cpus;
50
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
24
IbexPlicState plic;
25
+ IbexUartState uart;
26
27
MemoryRegion flash_mem;
28
MemoryRegion rom;
29
@@ -XXX,XX +XXX,XX @@ enum {
30
IBEX_PADCTRL,
31
};
32
33
+enum {
34
+ IBEX_UART_RX_PARITY_ERR_IRQ = 0x28,
35
+ IBEX_UART_RX_TIMEOUT_IRQ = 0x27,
36
+ IBEX_UART_RX_BREAK_ERR_IRQ = 0x26,
37
+ IBEX_UART_RX_FRAME_ERR_IRQ = 0x25,
38
+ IBEX_UART_RX_OVERFLOW_IRQ = 0x24,
39
+ IBEX_UART_TX_EMPTY_IRQ = 0x23,
40
+ IBEX_UART_RX_WATERMARK_IRQ = 0x22,
41
+ IBEX_UART_TX_WATERMARK_IRQ = 0x21,
42
+};
43
+
44
#endif
45
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
46
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/riscv/opentitan.c
52
--- a/target/riscv/translate.c
48
+++ b/hw/riscv/opentitan.c
53
+++ b/target/riscv/translate.c
49
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
54
@@ -XXX,XX +XXX,XX @@ static void gen_update_pc(DisasContext *ctx, target_long diff)
50
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
55
ctx->pc_save = ctx->base.pc_next + diff;
51
52
object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
53
+
54
+ object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
55
}
56
}
56
57
57
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
58
-static void generate_exception(DisasContext *ctx, int excp)
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
59
+static void generate_exception(DisasContext *ctx, RISCVException excp)
59
}
60
{
60
sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
61
gen_update_pc(ctx, 0);
61
62
gen_helper_raise_exception(tcg_env, tcg_constant_i32(excp));
62
- create_unimplemented_device("riscv.lowrisc.ibex.uart",
63
- memmap[IBEX_UART].base, memmap[IBEX_UART].size);
64
+ /* UART */
65
+ qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
66
+ sysbus_realize(SYS_BUS_DEVICE(&s->uart), &err);
67
+ if (err != NULL) {
68
+ error_propagate(errp, err);
69
+ return;
70
+ }
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart), 0, memmap[IBEX_UART].base);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
73
+ 0, qdev_get_gpio_in(DEVICE(&s->plic),
74
+ IBEX_UART_TX_WATERMARK_IRQ));
75
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
76
+ 1, qdev_get_gpio_in(DEVICE(&s->plic),
77
+ IBEX_UART_RX_WATERMARK_IRQ));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
79
+ 2, qdev_get_gpio_in(DEVICE(&s->plic),
80
+ IBEX_UART_TX_EMPTY_IRQ));
81
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
82
+ 3, qdev_get_gpio_in(DEVICE(&s->plic),
83
+ IBEX_UART_RX_OVERFLOW_IRQ));
84
+
85
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
86
memmap[IBEX_GPIO].base, memmap[IBEX_GPIO].size);
87
create_unimplemented_device("riscv.lowrisc.ibex.spi",
88
--
63
--
89
2.27.0
64
2.48.1
90
65
91
66
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
When using system mode we can get the CPU traps being taken via the
4
'riscv_trap' trace or the "-d int" qemu log. User mode does not a way of
5
logging/showing exceptions to users.
6
7
Add a trace in riscv_raise_exception() to allow qemu-riscv(32/64) users
8
to check all exceptions being thrown. This is particularly useful to
9
help identifying insns that are throwing SIGILLs.
10
11
As it is today we need to debug their binaries to identify where the
12
illegal insns are:
13
14
$ ~/work/qemu/build/qemu-riscv64 -cpu rv64 ./foo.out
15
Illegal instruction (core dumped)
16
17
After this change users can capture the trace and use EPC to pinpoint
18
the insn:
19
20
$ ~/work/qemu/build/qemu-riscv64 -cpu rv64 -trace riscv_exception ./foo.out
21
riscv_exception 8 (user_ecall) on epc 0x17cd2
22
riscv_exception 8 (user_ecall) on epc 0x17cda
23
riscv_exception 8 (user_ecall) on epc 0x17622
24
(...)
25
riscv_exception 2 (illegal_instruction) on epc 0x1053a
26
Illegal instruction (core dumped)
27
28
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
29
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
30
Message-ID: <20250106173734.412353-3-dbarboza@ventanamicro.com>
31
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
32
---
33
target/riscv/op_helper.c | 6 ++++++
34
target/riscv/trace-events | 3 +++
35
2 files changed, 9 insertions(+)
36
37
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/op_helper.c
40
+++ b/target/riscv/op_helper.c
41
@@ -XXX,XX +XXX,XX @@
42
#include "exec/exec-all.h"
43
#include "exec/cpu_ldst.h"
44
#include "exec/helper-proto.h"
45
+#include "trace.h"
46
47
/* Exceptions processing helpers */
48
G_NORETURN void riscv_raise_exception(CPURISCVState *env,
49
@@ -XXX,XX +XXX,XX @@ G_NORETURN void riscv_raise_exception(CPURISCVState *env,
50
uintptr_t pc)
51
{
52
CPUState *cs = env_cpu(env);
53
+
54
+ trace_riscv_exception(exception,
55
+ riscv_cpu_get_trap_name(exception, false),
56
+ env->pc);
57
+
58
cs->exception_index = exception;
59
cpu_loop_exit_restore(cs, pc);
60
}
61
diff --git a/target/riscv/trace-events b/target/riscv/trace-events
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/riscv/trace-events
64
+++ b/target/riscv/trace-events
65
@@ -XXX,XX +XXX,XX @@ pmpaddr_csr_write(uint64_t mhartid, uint32_t addr_index, uint64_t val) "hart %"
66
67
mseccfg_csr_read(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": read mseccfg, val: 0x%" PRIx64
68
mseccfg_csr_write(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": write mseccfg, val: 0x%" PRIx64
69
+
70
+# op_helper.c
71
+riscv_exception(uint32_t exception, const char *desc, uint64_t epc) "%u (%s) on epc 0x%"PRIx64""
72
--
73
2.48.1
diff view generated by jsdifflib
New patch
1
From: Alexey Baturo <baturo.alexey@gmail.com>
1
2
3
Zjpm extension is finally ratified. And it's much simplier compared to the experimental one.
4
The newer version doesn't allow to specify custom mask or base for pointer masking.
5
Instead it allows only certain options for masking top bits.
6
7
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20250106102346.1100149-2-baturo.alexey@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.h | 33 +---
13
target/riscv/cpu_bits.h | 87 ----------
14
target/riscv/cpu.c | 13 +-
15
target/riscv/cpu_helper.c | 52 ------
16
target/riscv/csr.c | 326 -----------------------------------
17
target/riscv/machine.c | 17 +-
18
target/riscv/tcg/tcg-cpu.c | 5 +-
19
target/riscv/translate.c | 28 +--
20
target/riscv/vector_helper.c | 2 +-
21
9 files changed, 19 insertions(+), 544 deletions(-)
22
23
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/cpu.h
26
+++ b/target/riscv/cpu.h
27
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState CPURISCVState;
28
#define RVS RV('S')
29
#define RVU RV('U')
30
#define RVH RV('H')
31
-#define RVJ RV('J')
32
#define RVG RV('G')
33
#define RVB RV('B')
34
35
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
36
/* True if in debugger mode. */
37
bool debugger;
38
39
- /*
40
- * CSRs for PointerMasking extension
41
- */
42
- target_ulong mmte;
43
- target_ulong mpmmask;
44
- target_ulong mpmbase;
45
- target_ulong spmmask;
46
- target_ulong spmbase;
47
- target_ulong upmmask;
48
- target_ulong upmbase;
49
-
50
uint64_t mstateen[SMSTATEEN_MAX_COUNT];
51
uint64_t hstateen[SMSTATEEN_MAX_COUNT];
52
uint64_t sstateen[SMSTATEEN_MAX_COUNT];
53
uint64_t henvcfg;
54
#endif
55
- target_ulong cur_pmmask;
56
- target_ulong cur_pmbase;
57
58
/* Fields from here on are preserved across CPU reset. */
59
QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
60
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, XL, 16, 2)
61
/* If PointerMasking should be applied */
62
FIELD(TB_FLAGS, PM_MASK_ENABLED, 18, 1)
63
FIELD(TB_FLAGS, PM_BASE_ENABLED, 19, 1)
64
-FIELD(TB_FLAGS, VTA, 20, 1)
65
-FIELD(TB_FLAGS, VMA, 21, 1)
66
+FIELD(TB_FLAGS, VTA, 18, 1)
67
+FIELD(TB_FLAGS, VMA, 19, 1)
68
/* Native debug itrigger */
69
-FIELD(TB_FLAGS, ITRIGGER, 22, 1)
70
+FIELD(TB_FLAGS, ITRIGGER, 20, 1)
71
/* Virtual mode enabled */
72
-FIELD(TB_FLAGS, VIRT_ENABLED, 23, 1)
73
-FIELD(TB_FLAGS, PRIV, 24, 2)
74
-FIELD(TB_FLAGS, AXL, 26, 2)
75
+FIELD(TB_FLAGS, VIRT_ENABLED, 21, 1)
76
+FIELD(TB_FLAGS, PRIV, 22, 2)
77
+FIELD(TB_FLAGS, AXL, 24, 2)
78
/* zicfilp needs a TB flag to track indirect branches */
79
-FIELD(TB_FLAGS, FCFI_ENABLED, 28, 1)
80
-FIELD(TB_FLAGS, FCFI_LP_EXPECTED, 29, 1)
81
+FIELD(TB_FLAGS, FCFI_ENABLED, 26, 1)
82
+FIELD(TB_FLAGS, FCFI_LP_EXPECTED, 27, 1)
83
/* zicfiss needs a TB flag so that correct TB is located based on tb flags */
84
-FIELD(TB_FLAGS, BCFI_ENABLED, 30, 1)
85
+FIELD(TB_FLAGS, BCFI_ENABLED, 28, 1)
86
87
#ifdef TARGET_RISCV32
88
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
89
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_get_vlmax(uint32_t vlenb, uint32_t vsew,
90
void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
91
uint64_t *cs_base, uint32_t *pflags);
92
93
-void riscv_cpu_update_mask(CPURISCVState *env);
94
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
95
96
RISCVException riscv_csrr(CPURISCVState *env, int csrno,
97
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/riscv/cpu_bits.h
100
+++ b/target/riscv/cpu_bits.h
101
@@ -XXX,XX +XXX,XX @@
102
#define CSR_MHPMCOUNTER30H 0xb9e
103
#define CSR_MHPMCOUNTER31H 0xb9f
104
105
-/*
106
- * User PointerMasking registers
107
- * NB: actual CSR numbers might be changed in future
108
- */
109
-#define CSR_UMTE 0x4c0
110
-#define CSR_UPMMASK 0x4c1
111
-#define CSR_UPMBASE 0x4c2
112
-
113
-/*
114
- * Machine PointerMasking registers
115
- * NB: actual CSR numbers might be changed in future
116
- */
117
-#define CSR_MMTE 0x3c0
118
-#define CSR_MPMMASK 0x3c1
119
-#define CSR_MPMBASE 0x3c2
120
-
121
-/*
122
- * Supervisor PointerMaster registers
123
- * NB: actual CSR numbers might be changed in future
124
- */
125
-#define CSR_SMTE 0x1c0
126
-#define CSR_SPMMASK 0x1c1
127
-#define CSR_SPMBASE 0x1c2
128
-
129
-/*
130
- * Hypervisor PointerMaster registers
131
- * NB: actual CSR numbers might be changed in future
132
- */
133
-#define CSR_VSMTE 0x2c0
134
-#define CSR_VSPMMASK 0x2c1
135
-#define CSR_VSPMBASE 0x2c2
136
#define CSR_SCOUNTOVF 0xda0
137
138
/* Crypto Extension */
139
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
140
#define VS_MODE_INTERRUPTS ((uint64_t)(MIP_VSSIP | MIP_VSTIP | MIP_VSEIP))
141
#define HS_MODE_INTERRUPTS ((uint64_t)(MIP_SGEIP | VS_MODE_INTERRUPTS))
142
143
-/* General PointerMasking CSR bits */
144
-#define PM_ENABLE 0x00000001ULL
145
-#define PM_CURRENT 0x00000002ULL
146
-#define PM_INSN 0x00000004ULL
147
-
148
/* Execution environment configuration bits */
149
#define MENVCFG_FIOM BIT(0)
150
#define MENVCFG_LPE BIT(2) /* zicfilp */
151
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
152
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
153
#define HENVCFGH_STCE MENVCFGH_STCE
154
155
-/* Offsets for every pair of control bits per each priv level */
156
-#define XS_OFFSET 0ULL
157
-#define U_OFFSET 2ULL
158
-#define S_OFFSET 5ULL
159
-#define M_OFFSET 8ULL
160
-
161
-#define PM_XS_BITS (EXT_STATUS_MASK << XS_OFFSET)
162
-#define U_PM_ENABLE (PM_ENABLE << U_OFFSET)
163
-#define U_PM_CURRENT (PM_CURRENT << U_OFFSET)
164
-#define U_PM_INSN (PM_INSN << U_OFFSET)
165
-#define S_PM_ENABLE (PM_ENABLE << S_OFFSET)
166
-#define S_PM_CURRENT (PM_CURRENT << S_OFFSET)
167
-#define S_PM_INSN (PM_INSN << S_OFFSET)
168
-#define M_PM_ENABLE (PM_ENABLE << M_OFFSET)
169
-#define M_PM_CURRENT (PM_CURRENT << M_OFFSET)
170
-#define M_PM_INSN (PM_INSN << M_OFFSET)
171
-
172
-/* mmte CSR bits */
173
-#define MMTE_PM_XS_BITS PM_XS_BITS
174
-#define MMTE_U_PM_ENABLE U_PM_ENABLE
175
-#define MMTE_U_PM_CURRENT U_PM_CURRENT
176
-#define MMTE_U_PM_INSN U_PM_INSN
177
-#define MMTE_S_PM_ENABLE S_PM_ENABLE
178
-#define MMTE_S_PM_CURRENT S_PM_CURRENT
179
-#define MMTE_S_PM_INSN S_PM_INSN
180
-#define MMTE_M_PM_ENABLE M_PM_ENABLE
181
-#define MMTE_M_PM_CURRENT M_PM_CURRENT
182
-#define MMTE_M_PM_INSN M_PM_INSN
183
-#define MMTE_MASK (MMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | MMTE_U_PM_INSN | \
184
- MMTE_S_PM_ENABLE | MMTE_S_PM_CURRENT | MMTE_S_PM_INSN | \
185
- MMTE_M_PM_ENABLE | MMTE_M_PM_CURRENT | MMTE_M_PM_INSN | \
186
- MMTE_PM_XS_BITS)
187
-
188
-/* (v)smte CSR bits */
189
-#define SMTE_PM_XS_BITS PM_XS_BITS
190
-#define SMTE_U_PM_ENABLE U_PM_ENABLE
191
-#define SMTE_U_PM_CURRENT U_PM_CURRENT
192
-#define SMTE_U_PM_INSN U_PM_INSN
193
-#define SMTE_S_PM_ENABLE S_PM_ENABLE
194
-#define SMTE_S_PM_CURRENT S_PM_CURRENT
195
-#define SMTE_S_PM_INSN S_PM_INSN
196
-#define SMTE_MASK (SMTE_U_PM_ENABLE | SMTE_U_PM_CURRENT | SMTE_U_PM_INSN | \
197
- SMTE_S_PM_ENABLE | SMTE_S_PM_CURRENT | SMTE_S_PM_INSN | \
198
- SMTE_PM_XS_BITS)
199
-
200
-/* umte CSR bits */
201
-#define UMTE_U_PM_ENABLE U_PM_ENABLE
202
-#define UMTE_U_PM_CURRENT U_PM_CURRENT
203
-#define UMTE_U_PM_INSN U_PM_INSN
204
-#define UMTE_MASK (UMTE_U_PM_ENABLE | MMTE_U_PM_CURRENT | UMTE_U_PM_INSN)
205
-
206
/* MISELECT, SISELECT, and VSISELECT bits (AIA) */
207
#define ISELECT_IPRIO0 0x30
208
#define ISELECT_IPRIO15 0x3f
209
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
210
index XXXXXXX..XXXXXXX 100644
211
--- a/target/riscv/cpu.c
212
+++ b/target/riscv/cpu.c
213
@@ -XXX,XX +XXX,XX @@
214
/* RISC-V CPU definitions */
215
static const char riscv_single_letter_exts[] = "IEMAFDQCBPVH";
216
const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV,
217
- RVC, RVS, RVU, RVH, RVJ, RVG, RVB, 0};
218
+ RVC, RVS, RVU, RVH, RVG, RVB, 0};
219
220
/*
221
* From vector_helper.c
222
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
223
CSR_MSCRATCH,
224
CSR_SSCRATCH,
225
CSR_SATP,
226
- CSR_MMTE,
227
- CSR_UPMBASE,
228
- CSR_UPMMASK,
229
- CSR_SPMBASE,
230
- CSR_SPMMASK,
231
- CSR_MPMBASE,
232
- CSR_MPMMASK,
233
};
234
235
for (i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
236
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
237
}
238
i++;
239
}
240
- /* mmte is supposed to have pm.current hardwired to 1 */
241
- env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT);
242
243
/*
244
* Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor
245
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
246
env->ssp = 0;
247
248
env->xl = riscv_cpu_mxl(env);
249
- riscv_cpu_update_mask(env);
250
cs->exception_index = RISCV_EXCP_NONE;
251
env->load_res = -1;
252
set_default_nan_mode(1, &env->fp_status);
253
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
254
MISA_EXT_INFO(RVS, "s", "Supervisor-level instructions"),
255
MISA_EXT_INFO(RVU, "u", "User-level instructions"),
256
MISA_EXT_INFO(RVH, "h", "Hypervisor"),
257
- MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
258
MISA_EXT_INFO(RVV, "v", "Vector operations"),
259
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
260
MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
261
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
262
index XXXXXXX..XXXXXXX 100644
263
--- a/target/riscv/cpu_helper.c
264
+++ b/target/riscv/cpu_helper.c
265
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
266
flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
267
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
268
flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env));
269
- if (env->cur_pmmask != 0) {
270
- flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
271
- }
272
- if (env->cur_pmbase != 0) {
273
- flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
274
- }
275
276
*pflags = flags;
277
}
278
279
-void riscv_cpu_update_mask(CPURISCVState *env)
280
-{
281
- target_ulong mask = 0, base = 0;
282
- RISCVMXL xl = env->xl;
283
- /*
284
- * TODO: Current RVJ spec does not specify
285
- * how the extension interacts with XLEN.
286
- */
287
-#ifndef CONFIG_USER_ONLY
288
- int mode = cpu_address_mode(env);
289
- xl = cpu_get_xl(env, mode);
290
- if (riscv_has_ext(env, RVJ)) {
291
- switch (mode) {
292
- case PRV_M:
293
- if (env->mmte & M_PM_ENABLE) {
294
- mask = env->mpmmask;
295
- base = env->mpmbase;
296
- }
297
- break;
298
- case PRV_S:
299
- if (env->mmte & S_PM_ENABLE) {
300
- mask = env->spmmask;
301
- base = env->spmbase;
302
- }
303
- break;
304
- case PRV_U:
305
- if (env->mmte & U_PM_ENABLE) {
306
- mask = env->upmmask;
307
- base = env->upmbase;
308
- }
309
- break;
310
- default:
311
- g_assert_not_reached();
312
- }
313
- }
314
-#endif
315
- if (xl == MXL_RV32) {
316
- env->cur_pmmask = mask & UINT32_MAX;
317
- env->cur_pmbase = base & UINT32_MAX;
318
- } else {
319
- env->cur_pmmask = mask;
320
- env->cur_pmbase = base;
321
- }
322
-}
323
-
324
#ifndef CONFIG_USER_ONLY
325
326
/*
327
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv, bool virt_en)
328
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
329
env->priv = newpriv;
330
env->xl = cpu_recompute_xl(env);
331
- riscv_cpu_update_mask(env);
332
333
/*
334
* Clear the load reservation - otherwise a reservation placed in one
335
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
336
index XXXXXXX..XXXXXXX 100644
337
--- a/target/riscv/csr.c
338
+++ b/target/riscv/csr.c
339
@@ -XXX,XX +XXX,XX @@ static RISCVException hgatp(CPURISCVState *env, int csrno)
340
return hmode(env, csrno);
341
}
342
343
-/* Checks if PointerMasking registers could be accessed */
344
-static RISCVException pointer_masking(CPURISCVState *env, int csrno)
345
-{
346
- /* Check if j-ext is present */
347
- if (riscv_has_ext(env, RVJ)) {
348
- return RISCV_EXCP_NONE;
349
- }
350
- return RISCV_EXCP_ILLEGAL_INST;
351
-}
352
-
353
static RISCVException aia_hmode(CPURISCVState *env, int csrno)
354
{
355
if (!riscv_cpu_cfg(env)->ext_ssaia) {
356
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
357
env->xl = cpu_recompute_xl(env);
358
}
359
360
- riscv_cpu_update_mask(env);
361
return RISCV_EXCP_NONE;
362
}
363
364
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcontext(CPURISCVState *env, int csrno,
365
return RISCV_EXCP_NONE;
366
}
367
368
-/*
369
- * Functions to access Pointer Masking feature registers
370
- * We have to check if current priv lvl could modify
371
- * csr in given mode
372
- */
373
-static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
374
-{
375
- int csr_priv = get_field(csrno, 0x300);
376
- int pm_current;
377
-
378
- if (env->debugger) {
379
- return false;
380
- }
381
- /*
382
- * If priv lvls differ that means we're accessing csr from higher priv lvl,
383
- * so allow the access
384
- */
385
- if (env->priv != csr_priv) {
386
- return false;
387
- }
388
- switch (env->priv) {
389
- case PRV_M:
390
- pm_current = get_field(env->mmte, M_PM_CURRENT);
391
- break;
392
- case PRV_S:
393
- pm_current = get_field(env->mmte, S_PM_CURRENT);
394
- break;
395
- case PRV_U:
396
- pm_current = get_field(env->mmte, U_PM_CURRENT);
397
- break;
398
- default:
399
- g_assert_not_reached();
400
- }
401
- /* It's same priv lvl, so we allow to modify csr only if pm.current==1 */
402
- return !pm_current;
403
-}
404
-
405
-static RISCVException read_mmte(CPURISCVState *env, int csrno,
406
- target_ulong *val)
407
-{
408
- *val = env->mmte & MMTE_MASK;
409
- return RISCV_EXCP_NONE;
410
-}
411
-
412
-static RISCVException write_mmte(CPURISCVState *env, int csrno,
413
- target_ulong val)
414
-{
415
- uint64_t mstatus;
416
- target_ulong wpri_val = val & MMTE_MASK;
417
-
418
- if (val != wpri_val) {
419
- qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
420
- TARGET_FMT_lx "\n", "MMTE: WPRI violation written 0x",
421
- val, "vs expected 0x", wpri_val);
422
- }
423
- /* for machine mode pm.current is hardwired to 1 */
424
- wpri_val |= MMTE_M_PM_CURRENT;
425
-
426
- /* hardwiring pm.instruction bit to 0, since it's not supported yet */
427
- wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
428
- env->mmte = wpri_val | EXT_STATUS_DIRTY;
429
- riscv_cpu_update_mask(env);
430
-
431
- /* Set XS and SD bits, since PM CSRs are dirty */
432
- mstatus = env->mstatus | MSTATUS_XS;
433
- write_mstatus(env, csrno, mstatus);
434
- return RISCV_EXCP_NONE;
435
-}
436
-
437
-static RISCVException read_smte(CPURISCVState *env, int csrno,
438
- target_ulong *val)
439
-{
440
- *val = env->mmte & SMTE_MASK;
441
- return RISCV_EXCP_NONE;
442
-}
443
-
444
-static RISCVException write_smte(CPURISCVState *env, int csrno,
445
- target_ulong val)
446
-{
447
- target_ulong wpri_val = val & SMTE_MASK;
448
-
449
- if (val != wpri_val) {
450
- qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
451
- TARGET_FMT_lx "\n", "SMTE: WPRI violation written 0x",
452
- val, "vs expected 0x", wpri_val);
453
- }
454
-
455
- /* if pm.current==0 we can't modify current PM CSRs */
456
- if (check_pm_current_disabled(env, csrno)) {
457
- return RISCV_EXCP_NONE;
458
- }
459
-
460
- wpri_val |= (env->mmte & ~SMTE_MASK);
461
- write_mmte(env, csrno, wpri_val);
462
- return RISCV_EXCP_NONE;
463
-}
464
-
465
-static RISCVException read_umte(CPURISCVState *env, int csrno,
466
- target_ulong *val)
467
-{
468
- *val = env->mmte & UMTE_MASK;
469
- return RISCV_EXCP_NONE;
470
-}
471
-
472
-static RISCVException write_umte(CPURISCVState *env, int csrno,
473
- target_ulong val)
474
-{
475
- target_ulong wpri_val = val & UMTE_MASK;
476
-
477
- if (val != wpri_val) {
478
- qemu_log_mask(LOG_GUEST_ERROR, "%s" TARGET_FMT_lx " %s"
479
- TARGET_FMT_lx "\n", "UMTE: WPRI violation written 0x",
480
- val, "vs expected 0x", wpri_val);
481
- }
482
-
483
- if (check_pm_current_disabled(env, csrno)) {
484
- return RISCV_EXCP_NONE;
485
- }
486
-
487
- wpri_val |= (env->mmte & ~UMTE_MASK);
488
- write_mmte(env, csrno, wpri_val);
489
- return RISCV_EXCP_NONE;
490
-}
491
-
492
-static RISCVException read_mpmmask(CPURISCVState *env, int csrno,
493
- target_ulong *val)
494
-{
495
- *val = env->mpmmask;
496
- return RISCV_EXCP_NONE;
497
-}
498
-
499
-static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
500
- target_ulong val)
501
-{
502
- uint64_t mstatus;
503
-
504
- env->mpmmask = val;
505
- if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
506
- env->cur_pmmask = val;
507
- }
508
- env->mmte |= EXT_STATUS_DIRTY;
509
-
510
- /* Set XS and SD bits, since PM CSRs are dirty */
511
- mstatus = env->mstatus | MSTATUS_XS;
512
- write_mstatus(env, csrno, mstatus);
513
- return RISCV_EXCP_NONE;
514
-}
515
-
516
-static RISCVException read_spmmask(CPURISCVState *env, int csrno,
517
- target_ulong *val)
518
-{
519
- *val = env->spmmask;
520
- return RISCV_EXCP_NONE;
521
-}
522
-
523
-static RISCVException write_spmmask(CPURISCVState *env, int csrno,
524
- target_ulong val)
525
-{
526
- uint64_t mstatus;
527
-
528
- /* if pm.current==0 we can't modify current PM CSRs */
529
- if (check_pm_current_disabled(env, csrno)) {
530
- return RISCV_EXCP_NONE;
531
- }
532
- env->spmmask = val;
533
- if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
534
- env->cur_pmmask = val;
535
- if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
536
- env->cur_pmmask &= UINT32_MAX;
537
- }
538
- }
539
- env->mmte |= EXT_STATUS_DIRTY;
540
-
541
- /* Set XS and SD bits, since PM CSRs are dirty */
542
- mstatus = env->mstatus | MSTATUS_XS;
543
- write_mstatus(env, csrno, mstatus);
544
- return RISCV_EXCP_NONE;
545
-}
546
-
547
-static RISCVException read_upmmask(CPURISCVState *env, int csrno,
548
- target_ulong *val)
549
-{
550
- *val = env->upmmask;
551
- return RISCV_EXCP_NONE;
552
-}
553
-
554
-static RISCVException write_upmmask(CPURISCVState *env, int csrno,
555
- target_ulong val)
556
-{
557
- uint64_t mstatus;
558
-
559
- /* if pm.current==0 we can't modify current PM CSRs */
560
- if (check_pm_current_disabled(env, csrno)) {
561
- return RISCV_EXCP_NONE;
562
- }
563
- env->upmmask = val;
564
- if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
565
- env->cur_pmmask = val;
566
- if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
567
- env->cur_pmmask &= UINT32_MAX;
568
- }
569
- }
570
- env->mmte |= EXT_STATUS_DIRTY;
571
-
572
- /* Set XS and SD bits, since PM CSRs are dirty */
573
- mstatus = env->mstatus | MSTATUS_XS;
574
- write_mstatus(env, csrno, mstatus);
575
- return RISCV_EXCP_NONE;
576
-}
577
-
578
-static RISCVException read_mpmbase(CPURISCVState *env, int csrno,
579
- target_ulong *val)
580
-{
581
- *val = env->mpmbase;
582
- return RISCV_EXCP_NONE;
583
-}
584
-
585
-static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
586
- target_ulong val)
587
-{
588
- uint64_t mstatus;
589
-
590
- env->mpmbase = val;
591
- if ((cpu_address_mode(env) == PRV_M) && (env->mmte & M_PM_ENABLE)) {
592
- env->cur_pmbase = val;
593
- }
594
- env->mmte |= EXT_STATUS_DIRTY;
595
-
596
- /* Set XS and SD bits, since PM CSRs are dirty */
597
- mstatus = env->mstatus | MSTATUS_XS;
598
- write_mstatus(env, csrno, mstatus);
599
- return RISCV_EXCP_NONE;
600
-}
601
-
602
-static RISCVException read_spmbase(CPURISCVState *env, int csrno,
603
- target_ulong *val)
604
-{
605
- *val = env->spmbase;
606
- return RISCV_EXCP_NONE;
607
-}
608
-
609
-static RISCVException write_spmbase(CPURISCVState *env, int csrno,
610
- target_ulong val)
611
-{
612
- uint64_t mstatus;
613
-
614
- /* if pm.current==0 we can't modify current PM CSRs */
615
- if (check_pm_current_disabled(env, csrno)) {
616
- return RISCV_EXCP_NONE;
617
- }
618
- env->spmbase = val;
619
- if ((cpu_address_mode(env) == PRV_S) && (env->mmte & S_PM_ENABLE)) {
620
- env->cur_pmbase = val;
621
- if (cpu_get_xl(env, PRV_S) == MXL_RV32) {
622
- env->cur_pmbase &= UINT32_MAX;
623
- }
624
- }
625
- env->mmte |= EXT_STATUS_DIRTY;
626
-
627
- /* Set XS and SD bits, since PM CSRs are dirty */
628
- mstatus = env->mstatus | MSTATUS_XS;
629
- write_mstatus(env, csrno, mstatus);
630
- return RISCV_EXCP_NONE;
631
-}
632
-
633
-static RISCVException read_upmbase(CPURISCVState *env, int csrno,
634
- target_ulong *val)
635
-{
636
- *val = env->upmbase;
637
- return RISCV_EXCP_NONE;
638
-}
639
-
640
-static RISCVException write_upmbase(CPURISCVState *env, int csrno,
641
- target_ulong val)
642
-{
643
- uint64_t mstatus;
644
-
645
- /* if pm.current==0 we can't modify current PM CSRs */
646
- if (check_pm_current_disabled(env, csrno)) {
647
- return RISCV_EXCP_NONE;
648
- }
649
- env->upmbase = val;
650
- if ((cpu_address_mode(env) == PRV_U) && (env->mmte & U_PM_ENABLE)) {
651
- env->cur_pmbase = val;
652
- if (cpu_get_xl(env, PRV_U) == MXL_RV32) {
653
- env->cur_pmbase &= UINT32_MAX;
654
- }
655
- }
656
- env->mmte |= EXT_STATUS_DIRTY;
657
-
658
- /* Set XS and SD bits, since PM CSRs are dirty */
659
- mstatus = env->mstatus | MSTATUS_XS;
660
- write_mstatus(env, csrno, mstatus);
661
- return RISCV_EXCP_NONE;
662
-}
663
-
664
#endif
665
666
/* Crypto Extension */
667
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
668
[CSR_TINFO] = { "tinfo", debug, read_tinfo, write_ignore },
669
[CSR_MCONTEXT] = { "mcontext", debug, read_mcontext, write_mcontext },
670
671
- /* User Pointer Masking */
672
- [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
673
- [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask,
674
- write_upmmask },
675
- [CSR_UPMBASE] = { "upmbase", pointer_masking, read_upmbase,
676
- write_upmbase },
677
- /* Machine Pointer Masking */
678
- [CSR_MMTE] = { "mmte", pointer_masking, read_mmte, write_mmte },
679
- [CSR_MPMMASK] = { "mpmmask", pointer_masking, read_mpmmask,
680
- write_mpmmask },
681
- [CSR_MPMBASE] = { "mpmbase", pointer_masking, read_mpmbase,
682
- write_mpmbase },
683
- /* Supervisor Pointer Masking */
684
- [CSR_SMTE] = { "smte", pointer_masking, read_smte, write_smte },
685
- [CSR_SPMMASK] = { "spmmask", pointer_masking, read_spmmask,
686
- write_spmmask },
687
- [CSR_SPMBASE] = { "spmbase", pointer_masking, read_spmbase,
688
- write_spmbase },
689
-
690
/* Performance Counters */
691
[CSR_HPMCOUNTER3] = { "hpmcounter3", ctr, read_hpmcounter },
692
[CSR_HPMCOUNTER4] = { "hpmcounter4", ctr, read_hpmcounter },
693
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
694
index XXXXXXX..XXXXXXX 100644
695
--- a/target/riscv/machine.c
696
+++ b/target/riscv/machine.c
697
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vector = {
698
699
static bool pointermasking_needed(void *opaque)
700
{
701
- RISCVCPU *cpu = opaque;
702
- CPURISCVState *env = &cpu->env;
703
-
704
- return riscv_has_ext(env, RVJ);
705
+ return false;
706
}
707
708
static const VMStateDescription vmstate_pointermasking = {
709
.name = "cpu/pointer_masking",
710
- .version_id = 1,
711
- .minimum_version_id = 1,
712
+ .version_id = 2,
713
+ .minimum_version_id = 2,
714
.needed = pointermasking_needed,
715
.fields = (const VMStateField[]) {
716
- VMSTATE_UINTTL(env.mmte, RISCVCPU),
717
- VMSTATE_UINTTL(env.mpmmask, RISCVCPU),
718
- VMSTATE_UINTTL(env.mpmbase, RISCVCPU),
719
- VMSTATE_UINTTL(env.spmmask, RISCVCPU),
720
- VMSTATE_UINTTL(env.spmbase, RISCVCPU),
721
- VMSTATE_UINTTL(env.upmmask, RISCVCPU),
722
- VMSTATE_UINTTL(env.upmbase, RISCVCPU),
723
724
VMSTATE_END_OF_LIST()
725
}
726
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_post_load(void *opaque, int version_id)
727
CPURISCVState *env = &cpu->env;
728
729
env->xl = cpu_recompute_xl(env);
730
- riscv_cpu_update_mask(env);
731
return 0;
732
}
733
734
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
735
index XXXXXXX..XXXXXXX 100644
736
--- a/target/riscv/tcg/tcg-cpu.c
737
+++ b/target/riscv/tcg/tcg-cpu.c
738
@@ -XXX,XX +XXX,XX @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = {
739
MISA_CFG(RVS, true),
740
MISA_CFG(RVU, true),
741
MISA_CFG(RVH, true),
742
- MISA_CFG(RVJ, false),
743
MISA_CFG(RVV, false),
744
MISA_CFG(RVG, false),
745
MISA_CFG(RVB, false),
746
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
747
CPURISCVState *env = &cpu->env;
748
const RISCVCPUMultiExtConfig *prop;
749
750
- /* Enable RVG, RVJ and RVV that are disabled by default */
751
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
752
+ /* Enable RVG and RVV that are disabled by default */
753
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVV);
754
755
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
756
isa_ext_update_enabled(cpu, prop->offset, true);
757
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
758
index XXXXXXX..XXXXXXX 100644
759
--- a/target/riscv/translate.c
760
+++ b/target/riscv/translate.c
761
@@ -XXX,XX +XXX,XX @@ static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
762
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
763
static TCGv load_res;
764
static TCGv load_val;
765
-/* globals for PM CSRs */
766
-static TCGv pm_mask;
767
-static TCGv pm_base;
768
769
/*
770
* If an operation is being performed on less than TARGET_LONG_BITS,
771
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
772
bool vl_eq_vlmax;
773
CPUState *cs;
774
TCGv zero;
775
- /* PointerMasking extension */
776
- bool pm_mask_enabled;
777
- bool pm_base_enabled;
778
/* Ztso */
779
bool ztso;
780
/* Use icount trigger for native debug */
781
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
782
TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
783
784
tcg_gen_addi_tl(addr, src1, imm);
785
- if (ctx->pm_mask_enabled) {
786
- tcg_gen_andc_tl(addr, addr, pm_mask);
787
- } else if (get_address_xl(ctx) == MXL_RV32) {
788
+ if (get_address_xl(ctx) == MXL_RV32) {
789
tcg_gen_ext32u_tl(addr, addr);
790
}
791
- if (ctx->pm_base_enabled) {
792
- tcg_gen_or_tl(addr, addr, pm_base);
793
- }
794
795
return addr;
796
}
797
@@ -XXX,XX +XXX,XX @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs)
798
TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
799
800
tcg_gen_add_tl(addr, src1, offs);
801
- if (ctx->pm_mask_enabled) {
802
- tcg_gen_andc_tl(addr, addr, pm_mask);
803
- } else if (get_xl(ctx) == MXL_RV32) {
804
+ if (get_xl(ctx) == MXL_RV32) {
805
tcg_gen_ext32u_tl(addr, addr);
806
}
807
- if (ctx->pm_base_enabled) {
808
- tcg_gen_or_tl(addr, addr, pm_base);
809
- }
810
+
811
return addr;
812
}
813
814
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
815
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
816
ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
817
ctx->cs = cs;
818
- ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
819
- ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
820
ctx->ztso = cpu->cfg.ext_ztso;
821
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
822
ctx->bcfi_enabled = FIELD_EX32(tb_flags, TB_FLAGS, BCFI_ENABLED);
823
@@ -XXX,XX +XXX,XX @@ void riscv_translate_init(void)
824
"load_res");
825
load_val = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, load_val),
826
"load_val");
827
- /* Assign PM CSRs to tcg globals */
828
- pm_mask = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, cur_pmmask),
829
- "pmmask");
830
- pm_base = tcg_global_mem_new(tcg_env, offsetof(CPURISCVState, cur_pmbase),
831
- "pmbase");
832
}
833
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
834
index XXXXXXX..XXXXXXX 100644
835
--- a/target/riscv/vector_helper.c
836
+++ b/target/riscv/vector_helper.c
837
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
838
839
static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
840
{
841
- return (addr & ~env->cur_pmmask) | env->cur_pmbase;
842
+ return addr;
843
}
844
845
/*
846
--
847
2.48.1
diff view generated by jsdifflib
1
From: Alexey Baturo <baturo.alexey@gmail.com>
2
3
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
4
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-ID: <20250106102346.1100149-3-baturo.alexey@gmail.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
---
8
---
4
target/riscv/pmp.c | 14 +++++++++-----
9
target/riscv/cpu.h | 8 ++++++++
5
1 file changed, 9 insertions(+), 5 deletions(-)
10
target/riscv/cpu_bits.h | 4 ++++
11
target/riscv/cpu_cfg.h | 3 +++
12
target/riscv/pmp.h | 1 +
13
target/riscv/csr.c | 33 +++++++++++++++++++++++++++++++--
14
target/riscv/pmp.c | 14 +++++++++++---
15
6 files changed, 58 insertions(+), 5 deletions(-)
6
16
17
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.h
20
+++ b/target/riscv/cpu.h
21
@@ -XXX,XX +XXX,XX @@ typedef enum {
22
EXT_STATUS_DIRTY,
23
} RISCVExtStatus;
24
25
+/* Enum holds PMM field values for Zjpm v1.0 extension */
26
+typedef enum {
27
+ PMM_FIELD_DISABLED = 0,
28
+ PMM_FIELD_RESERVED = 1,
29
+ PMM_FIELD_PMLEN7 = 2,
30
+ PMM_FIELD_PMLEN16 = 3,
31
+} RISCVPmPmm;
32
+
33
typedef struct riscv_cpu_implied_exts_rule {
34
#ifndef CONFIG_USER_ONLY
35
/*
36
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu_bits.h
39
+++ b/target/riscv/cpu_bits.h
40
@@ -XXX,XX +XXX,XX @@ typedef enum {
41
#define HSTATUS_VTSR 0x00400000
42
#define HSTATUS_HUKTE 0x01000000
43
#define HSTATUS_VSXL 0x300000000
44
+#define HSTATUS_HUPMM 0x3000000000000
45
46
#define HSTATUS32_WPRI 0xFF8FF87E
47
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
48
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
49
#define MENVCFG_CBIE (3UL << 4)
50
#define MENVCFG_CBCFE BIT(6)
51
#define MENVCFG_CBZE BIT(7)
52
+#define MENVCFG_PMM (3ULL << 32)
53
#define MENVCFG_ADUE (1ULL << 61)
54
#define MENVCFG_PBMTE (1ULL << 62)
55
#define MENVCFG_STCE (1ULL << 63)
56
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
57
#define SENVCFG_CBCFE MENVCFG_CBCFE
58
#define SENVCFG_CBZE MENVCFG_CBZE
59
#define SENVCFG_UKTE BIT(8)
60
+#define SENVCFG_PMM MENVCFG_PMM
61
62
#define HENVCFG_FIOM MENVCFG_FIOM
63
#define HENVCFG_LPE MENVCFG_LPE
64
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
65
#define HENVCFG_CBIE MENVCFG_CBIE
66
#define HENVCFG_CBCFE MENVCFG_CBCFE
67
#define HENVCFG_CBZE MENVCFG_CBZE
68
+#define HENVCFG_PMM MENVCFG_PMM
69
#define HENVCFG_ADUE MENVCFG_ADUE
70
#define HENVCFG_PBMTE MENVCFG_PBMTE
71
#define HENVCFG_STCE MENVCFG_STCE
72
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu_cfg.h
75
+++ b/target/riscv/cpu_cfg.h
76
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
77
bool ext_ssaia;
78
bool ext_sscofpmf;
79
bool ext_smepmp;
80
+ bool ext_ssnpm;
81
+ bool ext_smnpm;
82
+ bool ext_smmpm;
83
bool rvv_ta_all_1s;
84
bool rvv_ma_all_1s;
85
bool rvv_vl_half_avl;
86
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/riscv/pmp.h
89
+++ b/target/riscv/pmp.h
90
@@ -XXX,XX +XXX,XX @@ typedef enum {
91
MSECCFG_USEED = 1 << 8,
92
MSECCFG_SSEED = 1 << 9,
93
MSECCFG_MLPE = 1 << 10,
94
+ MSECCFG_PMM = 3ULL << 32,
95
} mseccfg_field_t;
96
97
typedef struct {
98
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/target/riscv/csr.c
101
+++ b/target/riscv/csr.c
102
@@ -XXX,XX +XXX,XX @@ static RISCVException have_mseccfg(CPURISCVState *env, int csrno)
103
if (riscv_cpu_cfg(env)->ext_zkr) {
104
return RISCV_EXCP_NONE;
105
}
106
+ if (riscv_cpu_cfg(env)->ext_smmpm) {
107
+ return RISCV_EXCP_NONE;
108
+ }
109
110
return RISCV_EXCP_ILLEGAL_INST;
111
}
112
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
113
if (env_archcpu(env)->cfg.ext_zicfiss) {
114
mask |= MENVCFG_SSE;
115
}
116
+
117
+ /* Update PMM field only if the value is valid according to Zjpm v1.0 */
118
+ if (env_archcpu(env)->cfg.ext_smnpm &&
119
+ get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
120
+ mask |= MENVCFG_PMM;
121
+ }
122
}
123
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
124
125
@@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
126
{
127
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
128
RISCVException ret;
129
+ /* Update PMM field only if the value is valid according to Zjpm v1.0 */
130
+ if (env_archcpu(env)->cfg.ext_ssnpm &&
131
+ riscv_cpu_mxl(env) == MXL_RV64 &&
132
+ get_field(val, SENVCFG_PMM) != PMM_FIELD_RESERVED) {
133
+ mask |= SENVCFG_PMM;
134
+ }
135
136
ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
137
if (ret != RISCV_EXCP_NONE) {
138
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
139
get_field(env->menvcfg, MENVCFG_SSE)) {
140
mask |= HENVCFG_SSE;
141
}
142
+
143
+ /* Update PMM field only if the value is valid according to Zjpm v1.0 */
144
+ if (env_archcpu(env)->cfg.ext_ssnpm &&
145
+ get_field(val, HENVCFG_PMM) != PMM_FIELD_RESERVED) {
146
+ mask |= HENVCFG_PMM;
147
+ }
148
}
149
150
env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
151
@@ -XXX,XX +XXX,XX @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
152
static RISCVException write_hstatus(CPURISCVState *env, int csrno,
153
target_ulong val)
154
{
155
+ uint64_t mask = (target_ulong)-1;
156
if (!env_archcpu(env)->cfg.ext_svukte) {
157
- val = val & (~HSTATUS_HUKTE);
158
+ mask &= ~HSTATUS_HUKTE;
159
}
160
- env->hstatus = val;
161
+ /* Update PMM field only if the value is valid according to Zjpm v1.0 */
162
+ if (!env_archcpu(env)->cfg.ext_ssnpm ||
163
+ riscv_cpu_mxl(env) != MXL_RV64 ||
164
+ get_field(val, HSTATUS_HUPMM) == PMM_FIELD_RESERVED) {
165
+ mask &= ~HSTATUS_HUPMM;
166
+ }
167
+ env->hstatus = (env->hstatus & ~mask) | (val & mask);
168
+
169
if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
170
qemu_log_mask(LOG_UNIMP,
171
"QEMU does not support mixed HSXLEN options.");
7
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
172
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
8
index XXXXXXX..XXXXXXX 100644
173
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/pmp.c
174
--- a/target/riscv/pmp.c
10
+++ b/target/riscv/pmp.c
175
+++ b/target/riscv/pmp.c
11
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
176
@@ -XXX,XX +XXX,XX @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
12
return true;
177
void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
13
}
178
{
14
179
int i;
15
- /*
180
+ uint64_t mask = MSECCFG_MMWP | MSECCFG_MML;
16
- * if size is unknown (0), assume that all bytes
181
+ /* Update PMM field only if the value is valid according to Zjpm v1.0 */
17
- * from addr to the end of the page will be accessed.
182
+ if (riscv_cpu_cfg(env)->ext_smmpm &&
18
- */
183
+ riscv_cpu_mxl(env) == MXL_RV64 &&
19
if (size == 0) {
184
+ get_field(val, MSECCFG_PMM) != PMM_FIELD_RESERVED) {
20
- pmp_size = -(addr | TARGET_PAGE_MASK);
185
+ mask |= MSECCFG_PMM;
21
+ if (riscv_feature(env, RISCV_FEATURE_MMU)) {
186
+ }
22
+ /*
187
23
+ * If size is unknown (0), assume that all bytes
188
trace_mseccfg_csr_write(env->mhartid, val);
24
+ * from addr to the end of the page will be accessed.
189
25
+ */
190
@@ -XXX,XX +XXX,XX @@ void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
26
+ pmp_size = -(addr | TARGET_PAGE_MASK);
191
27
+ } else {
192
if (riscv_cpu_cfg(env)->ext_smepmp) {
28
+ pmp_size = sizeof(target_ulong);
193
/* Sticky bits */
29
+ }
194
- val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
195
- if ((val ^ env->mseccfg) & (MSECCFG_MMWP | MSECCFG_MML)) {
196
+ val |= (env->mseccfg & mask);
197
+ if ((val ^ env->mseccfg) & mask) {
198
tlb_flush(env_cpu(env));
199
}
30
} else {
200
} else {
31
pmp_size = size;
201
- val &= ~(MSECCFG_MMWP | MSECCFG_MML | MSECCFG_RLB);
32
}
202
+ mask |= MSECCFG_RLB;
203
+ val &= ~(mask);
204
}
205
206
/* M-mode forward cfi to be enabled if cfi extension is implemented */
33
--
207
--
34
2.27.0
208
2.48.1
35
36
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Alexey Baturo <baturo.alexey@gmail.com>
2
2
3
The HiFive Unleashed board wires GPIO pin#10 to the input of the
3
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
4
system reset signal. Let's set up the GPIO pin#10 and insert a
4
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
5
"gpio-restart" device tree node so that reboot is now functional
6
with QEMU 'sifive_u' machine.
7
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 1591625864-31494-10-git-send-email-bmeng.cn@gmail.com
6
Message-ID: <20250106102346.1100149-4-baturo.alexey@gmail.com>
11
Message-Id: <1591625864-31494-10-git-send-email-bmeng.cn@gmail.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
8
---
14
hw/riscv/sifive_u.c | 24 +++++++++++++++++++++++-
9
target/riscv/cpu.h | 5 +++
15
1 file changed, 23 insertions(+), 1 deletion(-)
10
target/riscv/cpu_helper.c | 78 +++++++++++++++++++++++++++++++++++++++
11
2 files changed, 83 insertions(+)
16
12
17
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
13
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/sifive_u.c
15
--- a/target/riscv/cpu.h
20
+++ b/hw/riscv/sifive_u.c
16
+++ b/target/riscv/cpu.h
21
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
22
#include "qapi/error.h"
18
23
#include "qapi/visitor.h"
19
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
24
#include "hw/boards.h"
20
25
+#include "hw/irq.h"
21
+bool riscv_cpu_virt_mem_enabled(CPURISCVState *env);
26
#include "hw/loader.h"
22
+RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env);
27
#include "hw/sysbus.h"
23
+uint32_t riscv_pm_get_pmlen(RISCVPmPmm pmm);
28
#include "hw/char/serial.h"
29
@@ -XXX,XX +XXX,XX @@
30
#include "net/eth.h"
31
#include "sysemu/arch_init.h"
32
#include "sysemu/device_tree.h"
33
+#include "sysemu/runstate.h"
34
#include "sysemu/sysemu.h"
35
#include "exec/address-spaces.h"
36
37
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
38
uint32_t *cells;
39
char *nodename;
40
char ethclk_names[] = "pclk\0hclk";
41
- uint32_t plic_phandle, prci_phandle, phandle = 1;
42
+ uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
43
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
44
45
fdt = s->fdt = create_device_tree(&s->fdt_size);
46
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
47
g_free(cells);
48
g_free(nodename);
49
50
+ gpio_phandle = phandle++;
51
nodename = g_strdup_printf("/soc/gpio@%lx",
52
(long)memmap[SIFIVE_U_GPIO].base);
53
qemu_fdt_add_subnode(fdt, nodename);
54
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", gpio_phandle);
55
qemu_fdt_setprop_cells(fdt, nodename, "clocks",
56
prci_phandle, PRCI_CLK_TLCLK);
57
qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
58
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
59
qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
60
g_free(nodename);
61
62
+ nodename = g_strdup_printf("/gpio-restart");
63
+ qemu_fdt_add_subnode(fdt, nodename);
64
+ qemu_fdt_setprop_cells(fdt, nodename, "gpios", gpio_phandle, 10, 1);
65
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart");
66
+ g_free(nodename);
67
+
24
+
68
phy_phandle = phandle++;
25
RISCVException riscv_csrr(CPURISCVState *env, int csrno,
69
nodename = g_strdup_printf("/soc/ethernet@%lx",
26
target_ulong *ret_value);
70
(long)memmap[SIFIVE_U_GEM].base);
27
+
71
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
28
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
72
g_free(nodename);
29
target_ulong *ret_value,
30
target_ulong new_value, target_ulong write_mask);
31
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_helper.c
34
+++ b/target/riscv/cpu_helper.c
35
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
36
*pflags = flags;
73
}
37
}
74
38
75
+static void sifive_u_machine_reset(void *opaque, int n, int level)
39
+RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
76
+{
40
+{
77
+ /* gpio pin active low triggers reset */
41
+#ifndef CONFIG_USER_ONLY
78
+ if (!level) {
42
+ int priv_mode = cpu_address_mode(env);
79
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
43
+
44
+ if (get_field(env->mstatus, MSTATUS_MPRV) &&
45
+ get_field(env->mstatus, MSTATUS_MXR)) {
46
+ return PMM_FIELD_DISABLED;
47
+ }
48
+
49
+ /* Get current PMM field */
50
+ switch (priv_mode) {
51
+ case PRV_M:
52
+ if (riscv_cpu_cfg(env)->ext_smmpm) {
53
+ return get_field(env->mseccfg, MSECCFG_PMM);
54
+ }
55
+ break;
56
+ case PRV_S:
57
+ if (riscv_cpu_cfg(env)->ext_smnpm) {
58
+ if (get_field(env->mstatus, MSTATUS_MPV)) {
59
+ return get_field(env->henvcfg, HENVCFG_PMM);
60
+ } else {
61
+ return get_field(env->menvcfg, MENVCFG_PMM);
62
+ }
63
+ }
64
+ break;
65
+ case PRV_U:
66
+ if (riscv_has_ext(env, RVS)) {
67
+ if (riscv_cpu_cfg(env)->ext_ssnpm) {
68
+ return get_field(env->senvcfg, SENVCFG_PMM);
69
+ }
70
+ } else {
71
+ if (riscv_cpu_cfg(env)->ext_smnpm) {
72
+ return get_field(env->menvcfg, MENVCFG_PMM);
73
+ }
74
+ }
75
+ break;
76
+ default:
77
+ g_assert_not_reached();
78
+ }
79
+ return PMM_FIELD_DISABLED;
80
+#else
81
+ return PMM_FIELD_DISABLED;
82
+#endif
83
+}
84
+
85
+bool riscv_cpu_virt_mem_enabled(CPURISCVState *env)
86
+{
87
+#ifndef CONFIG_USER_ONLY
88
+ int satp_mode = 0;
89
+ int priv_mode = cpu_address_mode(env);
90
+
91
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
92
+ satp_mode = get_field(env->satp, SATP32_MODE);
93
+ } else {
94
+ satp_mode = get_field(env->satp, SATP64_MODE);
95
+ }
96
+
97
+ return ((satp_mode != VM_1_10_MBARE) && (priv_mode != PRV_M));
98
+#else
99
+ return false;
100
+#endif
101
+}
102
+
103
+uint32_t riscv_pm_get_pmlen(RISCVPmPmm pmm)
104
+{
105
+ switch (pmm) {
106
+ case PMM_FIELD_DISABLED:
107
+ return 0;
108
+ case PMM_FIELD_PMLEN7:
109
+ return 7;
110
+ case PMM_FIELD_PMLEN16:
111
+ return 16;
112
+ default:
113
+ g_assert_not_reached();
80
+ }
114
+ }
81
+}
115
+}
82
+
116
+
83
static void sifive_u_machine_init(MachineState *machine)
117
#ifndef CONFIG_USER_ONLY
84
{
118
85
const struct MemmapEntry *memmap = sifive_u_memmap;
119
/*
86
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
87
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_FLASH0].base,
88
flash0);
89
90
+ /* register gpio-restart */
91
+ qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10,
92
+ qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
93
+
94
/* create device tree */
95
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
96
97
--
120
--
98
2.27.0
121
2.48.1
99
100
diff view generated by jsdifflib
New patch
1
From: Alexey Baturo <baturo.alexey@gmail.com>
1
2
3
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
7
Message-ID: <20250106102346.1100149-5-baturo.alexey@gmail.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/cpu.h | 3 +++
11
target/riscv/cpu_helper.c | 3 +++
12
target/riscv/translate.c | 5 +++++
13
3 files changed, 11 insertions(+)
14
15
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.h
18
+++ b/target/riscv/cpu.h
19
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, FCFI_ENABLED, 26, 1)
20
FIELD(TB_FLAGS, FCFI_LP_EXPECTED, 27, 1)
21
/* zicfiss needs a TB flag so that correct TB is located based on tb flags */
22
FIELD(TB_FLAGS, BCFI_ENABLED, 28, 1)
23
+/* If pointer masking should be applied and address sign extended */
24
+FIELD(TB_FLAGS, PM_PMM, 29, 2)
25
+FIELD(TB_FLAGS, PM_SIGNEXTEND, 31, 1)
26
27
#ifdef TARGET_RISCV32
28
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
29
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu_helper.c
32
+++ b/target/riscv/cpu_helper.c
33
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
34
RISCVCPU *cpu = env_archcpu(env);
35
RISCVExtStatus fs, vs;
36
uint32_t flags = 0;
37
+ bool pm_signext = riscv_cpu_virt_mem_enabled(env);
38
39
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
40
*cs_base = 0;
41
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
42
flags = FIELD_DP32(flags, TB_FLAGS, VS, vs);
43
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
44
flags = FIELD_DP32(flags, TB_FLAGS, AXL, cpu_address_xl(env));
45
+ flags = FIELD_DP32(flags, TB_FLAGS, PM_PMM, riscv_pm_get_pmm(env));
46
+ flags = FIELD_DP32(flags, TB_FLAGS, PM_SIGNEXTEND, pm_signext);
47
48
*pflags = flags;
49
}
50
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/translate.c
53
+++ b/target/riscv/translate.c
54
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
55
bool vl_eq_vlmax;
56
CPUState *cs;
57
TCGv zero;
58
+ /* actual address width */
59
+ uint8_t addr_xl;
60
+ bool addr_signed;
61
/* Ztso */
62
bool ztso;
63
/* Use icount trigger for native debug */
64
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
65
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
66
ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
67
ctx->cs = cs;
68
+ ctx->addr_xl = 0;
69
+ ctx->addr_signed = false;
70
ctx->ztso = cpu->cfg.ext_ztso;
71
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
72
ctx->bcfi_enabled = FIELD_EX32(tb_flags, TB_FLAGS, BCFI_ENABLED);
73
--
74
2.48.1
diff view generated by jsdifflib
1
Also correct the name of the VVMA instruction.
1
From: Alexey Baturo <baturo.alexey@gmail.com>
2
2
3
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-ID: <20250106102346.1100149-6-baturo.alexey@gmail.com>
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
---
8
---
6
target/riscv/insn32.decode | 8 ++-
9
target/riscv/translate.c | 22 ++++++++++++++++------
7
.../riscv/insn_trans/trans_privileged.inc.c | 38 -------------
10
target/riscv/vector_helper.c | 16 ++++++++++++++++
8
target/riscv/insn_trans/trans_rvh.inc.c | 57 +++++++++++++++++++
11
2 files changed, 32 insertions(+), 6 deletions(-)
9
target/riscv/translate.c | 1 +
10
4 files changed, 63 insertions(+), 41 deletions(-)
11
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
12
12
13
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/insn32.decode
16
+++ b/target/riscv/insn32.decode
17
@@ -XXX,XX +XXX,XX @@
18
@r2 ....... ..... ..... ... ..... ....... %rs1 %rd
19
20
@hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1
21
-@hfence_bvma ....... ..... ..... ... ..... ....... %rs2 %rs1
22
+@hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1
23
24
@sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1
25
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
26
@@ -XXX,XX +XXX,XX @@ uret 0000000 00010 00000 000 00000 1110011
27
sret 0001000 00010 00000 000 00000 1110011
28
mret 0011000 00010 00000 000 00000 1110011
29
wfi 0001000 00101 00000 000 00000 1110011
30
-hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
31
-hfence_bvma 0010001 ..... ..... 000 00000 1110011 @hfence_bvma
32
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
33
sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
34
35
@@ -XXX,XX +XXX,XX @@ fcvt_w_d 1100001 00000 ..... ... ..... 1010011 @r2_rm
36
fcvt_wu_d 1100001 00001 ..... ... ..... 1010011 @r2_rm
37
fcvt_d_w 1101001 00000 ..... ... ..... 1010011 @r2_rm
38
fcvt_d_wu 1101001 00001 ..... ... ..... 1010011 @r2_rm
39
+
40
+# *** RV32H Base Instruction Set ***
41
+hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
42
+hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma
43
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c b/target/riscv/insn_trans/trans_privileged.inc.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/insn_trans/trans_privileged.inc.c
46
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
47
@@ -XXX,XX +XXX,XX @@ static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
48
{
49
return false;
50
}
51
-
52
-static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
53
-{
54
-#ifndef CONFIG_USER_ONLY
55
- if (has_ext(ctx, RVH)) {
56
- /* Hpervisor extensions exist */
57
- /*
58
- * if (env->priv == PRV_M ||
59
- * (env->priv == PRV_S &&
60
- * !riscv_cpu_virt_enabled(env) &&
61
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
62
- */
63
- gen_helper_tlb_flush(cpu_env);
64
- return true;
65
- /* } */
66
- }
67
-#endif
68
- return false;
69
-}
70
-
71
-static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
72
-{
73
-#ifndef CONFIG_USER_ONLY
74
- if (has_ext(ctx, RVH)) {
75
- /* Hpervisor extensions exist */
76
- /*
77
- * if (env->priv == PRV_M ||
78
- * (env->priv == PRV_S &&
79
- * !riscv_cpu_virt_enabled(env) &&
80
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
81
- */
82
- gen_helper_tlb_flush(cpu_env);
83
- return true;
84
- /* } */
85
- }
86
-#endif
87
- return false;
88
-}
89
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
90
new file mode 100644
91
index XXXXXXX..XXXXXXX
92
--- /dev/null
93
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
94
@@ -XXX,XX +XXX,XX @@
95
+/*
96
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
97
+ *
98
+ * Copyright (c) 2020 Western Digital
99
+ *
100
+ * This program is free software; you can redistribute it and/or modify it
101
+ * under the terms and conditions of the GNU General Public License,
102
+ * version 2 or later, as published by the Free Software Foundation.
103
+ *
104
+ * This program is distributed in the hope it will be useful, but WITHOUT
105
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
106
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
107
+ * more details.
108
+ *
109
+ * You should have received a copy of the GNU General Public License along with
110
+ * this program. If not, see <http://www.gnu.org/licenses/>.
111
+ */
112
+
113
+static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
114
+{
115
+#ifndef CONFIG_USER_ONLY
116
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
117
+ has_ext(ctx, RVH)) {
118
+ /* Hpervisor extensions exist */
119
+ /*
120
+ * if (env->priv == PRV_M ||
121
+ * (env->priv == PRV_S &&
122
+ * !riscv_cpu_virt_enabled(env) &&
123
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
124
+ */
125
+ gen_helper_tlb_flush(cpu_env);
126
+ return true;
127
+ /* } */
128
+ }
129
+#endif
130
+ return false;
131
+}
132
+
133
+static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
134
+{
135
+#ifndef CONFIG_USER_ONLY
136
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
137
+ has_ext(ctx, RVH)) {
138
+ /* Hpervisor extensions exist */
139
+ /*
140
+ * if (env->priv == PRV_M ||
141
+ * (env->priv == PRV_S &&
142
+ * !riscv_cpu_virt_enabled(env) &&
143
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
144
+ */
145
+ gen_helper_tlb_flush(cpu_env);
146
+ return true;
147
+ /* } */
148
+ }
149
+#endif
150
+ return false;
151
+}
152
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
13
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
153
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
154
--- a/target/riscv/translate.c
15
--- a/target/riscv/translate.c
155
+++ b/target/riscv/translate.c
16
+++ b/target/riscv/translate.c
156
@@ -XXX,XX +XXX,XX @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
17
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
157
#include "insn_trans/trans_rva.inc.c"
18
TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
158
#include "insn_trans/trans_rvf.inc.c"
19
159
#include "insn_trans/trans_rvd.inc.c"
20
tcg_gen_addi_tl(addr, src1, imm);
160
+#include "insn_trans/trans_rvh.inc.c"
21
- if (get_address_xl(ctx) == MXL_RV32) {
161
#include "insn_trans/trans_privileged.inc.c"
22
- tcg_gen_ext32u_tl(addr, addr);
162
23
+ if (ctx->addr_signed) {
163
/* Include the auto-generated decoder for 16 bit insn */
24
+ tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_xl);
25
+ } else {
26
+ tcg_gen_extract_tl(addr, addr, 0, ctx->addr_xl);
27
}
28
29
return addr;
30
@@ -XXX,XX +XXX,XX @@ static TCGv get_address_indexed(DisasContext *ctx, int rs1, TCGv offs)
31
TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
32
33
tcg_gen_add_tl(addr, src1, offs);
34
- if (get_xl(ctx) == MXL_RV32) {
35
- tcg_gen_ext32u_tl(addr, addr);
36
+ if (ctx->addr_signed) {
37
+ tcg_gen_sextract_tl(addr, addr, 0, ctx->addr_xl);
38
+ } else {
39
+ tcg_gen_extract_tl(addr, addr, 0, ctx->addr_xl);
40
}
41
42
return addr;
43
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
44
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
45
ctx->address_xl = FIELD_EX32(tb_flags, TB_FLAGS, AXL);
46
ctx->cs = cs;
47
- ctx->addr_xl = 0;
48
- ctx->addr_signed = false;
49
+ if (get_xl(ctx) == MXL_RV32) {
50
+ ctx->addr_xl = 32;
51
+ ctx->addr_signed = false;
52
+ } else {
53
+ int pm_pmm = FIELD_EX32(tb_flags, TB_FLAGS, PM_PMM);
54
+ ctx->addr_xl = 64 - riscv_pm_get_pmlen(pm_pmm);
55
+ ctx->addr_signed = FIELD_EX32(tb_flags, TB_FLAGS, PM_SIGNEXTEND);
56
+ }
57
ctx->ztso = cpu->cfg.ext_ztso;
58
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
59
ctx->bcfi_enabled = FIELD_EX32(tb_flags, TB_FLAGS, BCFI_ENABLED);
60
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/riscv/vector_helper.c
63
+++ b/target/riscv/vector_helper.c
64
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
65
66
static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
67
{
68
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
69
+ return addr;
70
+ }
71
+ RISCVPmPmm pmm = riscv_pm_get_pmm(env);
72
+ if (pmm == PMM_FIELD_DISABLED) {
73
+ return addr;
74
+ }
75
+ int pmlen = riscv_pm_get_pmlen(pmm);
76
+ bool signext = riscv_cpu_virt_mem_enabled(env);
77
+ addr = addr << pmlen;
78
+ /* sign/zero extend masked address by N-1 bit */
79
+ if (signext) {
80
+ addr = (target_long)addr >> pmlen;
81
+ } else {
82
+ addr = addr >> pmlen;
83
+ }
84
return addr;
85
}
86
164
--
87
--
165
2.27.0
88
2.48.1
166
167
diff view generated by jsdifflib
1
From: Alexey Baturo <baturo.alexey@gmail.com>
2
3
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
4
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-ID: <20250106102346.1100149-7-baturo.alexey@gmail.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
---
8
---
4
target/riscv/cpu_helper.c | 9 +++++++--
9
target/riscv/cpu.h | 1 +
5
1 file changed, 7 insertions(+), 2 deletions(-)
10
target/riscv/internals.h | 54 ++++++++++++++++++++++++++++++++++++
11
target/riscv/cpu_helper.c | 19 +++++++++++++
12
target/riscv/op_helper.c | 16 +++++------
13
target/riscv/vector_helper.c | 21 --------------
14
5 files changed, 82 insertions(+), 29 deletions(-)
6
15
16
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu.h
19
+++ b/target/riscv/cpu.h
20
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_is_32bit(RISCVCPU *cpu);
21
22
bool riscv_cpu_virt_mem_enabled(CPURISCVState *env);
23
RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env);
24
+RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env);
25
uint32_t riscv_pm_get_pmlen(RISCVPmPmm pmm);
26
27
RISCVException riscv_csrr(CPURISCVState *env, int csrno,
28
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/internals.h
31
+++ b/target/riscv/internals.h
32
@@ -XXX,XX +XXX,XX @@ static inline float16 check_nanbox_h(CPURISCVState *env, uint64_t f)
33
/* Our implementation of CPUClass::has_work */
34
bool riscv_cpu_has_work(CPUState *cs);
35
36
+/* Zjpm addr masking routine */
37
+static inline target_ulong adjust_addr_body(CPURISCVState *env,
38
+ target_ulong addr,
39
+ bool is_virt_addr)
40
+{
41
+ RISCVPmPmm pmm = PMM_FIELD_DISABLED;
42
+ uint32_t pmlen = 0;
43
+ bool signext = false;
44
+
45
+ /* do nothing for rv32 mode */
46
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
47
+ return addr;
48
+ }
49
+
50
+ /* get pmm field depending on whether addr is */
51
+ if (is_virt_addr) {
52
+ pmm = riscv_pm_get_virt_pmm(env);
53
+ } else {
54
+ pmm = riscv_pm_get_pmm(env);
55
+ }
56
+
57
+ /* if pointer masking is disabled, return original addr */
58
+ if (pmm == PMM_FIELD_DISABLED) {
59
+ return addr;
60
+ }
61
+
62
+ if (!is_virt_addr) {
63
+ signext = riscv_cpu_virt_mem_enabled(env);
64
+ }
65
+ addr = addr << pmlen;
66
+ pmlen = riscv_pm_get_pmlen(pmm);
67
+
68
+ /* sign/zero extend masked address by N-1 bit */
69
+ if (signext) {
70
+ addr = (target_long)addr >> pmlen;
71
+ } else {
72
+ addr = addr >> pmlen;
73
+ }
74
+
75
+ return addr;
76
+}
77
+
78
+static inline target_ulong adjust_addr(CPURISCVState *env,
79
+ target_ulong addr)
80
+{
81
+ return adjust_addr_body(env, addr, false);
82
+}
83
+
84
+static inline target_ulong adjust_addr_virt(CPURISCVState *env,
85
+ target_ulong addr)
86
+{
87
+ return adjust_addr_body(env, addr, true);
88
+}
89
+
90
#endif
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
91
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
8
index XXXXXXX..XXXXXXX 100644
92
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/cpu_helper.c
93
--- a/target/riscv/cpu_helper.c
10
+++ b/target/riscv/cpu_helper.c
94
+++ b/target/riscv/cpu_helper.c
11
@@ -XXX,XX +XXX,XX @@ restart:
95
@@ -XXX,XX +XXX,XX @@ RISCVPmPmm riscv_pm_get_pmm(CPURISCVState *env)
12
hwaddr vbase;
96
#endif
13
97
}
14
/* Do the second stage translation on the base PTE address. */
98
15
- get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
99
+RISCVPmPmm riscv_pm_get_virt_pmm(CPURISCVState *env)
16
- mmu_idx, false, true);
100
+{
17
+ int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
101
+#ifndef CONFIG_USER_ONLY
18
+ base, MMU_DATA_LOAD,
102
+ int priv_mode = cpu_address_mode(env);
19
+ mmu_idx, false, true);
103
+
20
+
104
+ if (priv_mode == PRV_U) {
21
+ if (vbase_ret != TRANSLATE_SUCCESS) {
105
+ return get_field(env->hstatus, HSTATUS_HUPMM);
22
+ return vbase_ret;
106
+ } else {
23
+ }
107
+ if (get_field(env->hstatus, HSTATUS_SPVP)) {
24
108
+ return get_field(env->henvcfg, HENVCFG_PMM);
25
pte_addr = vbase + idx * ptesize;
109
+ } else {
26
} else {
110
+ return get_field(env->senvcfg, SENVCFG_PMM);
111
+ }
112
+ }
113
+#else
114
+ return PMM_FIELD_DISABLED;
115
+#endif
116
+}
117
+
118
bool riscv_cpu_virt_mem_enabled(CPURISCVState *env)
119
{
120
#ifndef CONFIG_USER_ONLY
121
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
122
index XXXXXXX..XXXXXXX 100644
123
--- a/target/riscv/op_helper.c
124
+++ b/target/riscv/op_helper.c
125
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_hlv_bu(CPURISCVState *env, target_ulong addr)
126
int mmu_idx = check_access_hlsv(env, false, ra);
127
MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
128
129
- return cpu_ldb_mmu(env, addr, oi, ra);
130
+ return cpu_ldb_mmu(env, adjust_addr_virt(env, addr), oi, ra);
131
}
132
133
target_ulong helper_hyp_hlv_hu(CPURISCVState *env, target_ulong addr)
134
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_hlv_hu(CPURISCVState *env, target_ulong addr)
135
int mmu_idx = check_access_hlsv(env, false, ra);
136
MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
137
138
- return cpu_ldw_mmu(env, addr, oi, ra);
139
+ return cpu_ldw_mmu(env, adjust_addr_virt(env, addr), oi, ra);
140
}
141
142
target_ulong helper_hyp_hlv_wu(CPURISCVState *env, target_ulong addr)
143
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_hlv_wu(CPURISCVState *env, target_ulong addr)
144
int mmu_idx = check_access_hlsv(env, false, ra);
145
MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
146
147
- return cpu_ldl_mmu(env, addr, oi, ra);
148
+ return cpu_ldl_mmu(env, adjust_addr_virt(env, addr), oi, ra);
149
}
150
151
target_ulong helper_hyp_hlv_d(CPURISCVState *env, target_ulong addr)
152
@@ -XXX,XX +XXX,XX @@ target_ulong helper_hyp_hlv_d(CPURISCVState *env, target_ulong addr)
153
int mmu_idx = check_access_hlsv(env, false, ra);
154
MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx);
155
156
- return cpu_ldq_mmu(env, addr, oi, ra);
157
+ return cpu_ldq_mmu(env, adjust_addr_virt(env, addr), oi, ra);
158
}
159
160
void helper_hyp_hsv_b(CPURISCVState *env, target_ulong addr, target_ulong val)
161
@@ -XXX,XX +XXX,XX @@ void helper_hyp_hsv_b(CPURISCVState *env, target_ulong addr, target_ulong val)
162
int mmu_idx = check_access_hlsv(env, false, ra);
163
MemOpIdx oi = make_memop_idx(MO_UB, mmu_idx);
164
165
- cpu_stb_mmu(env, addr, val, oi, ra);
166
+ cpu_stb_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
167
}
168
169
void helper_hyp_hsv_h(CPURISCVState *env, target_ulong addr, target_ulong val)
170
@@ -XXX,XX +XXX,XX @@ void helper_hyp_hsv_h(CPURISCVState *env, target_ulong addr, target_ulong val)
171
int mmu_idx = check_access_hlsv(env, false, ra);
172
MemOpIdx oi = make_memop_idx(MO_TEUW, mmu_idx);
173
174
- cpu_stw_mmu(env, addr, val, oi, ra);
175
+ cpu_stw_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
176
}
177
178
void helper_hyp_hsv_w(CPURISCVState *env, target_ulong addr, target_ulong val)
179
@@ -XXX,XX +XXX,XX @@ void helper_hyp_hsv_w(CPURISCVState *env, target_ulong addr, target_ulong val)
180
int mmu_idx = check_access_hlsv(env, false, ra);
181
MemOpIdx oi = make_memop_idx(MO_TEUL, mmu_idx);
182
183
- cpu_stl_mmu(env, addr, val, oi, ra);
184
+ cpu_stl_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
185
}
186
187
void helper_hyp_hsv_d(CPURISCVState *env, target_ulong addr, target_ulong val)
188
@@ -XXX,XX +XXX,XX @@ void helper_hyp_hsv_d(CPURISCVState *env, target_ulong addr, target_ulong val)
189
int mmu_idx = check_access_hlsv(env, false, ra);
190
MemOpIdx oi = make_memop_idx(MO_TEUQ, mmu_idx);
191
192
- cpu_stq_mmu(env, addr, val, oi, ra);
193
+ cpu_stq_mmu(env, adjust_addr_virt(env, addr), val, oi, ra);
194
}
195
196
/*
197
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/target/riscv/vector_helper.c
200
+++ b/target/riscv/vector_helper.c
201
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t log2_esz)
202
return scale < 0 ? vlenb >> -scale : vlenb << scale;
203
}
204
205
-static inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
206
-{
207
- if (riscv_cpu_mxl(env) == MXL_RV32) {
208
- return addr;
209
- }
210
- RISCVPmPmm pmm = riscv_pm_get_pmm(env);
211
- if (pmm == PMM_FIELD_DISABLED) {
212
- return addr;
213
- }
214
- int pmlen = riscv_pm_get_pmlen(pmm);
215
- bool signext = riscv_cpu_virt_mem_enabled(env);
216
- addr = addr << pmlen;
217
- /* sign/zero extend masked address by N-1 bit */
218
- if (signext) {
219
- addr = (target_long)addr >> pmlen;
220
- } else {
221
- addr = addr >> pmlen;
222
- }
223
- return addr;
224
-}
225
-
226
/*
227
* This function checks watchpoint before real load operation.
228
*
27
--
229
--
28
2.27.0
230
2.48.1
29
30
diff view generated by jsdifflib
New patch
1
From: Alexey Baturo <baturo.alexey@gmail.com>
1
2
3
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-ID: <20250106102346.1100149-8-baturo.alexey@gmail.com>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
target/riscv/cpu.c | 6 ++++++
9
1 file changed, 6 insertions(+)
10
11
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/cpu.c
14
+++ b/target/riscv/cpu.c
15
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
16
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
17
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
18
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
19
+ ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
20
+ ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
21
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
22
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
23
ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
24
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
25
ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
26
+ ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_13_0, ext_ssnpm),
27
ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
28
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
29
ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
30
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
31
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
32
MULTI_EXT_CFG_BOOL("zvfhmin", ext_zvfhmin, false),
33
MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
34
+ MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false),
35
36
MULTI_EXT_CFG_BOOL("smaia", ext_smaia, false),
37
MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
38
+ MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false),
39
+ MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false),
40
MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
41
MULTI_EXT_CFG_BOOL("ssaia", ext_ssaia, false),
42
MULTI_EXT_CFG_BOOL("svade", ext_svade, false),
43
--
44
2.48.1
diff view generated by jsdifflib
New patch
1
From: Tommy Wu <tommy.wu@sifive.com>
1
2
3
The boolean variable 'ext_smrnmi' is used to determine whether the
4
Smrnmi extension exists.
5
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20250106054336.1878291-2-frank.chang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu_cfg.h | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_cfg.h
18
+++ b/target/riscv/cpu_cfg.h
19
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
20
bool ext_ssaia;
21
bool ext_sscofpmf;
22
bool ext_smepmp;
23
+ bool ext_smrnmi;
24
bool ext_ssnpm;
25
bool ext_smnpm;
26
bool ext_smmpm;
27
--
28
2.48.1
diff view generated by jsdifflib
1
The Ibex core contains a PLIC that although similar to the RISC-V spec
1
From: Tommy Wu <tommy.wu@sifive.com>
2
is not RISC-V spec compliant.
3
2
4
This patch implements a Ibex PLIC in a somewhat generic way.
3
The Smrnmi extension adds the 'mnscratch', 'mnepc', 'mncause',
4
'mnstatus' CSRs.
5
5
6
As the current RISC-V PLIC needs tidying up, my hope is that as the Ibex
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
PLIC move towards spec compliance this PLIC implementation can be
7
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
8
updated until it can replace the current PLIC.
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20250106054336.1878291-3-frank.chang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.h | 7 ++++
13
target/riscv/cpu_bits.h | 11 ++++++
14
target/riscv/cpu.c | 5 +++
15
target/riscv/csr.c | 82 +++++++++++++++++++++++++++++++++++++++++
16
4 files changed, 105 insertions(+)
9
17
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
19
index XXXXXXX..XXXXXXX 100644
12
---
20
--- a/target/riscv/cpu.h
13
include/hw/intc/ibex_plic.h | 63 +++++++++
21
+++ b/target/riscv/cpu.h
14
hw/intc/ibex_plic.c | 261 ++++++++++++++++++++++++++++++++++++
22
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
15
MAINTAINERS | 2 +
23
uint64_t kvm_timer_state;
16
hw/intc/Makefile.objs | 1 +
24
uint64_t kvm_timer_frequency;
17
4 files changed, 327 insertions(+)
25
#endif /* CONFIG_KVM */
18
create mode 100644 include/hw/intc/ibex_plic.h
26
+
19
create mode 100644 hw/intc/ibex_plic.c
27
+ /* RNMI */
20
28
+ target_ulong mnscratch;
21
diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
29
+ target_ulong mnepc;
22
new file mode 100644
30
+ target_ulong mncause; /* mncause without bit XLEN-1 set to 1 */
23
index XXXXXXX..XXXXXXX
31
+ target_ulong mnstatus;
24
--- /dev/null
32
+ target_ulong rnmip;
25
+++ b/include/hw/intc/ibex_plic.h
33
};
34
35
/*
36
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu_bits.h
39
+++ b/target/riscv/cpu_bits.h
26
@@ -XXX,XX +XXX,XX @@
40
@@ -XXX,XX +XXX,XX @@
27
+/*
41
#define CSR_PMPADDR14 0x3be
28
+ * QEMU RISC-V lowRISC Ibex PLIC
42
#define CSR_PMPADDR15 0x3bf
29
+ *
43
30
+ * Copyright (c) 2020 Western Digital
44
+/* RNMI */
31
+ *
45
+#define CSR_MNSCRATCH 0x740
32
+ * This program is free software; you can redistribute it and/or modify it
46
+#define CSR_MNEPC 0x741
33
+ * under the terms and conditions of the GNU General Public License,
47
+#define CSR_MNCAUSE 0x742
34
+ * version 2 or later, as published by the Free Software Foundation.
48
+#define CSR_MNSTATUS 0x744
35
+ *
36
+ * This program is distributed in the hope it will be useful, but WITHOUT
37
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
39
+ * more details.
40
+ *
41
+ * You should have received a copy of the GNU General Public License along with
42
+ * this program. If not, see <http://www.gnu.org/licenses/>.
43
+ */
44
+
49
+
45
+#ifndef HW_IBEX_PLIC_H
50
/* Debug/Trace Registers (shared with Debug Mode) */
46
+#define HW_IBEX_PLIC_H
51
#define CSR_TSELECT 0x7a0
52
#define CSR_TDATA1 0x7a1
53
@@ -XXX,XX +XXX,XX @@ typedef enum {
54
#define SATP64_ASID 0x0FFFF00000000000ULL
55
#define SATP64_PPN 0x00000FFFFFFFFFFFULL
56
57
+/* RNMI mnstatus CSR mask */
58
+#define MNSTATUS_NMIE 0x00000008
59
+#define MNSTATUS_MNPV 0x00000080
60
+#define MNSTATUS_MNPP 0x00001800
47
+
61
+
48
+#include "hw/sysbus.h"
62
/* VM modes (satp.mode) privileged ISA 1.10 */
49
+
63
#define VM_1_10_MBARE 0
50
+#define TYPE_IBEX_PLIC "ibex-plic"
64
#define VM_1_10_SV32 1
51
+#define IBEX_PLIC(obj) \
65
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
52
+ OBJECT_CHECK(IbexPlicState, (obj), TYPE_IBEX_PLIC)
66
index XXXXXXX..XXXXXXX 100644
53
+
67
--- a/target/riscv/cpu.c
54
+typedef struct IbexPlicState {
68
+++ b/target/riscv/cpu.c
55
+ /*< private >*/
69
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
56
+ SysBusDevice parent_obj;
70
riscv_trigger_reset_hold(env);
57
+
71
}
58
+ /*< public >*/
72
59
+ MemoryRegion mmio;
73
+ if (cpu->cfg.ext_smrnmi) {
60
+
74
+ env->rnmip = 0;
61
+ uint32_t *pending;
75
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, false);
62
+ uint32_t *source;
63
+ uint32_t *priority;
64
+ uint32_t *enable;
65
+ uint32_t threshold;
66
+ uint32_t claim;
67
+
68
+ /* config */
69
+ uint32_t num_cpus;
70
+ uint32_t num_sources;
71
+
72
+ uint32_t pending_base;
73
+ uint32_t pending_num;
74
+
75
+ uint32_t source_base;
76
+ uint32_t source_num;
77
+
78
+ uint32_t priority_base;
79
+ uint32_t priority_num;
80
+
81
+ uint32_t enable_base;
82
+ uint32_t enable_num;
83
+
84
+ uint32_t threshold_base;
85
+
86
+ uint32_t claim_base;
87
+} IbexPlicState;
88
+
89
+#endif /* HW_IBEX_PLIC_H */
90
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
91
new file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- /dev/null
94
+++ b/hw/intc/ibex_plic.c
95
@@ -XXX,XX +XXX,XX @@
96
+/*
97
+ * QEMU RISC-V lowRISC Ibex PLIC
98
+ *
99
+ * Copyright (c) 2020 Western Digital
100
+ *
101
+ * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
102
+ *
103
+ * This program is free software; you can redistribute it and/or modify it
104
+ * under the terms and conditions of the GNU General Public License,
105
+ * version 2 or later, as published by the Free Software Foundation.
106
+ *
107
+ * This program is distributed in the hope it will be useful, but WITHOUT
108
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
109
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
110
+ * more details.
111
+ *
112
+ * You should have received a copy of the GNU General Public License along with
113
+ * this program. If not, see <http://www.gnu.org/licenses/>.
114
+ */
115
+
116
+#include "qemu/osdep.h"
117
+#include "qemu/log.h"
118
+#include "hw/qdev-properties.h"
119
+#include "hw/core/cpu.h"
120
+#include "hw/boards.h"
121
+#include "hw/pci/msi.h"
122
+#include "target/riscv/cpu_bits.h"
123
+#include "target/riscv/cpu.h"
124
+#include "hw/intc/ibex_plic.h"
125
+
126
+static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
127
+{
128
+ uint32_t end = base + (num * 0x04);
129
+
130
+ if (addr >= base && addr < end) {
131
+ return true;
132
+ }
76
+ }
133
+
77
+
134
+ return false;
78
if (kvm_enabled()) {
79
kvm_riscv_reset_vcpu(cpu);
80
}
81
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/riscv/csr.c
84
+++ b/target/riscv/csr.c
85
@@ -XXX,XX +XXX,XX @@ static RISCVException debug(CPURISCVState *env, int csrno)
86
87
return RISCV_EXCP_ILLEGAL_INST;
88
}
89
+
90
+static RISCVException rnmi(CPURISCVState *env, int csrno)
91
+{
92
+ RISCVCPU *cpu = env_archcpu(env);
93
+
94
+ if (cpu->cfg.ext_smrnmi) {
95
+ return RISCV_EXCP_NONE;
96
+ }
97
+
98
+ return RISCV_EXCP_ILLEGAL_INST;
99
+}
100
#endif
101
102
static RISCVException seed(CPURISCVState *env, int csrno)
103
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcontext(CPURISCVState *env, int csrno,
104
return RISCV_EXCP_NONE;
105
}
106
107
+static RISCVException read_mnscratch(CPURISCVState *env, int csrno,
108
+ target_ulong *val)
109
+{
110
+ *val = env->mnscratch;
111
+ return RISCV_EXCP_NONE;
135
+}
112
+}
136
+
113
+
137
+static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
114
+static int write_mnscratch(CPURISCVState *env, int csrno, target_ulong val)
138
+{
115
+{
139
+ int pending_num = irq / 32;
116
+ env->mnscratch = val;
140
+
117
+ return RISCV_EXCP_NONE;
141
+ s->pending[pending_num] |= level << (irq % 32);
142
+}
118
+}
143
+
119
+
144
+static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
120
+static int read_mnepc(CPURISCVState *env, int csrno, target_ulong *val)
145
+{
121
+{
146
+ int i;
122
+ *val = env->mnepc;
123
+ return RISCV_EXCP_NONE;
124
+}
147
+
125
+
148
+ for (i = 0; i < s->pending_num; i++) {
126
+static int write_mnepc(CPURISCVState *env, int csrno, target_ulong val)
149
+ uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
127
+{
128
+ env->mnepc = val;
129
+ return RISCV_EXCP_NONE;
130
+}
150
+
131
+
151
+ if (!(s->pending[i] & s->enable[i])) {
132
+static int read_mncause(CPURISCVState *env, int csrno, target_ulong *val)
152
+ /* No pending and enabled IRQ */
133
+{
153
+ continue;
134
+ *val = env->mncause;
135
+ return RISCV_EXCP_NONE;
136
+}
137
+
138
+static int write_mncause(CPURISCVState *env, int csrno, target_ulong val)
139
+{
140
+ env->mncause = val;
141
+ return RISCV_EXCP_NONE;
142
+}
143
+
144
+static int read_mnstatus(CPURISCVState *env, int csrno, target_ulong *val)
145
+{
146
+ *val = env->mnstatus;
147
+ return RISCV_EXCP_NONE;
148
+}
149
+
150
+static int write_mnstatus(CPURISCVState *env, int csrno, target_ulong val)
151
+{
152
+ target_ulong mask = (MNSTATUS_NMIE | MNSTATUS_MNPP);
153
+
154
+ if (riscv_has_ext(env, RVH)) {
155
+ /* Flush tlb on mnstatus fields that affect VM. */
156
+ if ((val ^ env->mnstatus) & MNSTATUS_MNPV) {
157
+ tlb_flush(env_cpu(env));
154
+ }
158
+ }
155
+
159
+
156
+ if (s->priority[irq_num] > s->threshold) {
160
+ mask |= MNSTATUS_MNPV;
157
+ if (!s->claim) {
158
+ s->claim = irq_num;
159
+ }
160
+ return true;
161
+ }
162
+ }
161
+ }
163
+
162
+
164
+ return false;
163
+ /* mnstatus.mnie can only be cleared by hardware. */
164
+ env->mnstatus = (env->mnstatus & MNSTATUS_NMIE) | (val & mask);
165
+ return RISCV_EXCP_NONE;
165
+}
166
+}
166
+
167
+
167
+static void ibex_plic_update(IbexPlicState *s)
168
#endif
168
+{
169
169
+ CPUState *cpu;
170
/* Crypto Extension */
170
+ int level, i;
171
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
172
write_sstateen_1_3,
173
.min_priv_ver = PRIV_VERSION_1_12_0 },
174
175
+ /* RNMI */
176
+ [CSR_MNSCRATCH] = { "mnscratch", rnmi, read_mnscratch, write_mnscratch,
177
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
178
+ [CSR_MNEPC] = { "mnepc", rnmi, read_mnepc, write_mnepc,
179
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
180
+ [CSR_MNCAUSE] = { "mncause", rnmi, read_mncause, write_mncause,
181
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
182
+ [CSR_MNSTATUS] = { "mnstatus", rnmi, read_mnstatus, write_mnstatus,
183
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
171
+
184
+
172
+ for (i = 0; i < s->num_cpus; i++) {
185
/* Supervisor Trap Setup */
173
+ cpu = qemu_get_cpu(i);
186
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
174
+
187
NULL, read_sstatus_i128 },
175
+ if (!cpu) {
176
+ continue;
177
+ }
178
+
179
+ level = ibex_plic_irqs_pending(s, 0);
180
+
181
+ riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
182
+ }
183
+}
184
+
185
+static void ibex_plic_reset(DeviceState *dev)
186
+{
187
+ IbexPlicState *s = IBEX_PLIC(dev);
188
+
189
+ s->threshold = 0x00000000;
190
+ s->claim = 0x00000000;
191
+}
192
+
193
+static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
194
+ unsigned int size)
195
+{
196
+ IbexPlicState *s = opaque;
197
+ int offset;
198
+ uint32_t ret = 0;
199
+
200
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
201
+ offset = (addr - s->pending_base) / 4;
202
+ ret = s->pending[offset];
203
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "%s: Interrupt source mode not supported\n", __func__);
206
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
207
+ offset = (addr - s->priority_base) / 4;
208
+ ret = s->priority[offset];
209
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
210
+ offset = (addr - s->enable_base) / 4;
211
+ ret = s->enable[offset];
212
+ } else if (addr_between(addr, s->threshold_base, 1)) {
213
+ ret = s->threshold;
214
+ } else if (addr_between(addr, s->claim_base, 1)) {
215
+ int pending_num = s->claim / 32;
216
+ s->pending[pending_num] &= ~(1 << (s->claim % 32));
217
+
218
+ ret = s->claim;
219
+ }
220
+
221
+ return ret;
222
+}
223
+
224
+static void ibex_plic_write(void *opaque, hwaddr addr,
225
+ uint64_t value, unsigned int size)
226
+{
227
+ IbexPlicState *s = opaque;
228
+
229
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
230
+ qemu_log_mask(LOG_GUEST_ERROR,
231
+ "%s: Pending registers are read only\n", __func__);
232
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
233
+ qemu_log_mask(LOG_UNIMP,
234
+ "%s: Interrupt source mode not supported\n", __func__);
235
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
236
+ uint32_t irq = ((addr - s->priority_base) >> 2) + 1;
237
+ s->priority[irq] = value & 7;
238
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
239
+ uint32_t enable_reg = (addr - s->enable_base) / 4;
240
+
241
+ s->enable[enable_reg] = value;
242
+ } else if (addr_between(addr, s->threshold_base, 1)) {
243
+ s->threshold = value & 3;
244
+ } else if (addr_between(addr, s->claim_base, 1)) {
245
+ if (s->claim == value) {
246
+ /* Interrupt was completed */
247
+ s->claim = 0;
248
+ }
249
+ }
250
+
251
+ ibex_plic_update(s);
252
+}
253
+
254
+static const MemoryRegionOps ibex_plic_ops = {
255
+ .read = ibex_plic_read,
256
+ .write = ibex_plic_write,
257
+ .endianness = DEVICE_NATIVE_ENDIAN,
258
+ .valid = {
259
+ .min_access_size = 4,
260
+ .max_access_size = 4
261
+ }
262
+};
263
+
264
+static void ibex_plic_irq_request(void *opaque, int irq, int level)
265
+{
266
+ IbexPlicState *s = opaque;
267
+
268
+ ibex_plic_irqs_set_pending(s, irq, level > 0);
269
+ ibex_plic_update(s);
270
+}
271
+
272
+static Property ibex_plic_properties[] = {
273
+ DEFINE_PROP_UINT32("num-cpus", IbexPlicState, num_cpus, 1),
274
+ DEFINE_PROP_UINT32("num-sources", IbexPlicState, num_sources, 80),
275
+
276
+ DEFINE_PROP_UINT32("pending-base", IbexPlicState, pending_base, 0),
277
+ DEFINE_PROP_UINT32("pending-num", IbexPlicState, pending_num, 3),
278
+
279
+ DEFINE_PROP_UINT32("source-base", IbexPlicState, source_base, 0x0c),
280
+ DEFINE_PROP_UINT32("source-num", IbexPlicState, source_num, 3),
281
+
282
+ DEFINE_PROP_UINT32("priority-base", IbexPlicState, priority_base, 0x18),
283
+ DEFINE_PROP_UINT32("priority-num", IbexPlicState, priority_num, 80),
284
+
285
+ DEFINE_PROP_UINT32("enable-base", IbexPlicState, enable_base, 0x200),
286
+ DEFINE_PROP_UINT32("enable-num", IbexPlicState, enable_num, 3),
287
+
288
+ DEFINE_PROP_UINT32("threshold-base", IbexPlicState, threshold_base, 0x20c),
289
+
290
+ DEFINE_PROP_UINT32("claim-base", IbexPlicState, claim_base, 0x210),
291
+ DEFINE_PROP_END_OF_LIST(),
292
+};
293
+
294
+static void ibex_plic_init(Object *obj)
295
+{
296
+ IbexPlicState *s = IBEX_PLIC(obj);
297
+
298
+ memory_region_init_io(&s->mmio, obj, &ibex_plic_ops, s,
299
+ TYPE_IBEX_PLIC, 0x400);
300
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
301
+}
302
+
303
+static void ibex_plic_realize(DeviceState *dev, Error **errp)
304
+{
305
+ IbexPlicState *s = IBEX_PLIC(dev);
306
+ int i;
307
+
308
+ s->pending = g_new0(uint32_t, s->pending_num);
309
+ s->source = g_new0(uint32_t, s->source_num);
310
+ s->priority = g_new0(uint32_t, s->priority_num);
311
+ s->enable = g_new0(uint32_t, s->enable_num);
312
+
313
+ qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
314
+
315
+ /*
316
+ * We can't allow the supervisor to control SEIP as this would allow the
317
+ * supervisor to clear a pending external interrupt which will result in
318
+ * a lost interrupt in the case a PLIC is attached. The SEIP bit must be
319
+ * hardware controlled when a PLIC is attached.
320
+ */
321
+ MachineState *ms = MACHINE(qdev_get_machine());
322
+ unsigned int smp_cpus = ms->smp.cpus;
323
+ for (i = 0; i < smp_cpus; i++) {
324
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
325
+ if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
326
+ error_report("SEIP already claimed");
327
+ exit(1);
328
+ }
329
+ }
330
+
331
+ msi_nonbroken = true;
332
+}
333
+
334
+static void ibex_plic_class_init(ObjectClass *klass, void *data)
335
+{
336
+ DeviceClass *dc = DEVICE_CLASS(klass);
337
+
338
+ dc->reset = ibex_plic_reset;
339
+ device_class_set_props(dc, ibex_plic_properties);
340
+ dc->realize = ibex_plic_realize;
341
+}
342
+
343
+static const TypeInfo ibex_plic_info = {
344
+ .name = TYPE_IBEX_PLIC,
345
+ .parent = TYPE_SYS_BUS_DEVICE,
346
+ .instance_size = sizeof(IbexPlicState),
347
+ .instance_init = ibex_plic_init,
348
+ .class_init = ibex_plic_class_init,
349
+};
350
+
351
+static void ibex_plic_register_types(void)
352
+{
353
+ type_register_static(&ibex_plic_info);
354
+}
355
+
356
+type_init(ibex_plic_register_types)
357
diff --git a/MAINTAINERS b/MAINTAINERS
358
index XXXXXXX..XXXXXXX 100644
359
--- a/MAINTAINERS
360
+++ b/MAINTAINERS
361
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
362
S: Supported
363
F: hw/riscv/opentitan.c
364
F: hw/char/ibex_uart.c
365
+F: hw/intc/ibex_plic.c
366
F: include/hw/riscv/opentitan.h
367
F: include/hw/char/ibex_uart.h
368
+F: include/hw/intc/ibex_plic.h
369
370
SH4 Machines
371
------------
372
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
373
index XXXXXXX..XXXXXXX 100644
374
--- a/hw/intc/Makefile.objs
375
+++ b/hw/intc/Makefile.objs
376
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
377
obj-$(CONFIG_MIPS_CPS) += mips_gic.o
378
obj-$(CONFIG_NIOS2) += nios2_iic.o
379
obj-$(CONFIG_OMPIC) += ompic.o
380
+obj-$(CONFIG_IBEX) += ibex_plic.o
381
--
188
--
382
2.27.0
189
2.48.1
383
384
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
This was done in the virt & sifive_u codes, but opentitan codes were
3
Because the RNMI interrupt trap handler address is implementation defined.
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
4
We add the 'rnmi-interrupt-vector' and 'rnmi-exception-vector' as the property
5
5
of the harts. It’s very easy for users to set the address based on their
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
expectation. This patch also adds the functionality to handle the RNMI signals.
7
8
Signed-off-by: Frank Chang <frank.chang@sifive.com>
9
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591625864-31494-3-git-send-email-bmeng.cn@gmail.com
12
Message-ID: <20250106054336.1878291-4-frank.chang@sifive.com>
9
Message-Id: <1591625864-31494-3-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
14
---
12
hw/riscv/opentitan.c | 29 ++++++++++++++---------------
15
include/hw/riscv/riscv_hart.h | 4 ++
13
1 file changed, 14 insertions(+), 15 deletions(-)
16
target/riscv/cpu.h | 3 ++
14
17
target/riscv/cpu_bits.h | 12 +++++
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
18
hw/riscv/riscv_hart.c | 41 ++++++++++++++++
16
index XXXXXXX..XXXXXXX 100644
19
target/riscv/cpu.c | 11 +++++
17
--- a/hw/riscv/opentitan.c
20
target/riscv/cpu_helper.c | 88 ++++++++++++++++++++++++++++++++---
18
+++ b/hw/riscv/opentitan.c
21
6 files changed, 152 insertions(+), 7 deletions(-)
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
22
20
[IBEX_PADCTRL] = { 0x40160000, 0x10000 }
23
diff --git a/include/hw/riscv/riscv_hart.h b/include/hw/riscv/riscv_hart.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/riscv_hart.h
26
+++ b/include/hw/riscv/riscv_hart.h
27
@@ -XXX,XX +XXX,XX @@ struct RISCVHartArrayState {
28
uint32_t hartid_base;
29
char *cpu_type;
30
uint64_t resetvec;
31
+ uint32_t num_rnmi_irqvec;
32
+ uint64_t *rnmi_irqvec;
33
+ uint32_t num_rnmi_excpvec;
34
+ uint64_t *rnmi_excpvec;
35
RISCVCPU *harts;
21
};
36
};
22
37
23
-static void riscv_opentitan_init(MachineState *machine)
38
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
+static void opentitan_board_init(MachineState *machine)
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu.h
41
+++ b/target/riscv/cpu.h
42
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
43
target_ulong mncause; /* mncause without bit XLEN-1 set to 1 */
44
target_ulong mnstatus;
45
target_ulong rnmip;
46
+ uint64_t rnmi_irqvec;
47
+ uint64_t rnmi_excpvec;
48
};
49
50
/*
51
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env);
52
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts);
53
uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask,
54
uint64_t value);
55
+void riscv_cpu_set_rnmi(RISCVCPU *cpu, uint32_t irq, bool level);
56
void riscv_cpu_interrupt(CPURISCVState *env);
57
#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
58
void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *),
59
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
60
index XXXXXXX..XXXXXXX 100644
61
--- a/target/riscv/cpu_bits.h
62
+++ b/target/riscv/cpu_bits.h
63
@@ -XXX,XX +XXX,XX @@ typedef enum {
64
/* Default Reset Vector address */
65
#define DEFAULT_RSTVEC 0x1000
66
67
+/* Default RNMI Interrupt Vector address */
68
+#define DEFAULT_RNMI_IRQVEC 0x0
69
+
70
+/* Default RNMI Exception Vector address */
71
+#define DEFAULT_RNMI_EXCPVEC 0x0
72
+
73
/* Exception causes */
74
typedef enum RISCVException {
75
RISCV_EXCP_NONE = -1, /* sentinel value */
76
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
77
/* -1 is due to bit zero of hgeip and hgeie being ROZ. */
78
#define IRQ_LOCAL_GUEST_MAX (TARGET_LONG_BITS - 1)
79
80
+/* RNMI causes */
81
+#define RNMI_MAX 16
82
+
83
/* mip masks */
84
#define MIP_USIP (1 << IRQ_U_SOFT)
85
#define MIP_SSIP (1 << IRQ_S_SOFT)
86
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
87
#define MHPMEVENT_IDX_MASK 0xFFFFF
88
#define MHPMEVENT_SSCOF_RESVD 16
89
90
+/* RISC-V-specific interrupt pending bits. */
91
+#define CPU_INTERRUPT_RNMI CPU_INTERRUPT_TGT_EXT_0
92
+
93
/* JVT CSR bits */
94
#define JVT_MODE 0x3F
95
#define JVT_BASE (~0x3F)
96
diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
97
index XXXXXXX..XXXXXXX 100644
98
--- a/hw/riscv/riscv_hart.c
99
+++ b/hw/riscv/riscv_hart.c
100
@@ -XXX,XX +XXX,XX @@
101
#include "target/riscv/cpu.h"
102
#include "hw/qdev-properties.h"
103
#include "hw/riscv/riscv_hart.h"
104
+#include "qemu/error-report.h"
105
106
static const Property riscv_harts_props[] = {
107
DEFINE_PROP_UINT32("num-harts", RISCVHartArrayState, num_harts, 1),
108
@@ -XXX,XX +XXX,XX @@ static const Property riscv_harts_props[] = {
109
DEFINE_PROP_STRING("cpu-type", RISCVHartArrayState, cpu_type),
110
DEFINE_PROP_UINT64("resetvec", RISCVHartArrayState, resetvec,
111
DEFAULT_RSTVEC),
112
+
113
+ /*
114
+ * Smrnmi implementation-defined interrupt and exception trap handlers.
115
+ *
116
+ * When an RNMI interrupt is detected, the hart then enters M-mode and
117
+ * jumps to the address defined by "rnmi-interrupt-vector".
118
+ *
119
+ * When the hart encounters an exception while executing in M-mode with
120
+ * the mnstatus.NMIE bit clear, the hart then jumps to the address
121
+ * defined by "rnmi-exception-vector".
122
+ */
123
+ DEFINE_PROP_ARRAY("rnmi-interrupt-vector", RISCVHartArrayState,
124
+ num_rnmi_irqvec, rnmi_irqvec, qdev_prop_uint64,
125
+ uint64_t),
126
+ DEFINE_PROP_ARRAY("rnmi-exception-vector", RISCVHartArrayState,
127
+ num_rnmi_excpvec, rnmi_excpvec, qdev_prop_uint64,
128
+ uint64_t),
129
};
130
131
static void riscv_harts_cpu_reset(void *opaque)
132
@@ -XXX,XX +XXX,XX @@ static bool riscv_hart_realize(RISCVHartArrayState *s, int idx,
25
{
133
{
26
const struct MemmapEntry *memmap = ibex_memmap;
134
object_initialize_child(OBJECT(s), "harts[*]", &s->harts[idx], cpu_type);
27
OpenTitanState *s = g_new0(OpenTitanState, 1);
135
qdev_prop_set_uint64(DEVICE(&s->harts[idx]), "resetvec", s->resetvec);
28
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
136
+
29
memory_region_add_subregion(sys_mem,
137
+ if (s->harts[idx].cfg.ext_smrnmi) {
30
memmap[IBEX_RAM].base, main_mem);
138
+ if (idx < s->num_rnmi_irqvec) {
31
139
+ qdev_prop_set_uint64(DEVICE(&s->harts[idx]),
32
-
140
+ "rnmi-interrupt-vector", s->rnmi_irqvec[idx]);
33
if (machine->firmware) {
141
+ }
34
riscv_load_firmware(machine->firmware, memmap[IBEX_RAM].base, NULL);
142
+
35
}
143
+ if (idx < s->num_rnmi_excpvec) {
36
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
144
+ qdev_prop_set_uint64(DEVICE(&s->harts[idx]),
145
+ "rnmi-exception-vector", s->rnmi_excpvec[idx]);
146
+ }
147
+ } else {
148
+ if (s->num_rnmi_irqvec > 0) {
149
+ warn_report_once("rnmi-interrupt-vector property is ignored "
150
+ "because Smrnmi extension is not enabled.");
151
+ }
152
+
153
+ if (s->num_rnmi_excpvec > 0) {
154
+ warn_report_once("rnmi-exception-vector property is ignored "
155
+ "because Smrnmi extension is not enabled.");
156
+ }
157
+ }
158
+
159
s->harts[idx].env.mhartid = s->hartid_base + idx;
160
qemu_register_reset(riscv_harts_cpu_reset, &s->harts[idx]);
161
return qdev_realize(DEVICE(&s->harts[idx]), NULL, errp);
162
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
163
index XXXXXXX..XXXXXXX 100644
164
--- a/target/riscv/cpu.c
165
+++ b/target/riscv/cpu.c
166
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
167
g_assert_not_reached();
37
}
168
}
38
}
169
}
39
170
+
40
-static void riscv_opentitan_machine_init(MachineClass *mc)
171
+static void riscv_cpu_set_nmi(void *opaque, int irq, int level)
41
+static void opentitan_machine_init(MachineClass *mc)
172
+{
173
+ riscv_cpu_set_rnmi(RISCV_CPU(opaque), irq, level);
174
+}
175
#endif /* CONFIG_USER_ONLY */
176
177
static bool riscv_cpu_is_dynamic(Object *cpu_obj)
178
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_init(Object *obj)
179
#ifndef CONFIG_USER_ONLY
180
qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
181
IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
182
+ qdev_init_gpio_in_named(DEVICE(cpu), riscv_cpu_set_nmi,
183
+ "riscv.cpu.rnmi", RNMI_MAX);
184
#endif /* CONFIG_USER_ONLY */
185
186
general_user_opts = g_hash_table_new(g_str_hash, g_str_equal);
187
@@ -XXX,XX +XXX,XX @@ static const Property riscv_cpu_properties[] = {
188
189
#ifndef CONFIG_USER_ONLY
190
DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
191
+ DEFINE_PROP_UINT64("rnmi-interrupt-vector", RISCVCPU, env.rnmi_irqvec,
192
+ DEFAULT_RNMI_IRQVEC),
193
+ DEFINE_PROP_UINT64("rnmi-exception-vector", RISCVCPU, env.rnmi_excpvec,
194
+ DEFAULT_RNMI_EXCPVEC),
195
#endif
196
197
DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
198
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
199
index XXXXXXX..XXXXXXX 100644
200
--- a/target/riscv/cpu_helper.c
201
+++ b/target/riscv/cpu_helper.c
202
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
203
uint64_t vsbits, irq_delegated;
204
int virq;
205
206
+ /* Priority: RNMI > Other interrupt. */
207
+ if (riscv_cpu_cfg(env)->ext_smrnmi) {
208
+ /* If mnstatus.NMIE == 0, all interrupts are disabled. */
209
+ if (!get_field(env->mnstatus, MNSTATUS_NMIE)) {
210
+ return RISCV_EXCP_NONE;
211
+ }
212
+
213
+ if (env->rnmip) {
214
+ return ctz64(env->rnmip); /* since non-zero */
215
+ }
216
+ }
217
+
218
/* Determine interrupt enable state of all privilege modes */
219
if (env->virt_enabled) {
220
mie = 1;
221
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
222
223
bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
42
{
224
{
43
mc->desc = "RISC-V Board compatible with OpenTitan";
225
- if (interrupt_request & CPU_INTERRUPT_HARD) {
44
- mc->init = riscv_opentitan_init;
226
+ uint32_t mask = CPU_INTERRUPT_HARD | CPU_INTERRUPT_RNMI;
45
+ mc->init = opentitan_board_init;
227
+
46
mc->max_cpus = 1;
228
+ if (interrupt_request & mask) {
47
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
229
RISCVCPU *cpu = RISCV_CPU(cs);
230
CPURISCVState *env = &cpu->env;
231
int interruptno = riscv_cpu_local_irq_pending(env);
232
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_geilen(CPURISCVState *env, target_ulong geilen)
233
env->geilen = geilen;
48
}
234
}
49
235
50
-DEFINE_MACHINE("opentitan", riscv_opentitan_machine_init)
236
+void riscv_cpu_set_rnmi(RISCVCPU *cpu, uint32_t irq, bool level)
51
+DEFINE_MACHINE("opentitan", opentitan_machine_init)
237
+{
52
238
+ CPURISCVState *env = &cpu->env;
53
-static void riscv_lowrisc_ibex_soc_init(Object *obj)
239
+ CPUState *cs = CPU(cpu);
54
+static void lowrisc_ibex_soc_init(Object *obj)
240
+ bool release_lock = false;
241
+
242
+ if (!bql_locked()) {
243
+ release_lock = true;
244
+ bql_lock();
245
+ }
246
+
247
+ if (level) {
248
+ env->rnmip |= 1 << irq;
249
+ cpu_interrupt(cs, CPU_INTERRUPT_RNMI);
250
+ } else {
251
+ env->rnmip &= ~(1 << irq);
252
+ cpu_reset_interrupt(cs, CPU_INTERRUPT_RNMI);
253
+ }
254
+
255
+ if (release_lock) {
256
+ bql_unlock();
257
+ }
258
+}
259
+
260
int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts)
55
{
261
{
56
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
262
CPURISCVState *env = &cpu->env;
57
263
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
264
bool write_gva = false;
59
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
265
bool always_storeamo = (env->excp_uw2 & RISCV_UW2_ALWAYS_STORE_AMO);
60
}
266
uint64_t s;
61
267
+ int mode;
62
-static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
268
63
+static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
269
/*
64
{
270
* cs->exception is 32-bits wide unlike mcause which is XLEN-bits wide
65
const struct MemmapEntry *memmap = ibex_memmap;
271
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
66
MachineState *ms = MACHINE(qdev_get_machine());
272
target_ulong htval = 0;
67
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
273
target_ulong mtval2 = 0;
68
memmap[IBEX_PADCTRL].base, memmap[IBEX_PADCTRL].size);
274
int sxlen = 0;
69
}
275
- int mxlen = 0;
70
276
+ int mxlen = 16 << riscv_cpu_mxl(env);
71
-static void riscv_lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
277
+ bool nnmi_excep = false;
72
+static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
278
+
73
{
279
+ if (cpu->cfg.ext_smrnmi && env->rnmip && async) {
74
DeviceClass *dc = DEVICE_CLASS(oc);
280
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, false);
75
281
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPV,
76
- dc->realize = riscv_lowrisc_ibex_soc_realize;
282
+ env->virt_enabled);
77
+ dc->realize = lowrisc_ibex_soc_realize;
283
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPP,
78
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
284
+ env->priv);
79
dc->user_creatable = false;
285
+ env->mncause = cause | ((target_ulong)1U << (mxlen - 1));
80
}
286
+ env->mnepc = env->pc;
81
287
+ env->pc = env->rnmi_irqvec;
82
-static const TypeInfo riscv_lowrisc_ibex_soc_type_info = {
288
+
83
+static const TypeInfo lowrisc_ibex_soc_type_info = {
289
+ /* Trapping to M mode, virt is disabled */
84
.name = TYPE_RISCV_IBEX_SOC,
290
+ riscv_cpu_set_mode(env, PRV_M, false);
85
.parent = TYPE_DEVICE,
291
+
86
.instance_size = sizeof(LowRISCIbexSoCState),
292
+ return;
87
- .instance_init = riscv_lowrisc_ibex_soc_init,
293
+ }
88
- .class_init = riscv_lowrisc_ibex_soc_class_init,
294
89
+ .instance_init = lowrisc_ibex_soc_init,
295
if (!async) {
90
+ .class_init = lowrisc_ibex_soc_class_init,
296
/* set tval to badaddr for traps with address information */
91
};
297
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
92
298
__func__, env->mhartid, async, cause, env->pc, tval,
93
-static void riscv_lowrisc_ibex_soc_register_types(void)
299
riscv_cpu_get_trap_name(cause, async));
94
+static void lowrisc_ibex_soc_register_types(void)
300
95
{
301
- if (env->priv <= PRV_S && cause < 64 &&
96
- type_register_static(&riscv_lowrisc_ibex_soc_type_info);
302
- (((deleg >> cause) & 1) || s_injected || vs_injected)) {
97
+ type_register_static(&lowrisc_ibex_soc_type_info);
303
+ mode = env->priv <= PRV_S && cause < 64 &&
98
}
304
+ (((deleg >> cause) & 1) || s_injected || vs_injected) ? PRV_S : PRV_M;
99
305
+
100
-type_init(riscv_lowrisc_ibex_soc_register_types)
306
+ if (mode == PRV_S) {
101
+type_init(lowrisc_ibex_soc_register_types)
307
/* handle the trap in S-mode */
308
/* save elp status */
309
if (cpu_get_fcfien(env)) {
310
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
311
((async && (env->stvec & 3) == 1) ? cause * 4 : 0);
312
riscv_cpu_set_mode(env, PRV_S, virt);
313
} else {
314
+ /*
315
+ * If the hart encounters an exception while executing in M-mode
316
+ * with the mnstatus.NMIE bit clear, the exception is an RNMI exception.
317
+ */
318
+ nnmi_excep = cpu->cfg.ext_smrnmi &&
319
+ !get_field(env->mnstatus, MNSTATUS_NMIE) &&
320
+ !async;
321
+
322
/* handle the trap in M-mode */
323
/* save elp status */
324
if (cpu_get_fcfien(env)) {
325
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
326
s = set_field(s, MSTATUS_MPP, env->priv);
327
s = set_field(s, MSTATUS_MIE, 0);
328
env->mstatus = s;
329
- mxlen = 16 << riscv_cpu_mxl(env);
330
env->mcause = cause | ((target_ulong)async << (mxlen - 1));
331
env->mepc = env->pc;
332
env->mtval = tval;
333
env->mtval2 = mtval2;
334
env->mtinst = tinst;
335
- env->pc = (env->mtvec >> 2 << 2) +
336
- ((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
337
+
338
+ /*
339
+ * For RNMI exception, program counter is set to the RNMI exception
340
+ * trap handler address.
341
+ */
342
+ if (nnmi_excep) {
343
+ env->pc = env->rnmi_excpvec;
344
+ } else {
345
+ env->pc = (env->mtvec >> 2 << 2) +
346
+ ((async && (env->mtvec & 3) == 1) ? cause * 4 : 0);
347
+ }
348
riscv_cpu_set_mode(env, PRV_M, virt);
349
}
350
102
--
351
--
103
2.27.0
352
2.48.1
104
353
105
354
diff view generated by jsdifflib
1
Call the helper_hyp_tlb_flush() function on hfence instructions which
1
From: Tommy Wu <tommy.wu@sifive.com>
2
will generate an illegal insruction execption if we don't have
3
permission to flush the Hypervisor level TLBs.
4
2
3
This patch adds a new instruction 'mnret'. 'mnret' is an M-mode-only
4
instruction that uses the values in `mnepc` and `mnstatus` to return to the
5
program counter, privilege mode, and virtualization mode of the
6
interrupted context.
7
8
Signed-off-by: Frank Chang <frank.chang@sifive.com>
9
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-ID: <20250106054336.1878291-5-frank.chang@sifive.com>
5
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
---
14
---
8
target/riscv/helper.h | 5 ++++
15
target/riscv/helper.h | 1 +
9
target/riscv/insn_trans/trans_rvh.inc.c | 32 +++++--------------------
16
target/riscv/insn32.decode | 3 ++
10
target/riscv/op_helper.c | 13 ++++++++++
17
target/riscv/op_helper.c | 45 ++++++++++++++++---
11
3 files changed, 24 insertions(+), 26 deletions(-)
18
.../riscv/insn_trans/trans_privileged.c.inc | 20 +++++++++
19
4 files changed, 64 insertions(+), 5 deletions(-)
12
20
13
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
21
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
14
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/helper.h
23
--- a/target/riscv/helper.h
16
+++ b/target/riscv/helper.h
24
+++ b/target/riscv/helper.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(mret, tl, env, tl)
25
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
26
#ifndef CONFIG_USER_ONLY
27
DEF_HELPER_1(sret, tl, env)
28
DEF_HELPER_1(mret, tl, env)
29
+DEF_HELPER_1(mnret, tl, env)
18
DEF_HELPER_1(wfi, void, env)
30
DEF_HELPER_1(wfi, void, env)
31
DEF_HELPER_1(wrs_nto, void, env)
19
DEF_HELPER_1(tlb_flush, void, env)
32
DEF_HELPER_1(tlb_flush, void, env)
20
#endif
33
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/insn32.decode
36
+++ b/target/riscv/insn32.decode
37
@@ -XXX,XX +XXX,XX @@ wfi 0001000 00101 00000 000 00000 1110011
38
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
39
sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
40
41
+# *** NMI ***
42
+mnret 0111000 00010 00000 000 00000 1110011
21
+
43
+
22
+/* Hypervisor functions */
44
# *** RV32I Base Instruction Set ***
23
+#ifndef CONFIG_USER_ONLY
45
lui .................... ..... 0110111 @u
24
+DEF_HELPER_1(hyp_tlb_flush, void, env)
25
+#endif
26
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/insn_trans/trans_rvh.inc.c
29
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
30
@@ -XXX,XX +XXX,XX @@
31
32
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
33
{
46
{
34
+ REQUIRE_EXT(ctx, RVH);
35
#ifndef CONFIG_USER_ONLY
36
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
37
- has_ext(ctx, RVH)) {
38
- /* Hpervisor extensions exist */
39
- /*
40
- * if (env->priv == PRV_M ||
41
- * (env->priv == PRV_S &&
42
- * !riscv_cpu_virt_enabled(env) &&
43
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
44
- */
45
- gen_helper_tlb_flush(cpu_env);
46
- return true;
47
- /* } */
48
- }
49
+ gen_helper_hyp_tlb_flush(cpu_env);
50
+ return true;
51
#endif
52
return false;
53
}
54
55
static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
56
{
57
+ REQUIRE_EXT(ctx, RVH);
58
#ifndef CONFIG_USER_ONLY
59
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
60
- has_ext(ctx, RVH)) {
61
- /* Hpervisor extensions exist */
62
- /*
63
- * if (env->priv == PRV_M ||
64
- * (env->priv == PRV_S &&
65
- * !riscv_cpu_virt_enabled(env) &&
66
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
67
- */
68
- gen_helper_tlb_flush(cpu_env);
69
- return true;
70
- /* } */
71
- }
72
+ gen_helper_hyp_tlb_flush(cpu_env);
73
+ return true;
74
#endif
75
return false;
76
}
77
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
47
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
78
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/op_helper.c
49
--- a/target/riscv/op_helper.c
80
+++ b/target/riscv/op_helper.c
50
+++ b/target/riscv/op_helper.c
81
@@ -XXX,XX +XXX,XX @@ void helper_tlb_flush(CPURISCVState *env)
51
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
52
return retpc;
53
}
54
55
-target_ulong helper_mret(CPURISCVState *env)
56
+static void check_ret_from_m_mode(CPURISCVState *env, target_ulong retpc,
57
+ target_ulong prev_priv)
58
{
59
if (!(env->priv >= PRV_M)) {
60
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
82
}
61
}
62
63
- target_ulong retpc = env->mepc;
64
if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
65
riscv_raise_exception(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
66
}
67
68
- uint64_t mstatus = env->mstatus;
69
- target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
70
-
71
if (riscv_cpu_cfg(env)->pmp &&
72
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
73
riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
74
}
75
+}
76
+
77
+target_ulong helper_mret(CPURISCVState *env)
78
+{
79
+ target_ulong retpc = env->mepc;
80
+ uint64_t mstatus = env->mstatus;
81
+ target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
82
+
83
+ check_ret_from_m_mode(env, retpc, prev_priv);
84
85
target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV) &&
86
(prev_priv != PRV_M);
87
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
88
return retpc;
83
}
89
}
84
90
85
+void helper_hyp_tlb_flush(CPURISCVState *env)
91
+target_ulong helper_mnret(CPURISCVState *env)
86
+{
92
+{
87
+ CPUState *cs = env_cpu(env);
93
+ target_ulong retpc = env->mnepc;
94
+ target_ulong prev_priv = get_field(env->mnstatus, MNSTATUS_MNPP);
95
+ target_ulong prev_virt;
88
+
96
+
89
+ if (env->priv == PRV_M ||
97
+ check_ret_from_m_mode(env, retpc, prev_priv);
90
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env))) {
98
+
91
+ tlb_flush(cs);
99
+ prev_virt = get_field(env->mnstatus, MNSTATUS_MNPV) &&
92
+ return;
100
+ (prev_priv != PRV_M);
101
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, true);
102
+
103
+ /*
104
+ * If MNRET changes the privilege mode to a mode
105
+ * less privileged than M, it also sets mstatus.MPRV to 0.
106
+ */
107
+ if (prev_priv < PRV_M) {
108
+ env->mstatus = set_field(env->mstatus, MSTATUS_MPRV, false);
93
+ }
109
+ }
94
+
110
+
95
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
111
+ if (riscv_has_ext(env, RVH) && prev_virt) {
112
+ riscv_cpu_swap_hypervisor_regs(env);
113
+ }
114
+
115
+ riscv_cpu_set_mode(env, prev_priv, prev_virt);
116
+
117
+ return retpc;
96
+}
118
+}
97
+
119
+
98
#endif /* !CONFIG_USER_ONLY */
120
void helper_wfi(CPURISCVState *env)
121
{
122
CPUState *cs = env_cpu(env);
123
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
124
index XXXXXXX..XXXXXXX 100644
125
--- a/target/riscv/insn_trans/trans_privileged.c.inc
126
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
127
@@ -XXX,XX +XXX,XX @@
128
* this program. If not, see <http://www.gnu.org/licenses/>.
129
*/
130
131
+#define REQUIRE_SMRNMI(ctx) do { \
132
+ if (!ctx->cfg_ptr->ext_smrnmi) { \
133
+ return false; \
134
+ } \
135
+} while (0)
136
+
137
static bool trans_ecall(DisasContext *ctx, arg_ecall *a)
138
{
139
/* always generates U-level ECALL, fixed in do_interrupt handler */
140
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
141
#endif
142
}
143
144
+static bool trans_mnret(DisasContext *ctx, arg_mnret *a)
145
+{
146
+#ifndef CONFIG_USER_ONLY
147
+ REQUIRE_SMRNMI(ctx);
148
+ decode_save_opc(ctx, 0);
149
+ gen_helper_mnret(cpu_pc, tcg_env);
150
+ tcg_gen_exit_tb(NULL, 0); /* no chaining */
151
+ ctx->base.is_jmp = DISAS_NORETURN;
152
+ return true;
153
+#else
154
+ return false;
155
+#endif
156
+}
157
+
158
static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
159
{
160
#ifndef CONFIG_USER_ONLY
99
--
161
--
100
2.27.0
162
2.48.1
101
102
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Tommy Wu <tommy.wu@sifive.com>
2
2
3
Adding a _ to keep some consistency among the CPU init routines.
3
This adds the properties for ISA extension Smrnmi.
4
4
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
5
Also, when Smrnmi is present, the firmware (e.g., OpenSBI) must set
6
mnstatus.NMIE to 1 before enabling any interrupts. Otherwise, all
7
interrupts will be disabled. Since our current OpenSBI does not
8
support Smrnmi yet, let's disable Smrnmi for the 'max' type CPU for
9
now. We can re-enable it once OpenSBI includes proper support for it.
10
11
Signed-off-by: Frank Chang <frank.chang@sifive.com>
12
Signed-off-by: Tommy Wu <tommy.wu@sifive.com>
13
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <1591837729-27486-4-git-send-email-bmeng.cn@gmail.com>
16
Message-ID: <20250106054336.1878291-6-frank.chang@sifive.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
18
---
10
target/riscv/cpu.c | 8 ++++----
19
target/riscv/cpu.c | 2 ++
11
1 file changed, 4 insertions(+), 4 deletions(-)
20
target/riscv/tcg/tcg-cpu.c | 9 +++++++++
21
2 files changed, 11 insertions(+)
12
22
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
14
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.c
25
--- a/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
26
+++ b/target/riscv/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
27
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
18
28
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
19
#if defined(TARGET_RISCV32)
29
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
20
30
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
21
-static void rv32imcu_nommu_cpu_init(Object *obj)
31
+ ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
22
+static void rv32_imcu_nommu_cpu_init(Object *obj)
32
ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
23
{
33
ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
24
CPURISCVState *env = &RISCV_CPU(obj)->env;
34
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
25
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
35
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
26
@@ -XXX,XX +XXX,XX @@ static void rv32imcu_nommu_cpu_init(Object *obj)
36
27
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
37
MULTI_EXT_CFG_BOOL("smaia", ext_smaia, false),
38
MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
39
+ MULTI_EXT_CFG_BOOL("smrnmi", ext_smrnmi, false),
40
MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false),
41
MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false),
42
MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
43
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/tcg/tcg-cpu.c
46
+++ b/target/riscv/tcg/tcg-cpu.c
47
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
48
if (env->misa_mxl != MXL_RV32) {
49
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcf), false);
50
}
51
+
52
+ /*
53
+ * ext_smrnmi requires OpenSBI changes that our current
54
+ * image does not have. Disable it for now.
55
+ */
56
+ if (cpu->cfg.ext_smrnmi) {
57
+ isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_smrnmi), false);
58
+ qemu_log("Smrnmi is disabled in the 'max' type CPU\n");
59
+ }
28
}
60
}
29
61
30
-static void rv32imafcu_nommu_cpu_init(Object *obj)
62
static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
31
+static void rv32_imafcu_nommu_cpu_init(Object *obj)
32
{
33
CPURISCVState *env = &RISCV_CPU(obj)->env;
34
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
35
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
36
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
37
#if defined(TARGET_RISCV32)
38
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
39
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
40
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
41
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
42
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
43
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
44
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
45
#elif defined(TARGET_RISCV64)
46
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
47
--
63
--
48
2.27.0
64
2.48.1
49
50
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
2
3
Zicfilp extension introduces the MNPELP (bit 9) in mnstatus.
4
The MNPELP field holds the previous ELP.
5
6
When a RNMI trap is delivered, the MNPELP is set to ELP and ELP set
7
to NO_LP_EXPECTED. Upon a mnret, if the mnstatus.MNPP holds the
8
value y, then ELP is set to the value of MNPELP if yLPE is 1;
9
otherwise, it is set to NO_LP_EXPECTED.
10
11
Signed-off-by: Frank Chang <frank.chang@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20250106054336.1878291-7-frank.chang@sifive.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
16
---
5
include/hw/riscv/opentitan.h | 3 +++
17
target/riscv/cpu_bits.h | 1 +
6
hw/riscv/opentitan.c | 14 ++++++++++++--
18
target/riscv/cpu_helper.c | 11 ++++++++++-
7
2 files changed, 15 insertions(+), 2 deletions(-)
19
target/riscv/op_helper.c | 9 +++++++++
20
3 files changed, 20 insertions(+), 1 deletion(-)
8
21
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
22
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
10
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
24
--- a/target/riscv/cpu_bits.h
12
+++ b/include/hw/riscv/opentitan.h
25
+++ b/target/riscv/cpu_bits.h
13
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ typedef enum {
14
#define HW_OPENTITAN_H
27
/* RNMI mnstatus CSR mask */
15
28
#define MNSTATUS_NMIE 0x00000008
16
#include "hw/riscv/riscv_hart.h"
29
#define MNSTATUS_MNPV 0x00000080
17
+#include "hw/intc/ibex_plic.h"
30
+#define MNSTATUS_MNPELP 0x00000200
18
31
#define MNSTATUS_MNPP 0x00001800
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
32
20
#define RISCV_IBEX_SOC(obj) \
33
/* VM modes (satp.mode) privileged ISA 1.10 */
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
34
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
22
35
index XXXXXXX..XXXXXXX 100644
23
/*< public >*/
36
--- a/target/riscv/cpu_helper.c
24
RISCVHartArrayState cpus;
37
+++ b/target/riscv/cpu_helper.c
25
+ IbexPlicState plic;
38
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
39
env->mnepc = env->pc;
40
env->pc = env->rnmi_irqvec;
41
42
+ if (cpu_get_fcfien(env)) {
43
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPELP, env->elp);
44
+ }
26
+
45
+
27
MemoryRegion flash_mem;
46
/* Trapping to M mode, virt is disabled */
28
MemoryRegion rom;
47
riscv_cpu_set_mode(env, PRV_M, false);
29
} LowRISCIbexSoCState;
48
30
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
49
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
50
/* handle the trap in M-mode */
51
/* save elp status */
52
if (cpu_get_fcfien(env)) {
53
- env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, env->elp);
54
+ if (nnmi_excep) {
55
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPELP,
56
+ env->elp);
57
+ } else {
58
+ env->mstatus = set_field(env->mstatus, MSTATUS_MPELP, env->elp);
59
+ }
60
}
61
62
if (riscv_has_ext(env, RVH)) {
63
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
31
index XXXXXXX..XXXXXXX 100644
64
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/opentitan.c
65
--- a/target/riscv/op_helper.c
33
+++ b/hw/riscv/opentitan.c
66
+++ b/target/riscv/op_helper.c
34
@@ -XXX,XX +XXX,XX @@
67
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mnret(CPURISCVState *env)
35
#include "hw/riscv/boot.h"
68
36
#include "exec/address-spaces.h"
69
riscv_cpu_set_mode(env, prev_priv, prev_virt);
37
#include "qemu/units.h"
70
38
+#include "sysemu/sysemu.h"
71
+ /*
39
72
+ * If forward cfi enabled for new priv, restore elp status
40
static const struct MemmapEntry {
73
+ * and clear mnpelp in mnstatus
41
hwaddr base;
74
+ */
42
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
75
+ if (cpu_get_fcfien(env)) {
43
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
76
+ env->elp = get_field(env->mnstatus, MNSTATUS_MNPELP);
44
77
+ }
45
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
78
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPELP, 0);
46
+
79
+
47
+ object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
80
return retpc;
48
}
81
}
49
82
50
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
51
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
52
MachineState *ms = MACHINE(qdev_get_machine());
53
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
54
MemoryRegion *sys_mem = get_system_memory();
55
+ Error *err = NULL;
56
57
object_property_set_str(OBJECT(&s->cpus), ms->cpu_type, "cpu-type",
58
&error_abort);
59
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
60
memory_region_add_subregion(sys_mem, memmap[IBEX_FLASH].base,
61
&s->flash_mem);
62
63
+ /* PLIC */
64
+ sysbus_realize(SYS_BUS_DEVICE(&s->plic), &err);
65
+ if (err != NULL) {
66
+ error_propagate(errp, err);
67
+ return;
68
+ }
69
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
70
+
71
create_unimplemented_device("riscv.lowrisc.ibex.uart",
72
memmap[IBEX_UART].base, memmap[IBEX_UART].size);
73
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
74
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
75
memmap[IBEX_AES].base, memmap[IBEX_AES].size);
76
create_unimplemented_device("riscv.lowrisc.ibex.hmac",
77
memmap[IBEX_HMAC].base, memmap[IBEX_HMAC].size);
78
- create_unimplemented_device("riscv.lowrisc.ibex.plic",
79
- memmap[IBEX_PLIC].base, memmap[IBEX_PLIC].size);
80
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
81
memmap[IBEX_PINMUX].base, memmap[IBEX_PINMUX].size);
82
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
83
--
83
--
84
2.27.0
84
2.48.1
85
86
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
It is enough to simply map the SiFive FU540 DDR memory controller
3
Keep kvm_riscv_get_timebase_frequency() prototype aligned with
4
into the MMIO space using create_unimplemented_device(), to make
4
the other ones declared in "kvm_riscv.h", have it take a RISCVCPU
5
the upstream U-Boot v2020.07 DDR memory initialization codes happy.
5
cpu as argument. Include "target/riscv/cpu-qom.h" which declares
6
the RISCVCPU typedef.
6
7
7
Note we do not generate device tree fragment for the DDR memory
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
controller. Since the controller data in device tree consumes a
9
very large space (see fu540-hifive-unleashed-a00-ddr.dtsi in the
10
U-Boot source), and it is only needed by U-Boot SPL but not any
11
operating system, we choose not to generate the fragment here.
12
This also means when testing with U-Boot SPL, the device tree has
13
to come from U-Boot SPL itself, but not the one generated by QEMU
14
on the fly. The memory has to be set to 8GiB to match the real
15
HiFive Unleashed board when invoking QEMU (-m 8G).
16
17
With this commit, QEMU can boot U-Boot SPL built for SiFive FU540
18
all the way up to loading U-Boot proper from MMC:
19
20
$ qemu-system-riscv64 -nographic -M sifive_u,msel=6 -m 8G -bios u-boot-spl.bin
21
22
U-Boot SPL 2020.07-rc3-00208-g88bd5b1 (Jun 08 2020 - 20:16:10 +0800)
23
Trying to boot from MMC1
24
Unhandled exception: Load access fault
25
EPC: 0000000008009be6 TVAL: 0000000010050014
26
27
The above exception is expected because QSPI is unsupported yet.
28
29
Signed-off-by: Bin Meng <bin.meng@windriver.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-id: 1592268641-7478-6-git-send-email-bmeng.cn@gmail.com
10
Message-ID: <20250112231344.34632-2-philmd@linaro.org>
32
Message-Id: <1592268641-7478-6-git-send-email-bmeng.cn@gmail.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
12
---
35
include/hw/riscv/sifive_u.h | 1 +
13
target/riscv/kvm/kvm_riscv.h | 4 +++-
36
hw/riscv/sifive_u.c | 4 ++++
14
hw/riscv/virt.c | 2 +-
37
2 files changed, 5 insertions(+)
15
target/riscv/kvm/kvm-cpu.c | 4 ++--
16
3 files changed, 6 insertions(+), 4 deletions(-)
38
17
39
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
18
diff --git a/target/riscv/kvm/kvm_riscv.h b/target/riscv/kvm/kvm_riscv.h
40
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/riscv/sifive_u.h
20
--- a/target/riscv/kvm/kvm_riscv.h
42
+++ b/include/hw/riscv/sifive_u.h
21
+++ b/target/riscv/kvm/kvm_riscv.h
43
@@ -XXX,XX +XXX,XX @@ enum {
22
@@ -XXX,XX +XXX,XX @@
44
SIFIVE_U_UART1,
23
#ifndef QEMU_KVM_RISCV_H
45
SIFIVE_U_GPIO,
24
#define QEMU_KVM_RISCV_H
46
SIFIVE_U_OTP,
25
47
+ SIFIVE_U_DMC,
26
+#include "target/riscv/cpu-qom.h"
48
SIFIVE_U_FLASH0,
27
+
49
SIFIVE_U_DRAM,
28
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
50
SIFIVE_U_GEM,
29
void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
51
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
30
void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
31
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
32
void riscv_kvm_aplic_request(void *opaque, int irq, int level);
33
int kvm_riscv_sync_mpstate_to_kvm(RISCVCPU *cpu, int state);
34
void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
35
-uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs);
36
+uint64_t kvm_riscv_get_timebase_frequency(RISCVCPU *cpu);
37
38
#endif
39
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
52
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/riscv/sifive_u.c
41
--- a/hw/riscv/virt.c
54
+++ b/hw/riscv/sifive_u.c
42
+++ b/hw/riscv/virt.c
55
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
43
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
56
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
44
qemu_fdt_add_subnode(ms->fdt, "/cpus");
57
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
45
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
58
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
46
kvm_enabled() ?
59
+ [SIFIVE_U_DMC] = { 0x100b0000, 0x10000 },
47
- kvm_riscv_get_timebase_frequency(first_cpu) :
60
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
48
+ kvm_riscv_get_timebase_frequency(RISCV_CPU(first_cpu)) :
61
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
49
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
62
};
50
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
63
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
51
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
64
52
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
65
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
53
index XXXXXXX..XXXXXXX 100644
66
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
54
--- a/target/riscv/kvm/kvm-cpu.c
67
+
55
+++ b/target/riscv/kvm/kvm-cpu.c
68
+ create_unimplemented_device("riscv.sifive.u.dmc",
56
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs)
69
+ memmap[SIFIVE_U_DMC].base, memmap[SIFIVE_U_DMC].size);
57
env->kvm_timer_dirty = false;
70
}
58
}
71
59
72
static Property sifive_u_soc_props[] = {
60
-uint64_t kvm_riscv_get_timebase_frequency(CPUState *cs)
61
+uint64_t kvm_riscv_get_timebase_frequency(RISCVCPU *cpu)
62
{
63
uint64_t reg;
64
65
- KVM_RISCV_GET_TIMER(cs, frequency, reg);
66
+ KVM_RISCV_GET_TIMER(CPU(cpu), frequency, reg);
67
68
return reg;
69
}
73
--
70
--
74
2.27.0
71
2.48.1
75
72
76
73
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Move the flash and DRAM to the end of the SoC memmap table.
3
virt_machine_init() creates the HARTs vCPUs, then later
4
virt_machine_done() calls create_fdt_sockets(), so the
5
latter has access to the first vCPU via:
4
6
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
RISCVVirtState {
8
RISCVHartArrayState {
9
RISCVCPU *harts;
10
...
11
12
} soc[VIRT_SOCKETS_MAX];
13
...
14
15
} s;
16
17
Directly use that instead of the &first_cpu global.
18
19
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 1592268641-7478-5-git-send-email-bmeng.cn@gmail.com
21
Message-ID: <20250112231344.34632-3-philmd@linaro.org>
8
Message-Id: <1592268641-7478-5-git-send-email-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
23
---
11
hw/riscv/sifive_u.c | 4 ++--
24
hw/riscv/virt.c | 2 +-
12
1 file changed, 2 insertions(+), 2 deletions(-)
25
1 file changed, 1 insertion(+), 1 deletion(-)
13
26
14
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
27
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/sifive_u.c
29
--- a/hw/riscv/virt.c
17
+++ b/hw/riscv/sifive_u.c
30
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
31
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
19
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
32
qemu_fdt_add_subnode(ms->fdt, "/cpus");
20
[SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
33
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "timebase-frequency",
21
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
34
kvm_enabled() ?
22
- [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
35
- kvm_riscv_get_timebase_frequency(RISCV_CPU(first_cpu)) :
23
- [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
36
+ kvm_riscv_get_timebase_frequency(&s->soc->harts[0]) :
24
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
37
RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
25
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
38
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
26
+ [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
39
qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
27
+ [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
28
};
29
30
#define OTP_SERIAL 1
31
--
40
--
32
2.27.0
41
2.48.1
33
42
34
43
diff view generated by jsdifflib
New patch
1
From: Kaiwen Xue <kaiwenx@rivosinc.com>
1
2
3
This adds the properties for sxcsrind. Definitions of new registers and
4
implementations will come with future patches.
5
6
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-ID: <20250110-counter_delegation-v5-1-e83d797ae294@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu_cfg.h | 2 ++
14
target/riscv/cpu.c | 2 ++
15
2 files changed, 4 insertions(+)
16
17
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu_cfg.h
20
+++ b/target/riscv/cpu_cfg.h
21
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
22
bool ext_smstateen;
23
bool ext_sstc;
24
bool ext_smcntrpmf;
25
+ bool ext_smcsrind;
26
+ bool ext_sscsrind;
27
bool ext_svadu;
28
bool ext_svinval;
29
bool ext_svnapot;
30
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/cpu.c
33
+++ b/target/riscv/cpu.c
34
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
35
ISA_EXT_DATA_ENTRY(shvstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
36
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
37
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
38
+ ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
39
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
40
ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
41
ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
42
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
43
ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
44
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
45
ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
46
+ ISA_EXT_DATA_ENTRY(sscsrind, PRIV_VERSION_1_12_0, ext_sscsrind),
47
ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_13_0, ext_ssnpm),
48
ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
49
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
50
--
51
2.48.1
diff view generated by jsdifflib
New patch
1
From: Kaiwen Xue <kaiwenx@rivosinc.com>
1
2
3
Since xiselect and xireg also will be of use in sxcsrind, AIA should
4
have its own separated interface when those CSRs are accessed.
5
6
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
9
Message-ID: <20250110-counter_delegation-v5-2-e83d797ae294@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/csr.c | 165 ++++++++++++++++++++++++++++++++++++++-------
13
1 file changed, 139 insertions(+), 26 deletions(-)
14
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "system/cpu-timers.h"
21
#include "qemu/guest-random.h"
22
#include "qapi/error.h"
23
+#include <stdbool.h>
24
25
/* CSR function table public API */
26
void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
27
@@ -XXX,XX +XXX,XX @@ static RISCVException aia_any32(CPURISCVState *env, int csrno)
28
return any32(env, csrno);
29
}
30
31
+static RISCVException csrind_or_aia_any(CPURISCVState *env, int csrno)
32
+{
33
+ if (!riscv_cpu_cfg(env)->ext_smaia && !riscv_cpu_cfg(env)->ext_smcsrind) {
34
+ return RISCV_EXCP_ILLEGAL_INST;
35
+ }
36
+
37
+ return any(env, csrno);
38
+}
39
+
40
static RISCVException smode(CPURISCVState *env, int csrno)
41
{
42
if (riscv_has_ext(env, RVS)) {
43
@@ -XXX,XX +XXX,XX @@ static RISCVException aia_smode32(CPURISCVState *env, int csrno)
44
return smode32(env, csrno);
45
}
46
47
+static bool csrind_extensions_present(CPURISCVState *env)
48
+{
49
+ return riscv_cpu_cfg(env)->ext_smcsrind || riscv_cpu_cfg(env)->ext_sscsrind;
50
+}
51
+
52
+static bool aia_extensions_present(CPURISCVState *env)
53
+{
54
+ return riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_ssaia;
55
+}
56
+
57
+static bool csrind_or_aia_extensions_present(CPURISCVState *env)
58
+{
59
+ return csrind_extensions_present(env) || aia_extensions_present(env);
60
+}
61
+
62
+static RISCVException csrind_or_aia_smode(CPURISCVState *env, int csrno)
63
+{
64
+ if (!csrind_or_aia_extensions_present(env)) {
65
+ return RISCV_EXCP_ILLEGAL_INST;
66
+ }
67
+
68
+ return smode(env, csrno);
69
+}
70
+
71
static RISCVException hmode(CPURISCVState *env, int csrno)
72
{
73
if (riscv_has_ext(env, RVH)) {
74
@@ -XXX,XX +XXX,XX @@ static RISCVException hmode32(CPURISCVState *env, int csrno)
75
76
}
77
78
+static RISCVException csrind_or_aia_hmode(CPURISCVState *env, int csrno)
79
+{
80
+ if (!csrind_or_aia_extensions_present(env)) {
81
+ return RISCV_EXCP_ILLEGAL_INST;
82
+ }
83
+
84
+ return hmode(env, csrno);
85
+}
86
+
87
static RISCVException umode(CPURISCVState *env, int csrno)
88
{
89
if (riscv_has_ext(env, RVU)) {
90
@@ -XXX,XX +XXX,XX @@ static int aia_xlate_vs_csrno(CPURISCVState *env, int csrno)
91
};
92
}
93
94
+static int csrind_xlate_vs_csrno(CPURISCVState *env, int csrno)
95
+{
96
+ if (!env->virt_enabled) {
97
+ return csrno;
98
+ }
99
+
100
+ switch (csrno) {
101
+ case CSR_SISELECT:
102
+ return CSR_VSISELECT;
103
+ case CSR_SIREG:
104
+ return CSR_VSIREG;
105
+ default:
106
+ return csrno;
107
+ };
108
+}
109
+
110
static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
111
target_ulong *val, target_ulong new_val,
112
target_ulong wr_mask)
113
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
114
target_ulong *iselect;
115
116
/* Translate CSR number for VS-mode */
117
- csrno = aia_xlate_vs_csrno(env, csrno);
118
+ csrno = csrind_xlate_vs_csrno(env, csrno);
119
120
/* Find the iselect CSR based on CSR number */
121
switch (csrno) {
122
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
123
return RISCV_EXCP_NONE;
124
}
125
126
+static bool xiselect_aia_range(target_ulong isel)
127
+{
128
+ return (ISELECT_IPRIO0 <= isel && isel <= ISELECT_IPRIO15) ||
129
+ (ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST);
130
+}
131
+
132
static int rmw_iprio(target_ulong xlen,
133
target_ulong iselect, uint8_t *iprio,
134
target_ulong *val, target_ulong new_val,
135
@@ -XXX,XX +XXX,XX @@ static int rmw_iprio(target_ulong xlen,
136
return 0;
137
}
138
139
-static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
140
- target_ulong *val, target_ulong new_val,
141
- target_ulong wr_mask)
142
+static RISCVException rmw_xireg_aia(CPURISCVState *env, int csrno,
143
+ target_ulong isel, target_ulong *val,
144
+ target_ulong new_val, target_ulong wr_mask)
145
{
146
- bool virt, isel_reserved;
147
- uint8_t *iprio;
148
+ bool virt = false, isel_reserved = false;
149
int ret = -EINVAL;
150
- target_ulong priv, isel, vgein;
151
-
152
- /* Translate CSR number for VS-mode */
153
- csrno = aia_xlate_vs_csrno(env, csrno);
154
+ uint8_t *iprio;
155
+ target_ulong priv, vgein;
156
157
- /* Decode register details from CSR number */
158
- virt = false;
159
- isel_reserved = false;
160
+ /* VS-mode CSR number passed in has already been translated */
161
switch (csrno) {
162
case CSR_MIREG:
163
+ if (!riscv_cpu_cfg(env)->ext_smaia) {
164
+ goto done;
165
+ }
166
iprio = env->miprio;
167
- isel = env->miselect;
168
priv = PRV_M;
169
break;
170
case CSR_SIREG:
171
- if (env->priv == PRV_S && env->mvien & MIP_SEIP &&
172
+ if (!riscv_cpu_cfg(env)->ext_ssaia ||
173
+ (env->priv == PRV_S && env->mvien & MIP_SEIP &&
174
env->siselect >= ISELECT_IMSIC_EIDELIVERY &&
175
- env->siselect <= ISELECT_IMSIC_EIE63) {
176
+ env->siselect <= ISELECT_IMSIC_EIE63)) {
177
goto done;
178
}
179
iprio = env->siprio;
180
- isel = env->siselect;
181
priv = PRV_S;
182
break;
183
case CSR_VSIREG:
184
+ if (!riscv_cpu_cfg(env)->ext_ssaia) {
185
+ goto done;
186
+ }
187
iprio = env->hviprio;
188
- isel = env->vsiselect;
189
priv = PRV_S;
190
virt = true;
191
break;
192
default:
193
- goto done;
194
+ goto done;
195
};
196
197
/* Find the selected guest interrupt file */
198
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
199
}
200
201
done:
202
+ /*
203
+ * If AIA is not enabled, illegal instruction exception is always
204
+ * returned regardless of whether we are in VS-mode or not
205
+ */
206
if (ret) {
207
return (env->virt_enabled && virt && !isel_reserved) ?
208
RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
209
}
210
+
211
+ return RISCV_EXCP_NONE;
212
+}
213
+
214
+static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
215
+ target_ulong *val, target_ulong new_val,
216
+ target_ulong wr_mask)
217
+{
218
+ bool virt = false;
219
+ int ret = -EINVAL;
220
+ target_ulong isel;
221
+
222
+ /* Translate CSR number for VS-mode */
223
+ csrno = csrind_xlate_vs_csrno(env, csrno);
224
+
225
+ /* Decode register details from CSR number */
226
+ switch (csrno) {
227
+ case CSR_MIREG:
228
+ isel = env->miselect;
229
+ break;
230
+ case CSR_SIREG:
231
+ isel = env->siselect;
232
+ break;
233
+ case CSR_VSIREG:
234
+ isel = env->vsiselect;
235
+ virt = true;
236
+ break;
237
+ default:
238
+ goto done;
239
+ };
240
+
241
+ if (xiselect_aia_range(isel)) {
242
+ return rmw_xireg_aia(env, csrno, isel, val, new_val, wr_mask);
243
+ }
244
+
245
+done:
246
+ if (ret) {
247
+ return (env->virt_enabled && virt) ?
248
+ RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
249
+ }
250
return RISCV_EXCP_NONE;
251
}
252
253
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
254
[CSR_MIP] = { "mip", any, NULL, NULL, rmw_mip },
255
256
/* Machine-Level Window to Indirectly Accessed Registers (AIA) */
257
- [CSR_MISELECT] = { "miselect", aia_any, NULL, NULL, rmw_xiselect },
258
- [CSR_MIREG] = { "mireg", aia_any, NULL, NULL, rmw_xireg },
259
+ [CSR_MISELECT] = { "miselect", csrind_or_aia_any, NULL, NULL,
260
+ rmw_xiselect },
261
+ [CSR_MIREG] = { "mireg", csrind_or_aia_any, NULL, NULL,
262
+ rmw_xireg },
263
264
/* Machine-Level Interrupts (AIA) */
265
[CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
266
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
267
[CSR_SATP] = { "satp", satp, read_satp, write_satp },
268
269
/* Supervisor-Level Window to Indirectly Accessed Registers (AIA) */
270
- [CSR_SISELECT] = { "siselect", aia_smode, NULL, NULL, rmw_xiselect },
271
- [CSR_SIREG] = { "sireg", aia_smode, NULL, NULL, rmw_xireg },
272
+ [CSR_SISELECT] = { "siselect", csrind_or_aia_smode, NULL, NULL,
273
+ rmw_xiselect },
274
+ [CSR_SIREG] = { "sireg", csrind_or_aia_smode, NULL, NULL,
275
+ rmw_xireg },
276
277
/* Supervisor-Level Interrupts (AIA) */
278
[CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei },
279
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
280
/*
281
* VS-Level Window to Indirectly Accessed Registers (H-extension with AIA)
282
*/
283
- [CSR_VSISELECT] = { "vsiselect", aia_hmode, NULL, NULL,
284
- rmw_xiselect },
285
- [CSR_VSIREG] = { "vsireg", aia_hmode, NULL, NULL, rmw_xireg },
286
+ [CSR_VSISELECT] = { "vsiselect", csrind_or_aia_hmode, NULL, NULL,
287
+ rmw_xiselect },
288
+ [CSR_VSIREG] = { "vsireg", csrind_or_aia_hmode, NULL, NULL,
289
+ rmw_xireg },
290
291
/* VS-Level Interrupts (H-extension with AIA) */
292
[CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
293
--
294
2.48.1
diff view generated by jsdifflib
1
This is the initial commit of the Ibex UART device. Serial TX is
1
From: Atish Patra <atishp@rivosinc.com>
2
working, while RX has been implemeneted but untested.
3
2
4
This is based on the documentation from:
3
As per the ratified AIA spec v1.0, three stateen bits control AIA CSR
5
https://docs.opentitan.org/hw/ip/uart/doc/
4
access.
6
5
6
Bit 60 controls the indirect CSRs
7
Bit 59 controls the most AIA CSR state
8
Bit 58 controls the IMSIC state such as stopei and vstopei
9
10
Enable the corresponding bits in [m|h]stateen and enable corresponding
11
checks in the CSR accessor functions.
12
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Atish Patra <atishp@rivosinc.com>
15
Message-ID: <20250110-counter_delegation-v5-3-e83d797ae294@rivosinc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: LIU Zhiwei<zhiwei_liu@c-sky.com>
9
---
17
---
10
include/hw/char/ibex_uart.h | 110 ++++++++
18
target/riscv/csr.c | 85 +++++++++++++++++++++++++++++++++++++++++++++-
11
hw/char/ibex_uart.c | 492 ++++++++++++++++++++++++++++++++++++
19
1 file changed, 84 insertions(+), 1 deletion(-)
12
MAINTAINERS | 2 +
13
hw/char/Makefile.objs | 1 +
14
hw/riscv/Kconfig | 4 +
15
5 files changed, 609 insertions(+)
16
create mode 100644 include/hw/char/ibex_uart.h
17
create mode 100644 hw/char/ibex_uart.c
18
20
19
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
21
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
new file mode 100644
22
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX
23
--- a/target/riscv/csr.c
22
--- /dev/null
24
+++ b/target/riscv/csr.c
23
+++ b/include/hw/char/ibex_uart.h
25
@@ -XXX,XX +XXX,XX @@ static RISCVException smode32(CPURISCVState *env, int csrno)
24
@@ -XXX,XX +XXX,XX @@
26
25
+/*
27
static RISCVException aia_smode(CPURISCVState *env, int csrno)
26
+ * QEMU lowRISC Ibex UART device
28
{
27
+ *
29
+ int ret;
28
+ * Copyright (c) 2020 Western Digital
29
+ *
30
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ * of this software and associated documentation files (the "Software"), to deal
32
+ * in the Software without restriction, including without limitation the rights
33
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ * copies of the Software, and to permit persons to whom the Software is
35
+ * furnished to do so, subject to the following conditions:
36
+ *
37
+ * The above copyright notice and this permission notice shall be included in
38
+ * all copies or substantial portions of the Software.
39
+ *
40
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46
+ * THE SOFTWARE.
47
+ */
48
+
30
+
49
+#ifndef HW_IBEX_UART_H
31
if (!riscv_cpu_cfg(env)->ext_ssaia) {
50
+#define HW_IBEX_UART_H
32
return RISCV_EXCP_ILLEGAL_INST;
51
+
33
}
52
+#include "hw/sysbus.h"
34
53
+#include "chardev/char-fe.h"
35
+ if (csrno == CSR_STOPEI) {
54
+#include "qemu/timer.h"
36
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_IMSIC);
55
+
56
+#define IBEX_UART_INTR_STATE 0x00
57
+ #define INTR_STATE_TX_WATERMARK (1 << 0)
58
+ #define INTR_STATE_RX_WATERMARK (1 << 1)
59
+ #define INTR_STATE_TX_EMPTY (1 << 2)
60
+ #define INTR_STATE_RX_OVERFLOW (1 << 3)
61
+#define IBEX_UART_INTR_ENABLE 0x04
62
+#define IBEX_UART_INTR_TEST 0x08
63
+
64
+#define IBEX_UART_CTRL 0x0c
65
+ #define UART_CTRL_TX_ENABLE (1 << 0)
66
+ #define UART_CTRL_RX_ENABLE (1 << 1)
67
+ #define UART_CTRL_NF (1 << 2)
68
+ #define UART_CTRL_SLPBK (1 << 4)
69
+ #define UART_CTRL_LLPBK (1 << 5)
70
+ #define UART_CTRL_PARITY_EN (1 << 6)
71
+ #define UART_CTRL_PARITY_ODD (1 << 7)
72
+ #define UART_CTRL_RXBLVL (3 << 8)
73
+ #define UART_CTRL_NCO (0xFFFF << 16)
74
+
75
+#define IBEX_UART_STATUS 0x10
76
+ #define UART_STATUS_TXFULL (1 << 0)
77
+ #define UART_STATUS_RXFULL (1 << 1)
78
+ #define UART_STATUS_TXEMPTY (1 << 2)
79
+ #define UART_STATUS_RXIDLE (1 << 4)
80
+ #define UART_STATUS_RXEMPTY (1 << 5)
81
+
82
+#define IBEX_UART_RDATA 0x14
83
+#define IBEX_UART_WDATA 0x18
84
+
85
+#define IBEX_UART_FIFO_CTRL 0x1c
86
+ #define FIFO_CTRL_RXRST (1 << 0)
87
+ #define FIFO_CTRL_TXRST (1 << 1)
88
+ #define FIFO_CTRL_RXILVL (7 << 2)
89
+ #define FIFO_CTRL_RXILVL_SHIFT (2)
90
+ #define FIFO_CTRL_TXILVL (3 << 5)
91
+ #define FIFO_CTRL_TXILVL_SHIFT (5)
92
+
93
+#define IBEX_UART_FIFO_STATUS 0x20
94
+#define IBEX_UART_OVRD 0x24
95
+#define IBEX_UART_VAL 0x28
96
+#define IBEX_UART_TIMEOUT_CTRL 0x2c
97
+
98
+#define IBEX_UART_TX_FIFO_SIZE 16
99
+
100
+#define TYPE_IBEX_UART "ibex-uart"
101
+#define IBEX_UART(obj) \
102
+ OBJECT_CHECK(IbexUartState, (obj), TYPE_IBEX_UART)
103
+
104
+typedef struct {
105
+ /* <private> */
106
+ SysBusDevice parent_obj;
107
+
108
+ /* <public> */
109
+ MemoryRegion mmio;
110
+
111
+ uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
112
+ uint32_t tx_level;
113
+
114
+ QEMUTimer *fifo_trigger_handle;
115
+ uint64_t char_tx_time;
116
+
117
+ uint32_t uart_intr_state;
118
+ uint32_t uart_intr_enable;
119
+ uint32_t uart_ctrl;
120
+ uint32_t uart_status;
121
+ uint32_t uart_rdata;
122
+ uint32_t uart_fifo_ctrl;
123
+ uint32_t uart_fifo_status;
124
+ uint32_t uart_ovrd;
125
+ uint32_t uart_val;
126
+ uint32_t uart_timeout_ctrl;
127
+
128
+ CharBackend chr;
129
+ qemu_irq tx_watermark;
130
+ qemu_irq rx_watermark;
131
+ qemu_irq tx_empty;
132
+ qemu_irq rx_overflow;
133
+} IbexUartState;
134
+#endif /* HW_IBEX_UART_H */
135
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
136
new file mode 100644
137
index XXXXXXX..XXXXXXX
138
--- /dev/null
139
+++ b/hw/char/ibex_uart.c
140
@@ -XXX,XX +XXX,XX @@
141
+/*
142
+ * QEMU lowRISC Ibex UART device
143
+ *
144
+ * Copyright (c) 2020 Western Digital
145
+ *
146
+ * For details check the documentation here:
147
+ * https://docs.opentitan.org/hw/ip/uart/doc/
148
+ *
149
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
150
+ * of this software and associated documentation files (the "Software"), to deal
151
+ * in the Software without restriction, including without limitation the rights
152
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
153
+ * copies of the Software, and to permit persons to whom the Software is
154
+ * furnished to do so, subject to the following conditions:
155
+ *
156
+ * The above copyright notice and this permission notice shall be included in
157
+ * all copies or substantial portions of the Software.
158
+ *
159
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
160
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
162
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
163
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
164
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
165
+ * THE SOFTWARE.
166
+ */
167
+
168
+#include "qemu/osdep.h"
169
+#include "hw/char/ibex_uart.h"
170
+#include "hw/irq.h"
171
+#include "hw/qdev-properties.h"
172
+#include "migration/vmstate.h"
173
+#include "qemu/log.h"
174
+#include "qemu/module.h"
175
+
176
+static void ibex_uart_update_irqs(IbexUartState *s)
177
+{
178
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_WATERMARK) {
179
+ qemu_set_irq(s->tx_watermark, 1);
180
+ } else {
37
+ } else {
181
+ qemu_set_irq(s->tx_watermark, 0);
38
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
182
+ }
39
+ }
183
+
40
+
184
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_WATERMARK) {
41
+ if (ret != RISCV_EXCP_NONE) {
185
+ qemu_set_irq(s->rx_watermark, 1);
42
+ return ret;
186
+ } else {
187
+ qemu_set_irq(s->rx_watermark, 0);
188
+ }
43
+ }
189
+
44
+
190
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_EMPTY) {
45
return smode(env, csrno);
191
+ qemu_set_irq(s->tx_empty, 1);
46
}
192
+ } else {
47
193
+ qemu_set_irq(s->tx_empty, 0);
48
static RISCVException aia_smode32(CPURISCVState *env, int csrno)
49
{
50
+ int ret;
51
+
52
if (!riscv_cpu_cfg(env)->ext_ssaia) {
53
return RISCV_EXCP_ILLEGAL_INST;
54
}
55
56
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
57
+ if (ret != RISCV_EXCP_NONE) {
58
+ return ret;
194
+ }
59
+ }
195
+
60
+
196
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_OVERFLOW) {
61
+ if (ret != RISCV_EXCP_NONE) {
197
+ qemu_set_irq(s->rx_overflow, 1);
62
+ return ret;
198
+ } else {
199
+ qemu_set_irq(s->rx_overflow, 0);
200
+ }
201
+}
202
+
203
+static int ibex_uart_can_receive(void *opaque)
204
+{
205
+ IbexUartState *s = opaque;
206
+
207
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
208
+ return 1;
209
+ }
63
+ }
210
+
64
+
211
+ return 0;
65
return smode32(env, csrno);
212
+}
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static RISCVException hgatp(CPURISCVState *env, int csrno)
69
70
static RISCVException aia_hmode(CPURISCVState *env, int csrno)
71
{
72
+ int ret;
213
+
73
+
214
+static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
74
if (!riscv_cpu_cfg(env)->ext_ssaia) {
215
+{
75
return RISCV_EXCP_ILLEGAL_INST;
216
+ IbexUartState *s = opaque;
76
}
217
+ uint8_t rx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_RXILVL)
77
218
+ >> FIFO_CTRL_RXILVL_SHIFT;
78
- return hmode(env, csrno);
219
+
79
+ if (csrno == CSR_VSTOPEI) {
220
+ s->uart_rdata = *buf;
80
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_IMSIC);
221
+
81
+ } else {
222
+ s->uart_status &= ~UART_STATUS_RXIDLE;
82
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
223
+ s->uart_status &= ~UART_STATUS_RXEMPTY;
224
+
225
+ if (size > rx_fifo_level) {
226
+ s->uart_intr_state |= INTR_STATE_RX_WATERMARK;
227
+ }
83
+ }
228
+
84
+
229
+ ibex_uart_update_irqs(s);
85
+ if (ret != RISCV_EXCP_NONE) {
230
+}
86
+ return ret;
87
+ }
231
+
88
+
232
+static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond,
89
+ return hmode(env, csrno);
233
+ void *opaque)
90
}
234
+{
91
235
+ IbexUartState *s = opaque;
92
static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
236
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
93
{
237
+ >> FIFO_CTRL_TXILVL_SHIFT;
238
+ int ret;
94
+ int ret;
239
+
95
+
240
+ /* instant drain the fifo when there's no back-end */
96
+ if (!riscv_cpu_cfg(env)->ext_ssaia) {
241
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
97
+ return RISCV_EXCP_ILLEGAL_INST;
242
+ s->tx_level = 0;
98
+ }
243
+ return FALSE;
99
+
100
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_AIA);
101
+ if (ret != RISCV_EXCP_NONE) {
102
+ return ret;
244
+ }
103
+ }
245
+
104
+
246
+ if (!s->tx_level) {
105
if (!riscv_cpu_cfg(env)->ext_ssaia) {
247
+ s->uart_status &= ~UART_STATUS_TXFULL;
106
return RISCV_EXCP_ILLEGAL_INST;
248
+ s->uart_status |= UART_STATUS_TXEMPTY;
107
}
249
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
108
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
250
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
109
target_ulong wr_mask)
251
+ ibex_uart_update_irqs(s);
110
{
252
+ return FALSE;
111
target_ulong *iselect;
112
+ int ret;
113
+
114
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_SVSLCT);
115
+ if (ret != RISCV_EXCP_NONE) {
116
+ return ret;
117
+ }
118
119
/* Translate CSR number for VS-mode */
120
csrno = csrind_xlate_vs_csrno(env, csrno);
121
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
122
int ret = -EINVAL;
123
target_ulong isel;
124
125
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_SVSLCT);
126
+ if (ret != RISCV_EXCP_NONE) {
127
+ return ret;
253
+ }
128
+ }
254
+
129
+
255
+ ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_level);
130
/* Translate CSR number for VS-mode */
256
+
131
csrno = csrind_xlate_vs_csrno(env, csrno);
257
+ if (ret >= 0) {
132
258
+ s->tx_level -= ret;
133
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
259
+ memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_level);
134
wr_mask |= SMSTATEEN0_P1P13;
135
}
136
137
+ if (riscv_cpu_cfg(env)->ext_smaia) {
138
+ wr_mask |= SMSTATEEN0_SVSLCT;
260
+ }
139
+ }
261
+
140
+
262
+ if (s->tx_level) {
141
+ /*
263
+ guint r = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
142
+ * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if IMSIC is
264
+ ibex_uart_xmit, s);
143
+ * implemented. However, that information is with MachineState and we can't
265
+ if (!r) {
144
+ * figure that out in csr.c. Just enable if Smaia is available.
266
+ s->tx_level = 0;
145
+ */
267
+ return FALSE;
146
+ if (riscv_cpu_cfg(env)->ext_smaia) {
268
+ }
147
+ wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
269
+ }
148
+ }
270
+
149
+
271
+ /* Clear the TX Full bit */
150
return write_mstateen(env, csrno, wr_mask, new_val);
272
+ if (s->tx_level != IBEX_UART_TX_FIFO_SIZE) {
151
}
273
+ s->uart_status &= ~UART_STATUS_TXFULL;
152
153
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
154
wr_mask |= SMSTATEEN0_FCSR;
155
}
156
157
+ if (riscv_cpu_cfg(env)->ext_ssaia) {
158
+ wr_mask |= SMSTATEEN0_SVSLCT;
274
+ }
159
+ }
275
+
160
+
276
+ /* Disable the TX_WATERMARK IRQ */
161
+ /*
277
+ if (s->tx_level < tx_fifo_level) {
162
+ * As per the AIA specification, SMSTATEEN0_IMSIC is valid only if IMSIC is
278
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
163
+ * implemented. However, that information is with MachineState and we can't
164
+ * figure that out in csr.c. Just enable if Ssaia is available.
165
+ */
166
+ if (riscv_cpu_cfg(env)->ext_ssaia) {
167
+ wr_mask |= (SMSTATEEN0_AIA | SMSTATEEN0_IMSIC);
279
+ }
168
+ }
280
+
169
+
281
+ /* Set TX empty */
170
return write_hstateen(env, csrno, wr_mask, new_val);
282
+ if (s->tx_level == 0) {
171
}
283
+ s->uart_status |= UART_STATUS_TXEMPTY;
284
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
285
+ }
286
+
287
+ ibex_uart_update_irqs(s);
288
+ return FALSE;
289
+}
290
+
291
+static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
292
+ int size)
293
+{
294
+ uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
295
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
296
+ >> FIFO_CTRL_TXILVL_SHIFT;
297
+
298
+ if (size > IBEX_UART_TX_FIFO_SIZE - s->tx_level) {
299
+ size = IBEX_UART_TX_FIFO_SIZE - s->tx_level;
300
+ qemu_log_mask(LOG_GUEST_ERROR, "ibex_uart: TX FIFO overflow");
301
+ }
302
+
303
+ memcpy(s->tx_fifo + s->tx_level, buf, size);
304
+ s->tx_level += size;
305
+
306
+ if (s->tx_level > 0) {
307
+ s->uart_status &= ~UART_STATUS_TXEMPTY;
308
+ }
309
+
310
+ if (s->tx_level >= tx_fifo_level) {
311
+ s->uart_intr_state |= INTR_STATE_TX_WATERMARK;
312
+ ibex_uart_update_irqs(s);
313
+ }
314
+
315
+ if (s->tx_level == IBEX_UART_TX_FIFO_SIZE) {
316
+ s->uart_status |= UART_STATUS_TXFULL;
317
+ }
318
+
319
+ timer_mod(s->fifo_trigger_handle, current_time +
320
+ (s->char_tx_time * 4));
321
+}
322
+
323
+static void ibex_uart_reset(DeviceState *dev)
324
+{
325
+ IbexUartState *s = IBEX_UART(dev);
326
+
327
+ s->uart_intr_state = 0x00000000;
328
+ s->uart_intr_state = 0x00000000;
329
+ s->uart_intr_enable = 0x00000000;
330
+ s->uart_ctrl = 0x00000000;
331
+ s->uart_status = 0x0000003c;
332
+ s->uart_rdata = 0x00000000;
333
+ s->uart_fifo_ctrl = 0x00000000;
334
+ s->uart_fifo_status = 0x00000000;
335
+ s->uart_ovrd = 0x00000000;
336
+ s->uart_val = 0x00000000;
337
+ s->uart_timeout_ctrl = 0x00000000;
338
+
339
+ s->tx_level = 0;
340
+
341
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
342
+
343
+ ibex_uart_update_irqs(s);
344
+}
345
+
346
+static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
347
+ unsigned int size)
348
+{
349
+ IbexUartState *s = opaque;
350
+ uint64_t retvalue = 0;
351
+
352
+ switch (addr) {
353
+ case IBEX_UART_INTR_STATE:
354
+ retvalue = s->uart_intr_state;
355
+ break;
356
+ case IBEX_UART_INTR_ENABLE:
357
+ retvalue = s->uart_intr_enable;
358
+ break;
359
+ case IBEX_UART_INTR_TEST:
360
+ qemu_log_mask(LOG_GUEST_ERROR,
361
+ "%s: wdata is write only\n", __func__);
362
+ break;
363
+
364
+ case IBEX_UART_CTRL:
365
+ retvalue = s->uart_ctrl;
366
+ break;
367
+ case IBEX_UART_STATUS:
368
+ retvalue = s->uart_status;
369
+ break;
370
+
371
+ case IBEX_UART_RDATA:
372
+ retvalue = s->uart_rdata;
373
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
374
+ qemu_chr_fe_accept_input(&s->chr);
375
+
376
+ s->uart_status |= UART_STATUS_RXIDLE;
377
+ s->uart_status |= UART_STATUS_RXEMPTY;
378
+ }
379
+ break;
380
+ case IBEX_UART_WDATA:
381
+ qemu_log_mask(LOG_GUEST_ERROR,
382
+ "%s: wdata is write only\n", __func__);
383
+ break;
384
+
385
+ case IBEX_UART_FIFO_CTRL:
386
+ retvalue = s->uart_fifo_ctrl;
387
+ break;
388
+ case IBEX_UART_FIFO_STATUS:
389
+ retvalue = s->uart_fifo_status;
390
+
391
+ retvalue |= s->tx_level & 0x1F;
392
+
393
+ qemu_log_mask(LOG_UNIMP,
394
+ "%s: RX fifos are not supported\n", __func__);
395
+ break;
396
+
397
+ case IBEX_UART_OVRD:
398
+ retvalue = s->uart_ovrd;
399
+ qemu_log_mask(LOG_UNIMP,
400
+ "%s: ovrd is not supported\n", __func__);
401
+ break;
402
+ case IBEX_UART_VAL:
403
+ retvalue = s->uart_val;
404
+ qemu_log_mask(LOG_UNIMP,
405
+ "%s: val is not supported\n", __func__);
406
+ break;
407
+ case IBEX_UART_TIMEOUT_CTRL:
408
+ retvalue = s->uart_timeout_ctrl;
409
+ qemu_log_mask(LOG_UNIMP,
410
+ "%s: timeout_ctrl is not supported\n", __func__);
411
+ break;
412
+ default:
413
+ qemu_log_mask(LOG_GUEST_ERROR,
414
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
415
+ return 0;
416
+ }
417
+
418
+ return retvalue;
419
+}
420
+
421
+static void ibex_uart_write(void *opaque, hwaddr addr,
422
+ uint64_t val64, unsigned int size)
423
+{
424
+ IbexUartState *s = opaque;
425
+ uint32_t value = val64;
426
+
427
+ switch (addr) {
428
+ case IBEX_UART_INTR_STATE:
429
+ /* Write 1 clear */
430
+ s->uart_intr_state &= ~value;
431
+ ibex_uart_update_irqs(s);
432
+ break;
433
+ case IBEX_UART_INTR_ENABLE:
434
+ s->uart_intr_enable = value;
435
+ ibex_uart_update_irqs(s);
436
+ break;
437
+ case IBEX_UART_INTR_TEST:
438
+ s->uart_intr_state |= value;
439
+ ibex_uart_update_irqs(s);
440
+ break;
441
+
442
+ case IBEX_UART_CTRL:
443
+ s->uart_ctrl = value;
444
+
445
+ if (value & UART_CTRL_NF) {
446
+ qemu_log_mask(LOG_UNIMP,
447
+ "%s: UART_CTRL_NF is not supported\n", __func__);
448
+ }
449
+ if (value & UART_CTRL_SLPBK) {
450
+ qemu_log_mask(LOG_UNIMP,
451
+ "%s: UART_CTRL_SLPBK is not supported\n", __func__);
452
+ }
453
+ if (value & UART_CTRL_LLPBK) {
454
+ qemu_log_mask(LOG_UNIMP,
455
+ "%s: UART_CTRL_LLPBK is not supported\n", __func__);
456
+ }
457
+ if (value & UART_CTRL_PARITY_EN) {
458
+ qemu_log_mask(LOG_UNIMP,
459
+ "%s: UART_CTRL_PARITY_EN is not supported\n",
460
+ __func__);
461
+ }
462
+ if (value & UART_CTRL_PARITY_ODD) {
463
+ qemu_log_mask(LOG_UNIMP,
464
+ "%s: UART_CTRL_PARITY_ODD is not supported\n",
465
+ __func__);
466
+ }
467
+ if (value & UART_CTRL_RXBLVL) {
468
+ qemu_log_mask(LOG_UNIMP,
469
+ "%s: UART_CTRL_RXBLVL is not supported\n", __func__);
470
+ }
471
+ if (value & UART_CTRL_NCO) {
472
+ uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
473
+ baud *= 1000;
474
+ baud /= 2 ^ 20;
475
+
476
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
477
+ }
478
+ break;
479
+ case IBEX_UART_STATUS:
480
+ qemu_log_mask(LOG_GUEST_ERROR,
481
+ "%s: status is read only\n", __func__);
482
+ break;
483
+
484
+ case IBEX_UART_RDATA:
485
+ qemu_log_mask(LOG_GUEST_ERROR,
486
+ "%s: rdata is read only\n", __func__);
487
+ break;
488
+ case IBEX_UART_WDATA:
489
+ uart_write_tx_fifo(s, (uint8_t *) &value, 1);
490
+ break;
491
+
492
+ case IBEX_UART_FIFO_CTRL:
493
+ s->uart_fifo_ctrl = value;
494
+
495
+ if (value & FIFO_CTRL_RXRST) {
496
+ qemu_log_mask(LOG_UNIMP,
497
+ "%s: RX fifos are not supported\n", __func__);
498
+ }
499
+ if (value & FIFO_CTRL_TXRST) {
500
+ s->tx_level = 0;
501
+ }
502
+ break;
503
+ case IBEX_UART_FIFO_STATUS:
504
+ qemu_log_mask(LOG_GUEST_ERROR,
505
+ "%s: fifo_status is read only\n", __func__);
506
+ break;
507
+
508
+ case IBEX_UART_OVRD:
509
+ s->uart_ovrd = value;
510
+ qemu_log_mask(LOG_UNIMP,
511
+ "%s: ovrd is not supported\n", __func__);
512
+ break;
513
+ case IBEX_UART_VAL:
514
+ qemu_log_mask(LOG_GUEST_ERROR,
515
+ "%s: val is read only\n", __func__);
516
+ break;
517
+ case IBEX_UART_TIMEOUT_CTRL:
518
+ s->uart_timeout_ctrl = value;
519
+ qemu_log_mask(LOG_UNIMP,
520
+ "%s: timeout_ctrl is not supported\n", __func__);
521
+ break;
522
+ default:
523
+ qemu_log_mask(LOG_GUEST_ERROR,
524
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
525
+ }
526
+}
527
+
528
+static void fifo_trigger_update(void *opaque)
529
+{
530
+ IbexUartState *s = opaque;
531
+
532
+ if (s->uart_ctrl & UART_CTRL_TX_ENABLE) {
533
+ ibex_uart_xmit(NULL, G_IO_OUT, s);
534
+ }
535
+}
536
+
537
+static const MemoryRegionOps ibex_uart_ops = {
538
+ .read = ibex_uart_read,
539
+ .write = ibex_uart_write,
540
+ .endianness = DEVICE_NATIVE_ENDIAN,
541
+ .impl.min_access_size = 4,
542
+ .impl.max_access_size = 4,
543
+};
544
+
545
+static int ibex_uart_post_load(void *opaque, int version_id)
546
+{
547
+ IbexUartState *s = opaque;
548
+
549
+ ibex_uart_update_irqs(s);
550
+ return 0;
551
+}
552
+
553
+static const VMStateDescription vmstate_ibex_uart = {
554
+ .name = TYPE_IBEX_UART,
555
+ .version_id = 1,
556
+ .minimum_version_id = 1,
557
+ .post_load = ibex_uart_post_load,
558
+ .fields = (VMStateField[]) {
559
+ VMSTATE_UINT8_ARRAY(tx_fifo, IbexUartState,
560
+ IBEX_UART_TX_FIFO_SIZE),
561
+ VMSTATE_UINT32(tx_level, IbexUartState),
562
+ VMSTATE_UINT64(char_tx_time, IbexUartState),
563
+ VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexUartState),
564
+ VMSTATE_UINT32(uart_intr_state, IbexUartState),
565
+ VMSTATE_UINT32(uart_intr_enable, IbexUartState),
566
+ VMSTATE_UINT32(uart_ctrl, IbexUartState),
567
+ VMSTATE_UINT32(uart_status, IbexUartState),
568
+ VMSTATE_UINT32(uart_rdata, IbexUartState),
569
+ VMSTATE_UINT32(uart_fifo_ctrl, IbexUartState),
570
+ VMSTATE_UINT32(uart_fifo_status, IbexUartState),
571
+ VMSTATE_UINT32(uart_ovrd, IbexUartState),
572
+ VMSTATE_UINT32(uart_val, IbexUartState),
573
+ VMSTATE_UINT32(uart_timeout_ctrl, IbexUartState),
574
+ VMSTATE_END_OF_LIST()
575
+ }
576
+};
577
+
578
+static Property ibex_uart_properties[] = {
579
+ DEFINE_PROP_CHR("chardev", IbexUartState, chr),
580
+ DEFINE_PROP_END_OF_LIST(),
581
+};
582
+
583
+static void ibex_uart_init(Object *obj)
584
+{
585
+ IbexUartState *s = IBEX_UART(obj);
586
+
587
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
588
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_watermark);
589
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_empty);
590
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_overflow);
591
+
592
+ memory_region_init_io(&s->mmio, obj, &ibex_uart_ops, s,
593
+ TYPE_IBEX_UART, 0x400);
594
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
595
+}
596
+
597
+static void ibex_uart_realize(DeviceState *dev, Error **errp)
598
+{
599
+ IbexUartState *s = IBEX_UART(dev);
600
+
601
+ s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
602
+ fifo_trigger_update, s);
603
+
604
+ qemu_chr_fe_set_handlers(&s->chr, ibex_uart_can_receive,
605
+ ibex_uart_receive, NULL, NULL,
606
+ s, NULL, true);
607
+}
608
+
609
+static void ibex_uart_class_init(ObjectClass *klass, void *data)
610
+{
611
+ DeviceClass *dc = DEVICE_CLASS(klass);
612
+
613
+ dc->reset = ibex_uart_reset;
614
+ dc->realize = ibex_uart_realize;
615
+ dc->vmsd = &vmstate_ibex_uart;
616
+ device_class_set_props(dc, ibex_uart_properties);
617
+}
618
+
619
+static const TypeInfo ibex_uart_info = {
620
+ .name = TYPE_IBEX_UART,
621
+ .parent = TYPE_SYS_BUS_DEVICE,
622
+ .instance_size = sizeof(IbexUartState),
623
+ .instance_init = ibex_uart_init,
624
+ .class_init = ibex_uart_class_init,
625
+};
626
+
627
+static void ibex_uart_register_types(void)
628
+{
629
+ type_register_static(&ibex_uart_info);
630
+}
631
+
632
+type_init(ibex_uart_register_types)
633
diff --git a/MAINTAINERS b/MAINTAINERS
634
index XXXXXXX..XXXXXXX 100644
635
--- a/MAINTAINERS
636
+++ b/MAINTAINERS
637
@@ -XXX,XX +XXX,XX @@ M: Alistair Francis <Alistair.Francis@wdc.com>
638
L: qemu-riscv@nongnu.org
639
S: Supported
640
F: hw/riscv/opentitan.c
641
+F: hw/char/ibex_uart.c
642
F: include/hw/riscv/opentitan.h
643
+F: include/hw/char/ibex_uart.h
644
645
SH4 Machines
646
------------
647
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
648
index XXXXXXX..XXXXXXX 100644
649
--- a/hw/char/Makefile.objs
650
+++ b/hw/char/Makefile.objs
651
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
652
common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
653
common-obj-$(CONFIG_XEN) += xen_console.o
654
common-obj-$(CONFIG_CADENCE) += cadence_uart.o
655
+common-obj-$(CONFIG_IBEX) += ibex_uart.o
656
657
common-obj-$(CONFIG_EXYNOS4) += exynos4210_uart.o
658
common-obj-$(CONFIG_COLDFIRE) += mcf_uart.o
659
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
660
index XXXXXXX..XXXXXXX 100644
661
--- a/hw/riscv/Kconfig
662
+++ b/hw/riscv/Kconfig
663
@@ -XXX,XX +XXX,XX @@ config HTIF
664
config HART
665
bool
666
667
+config IBEX
668
+ bool
669
+
670
config SIFIVE
671
bool
672
select MSI_NONBROKEN
673
@@ -XXX,XX +XXX,XX @@ config SPIKE
674
675
config OPENTITAN
676
bool
677
+ select IBEX
678
select HART
679
select UNIMP
680
172
681
--
173
--
682
2.27.0
174
2.48.1
683
684
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Kaiwen Xue <kaiwenx@rivosinc.com>
2
2
3
Do various minor clean-ups to the exisiting codes for:
3
This adds the indirect access registers required by sscsrind/smcsrind
4
and the operations on them. Note that xiselect and xireg are used for
5
both AIA and sxcsrind, and the behavior of accessing them depends on
6
whether each extension is enabled and the value stored in xiselect.
4
7
5
- coding convention conformance
8
Co-developed-by: Atish Patra <atishp@rivosinc.com>
6
- remove unnecessary blank lines
9
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
7
- spell SiFive correctly
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
11
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
12
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20250110-counter_delegation-v5-4-e83d797ae294@rivosinc.com>
11
Message-id: 1591625864-31494-6-git-send-email-bmeng.cn@gmail.com
12
Message-Id: <1591625864-31494-6-git-send-email-bmeng.cn@gmail.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
---
15
include/hw/riscv/sifive_gpio.h | 7 ++++---
16
target/riscv/cpu_bits.h | 28 +++++++-
16
hw/riscv/sifive_gpio.c | 13 +++++--------
17
target/riscv/csr.c | 144 ++++++++++++++++++++++++++++++++++++++--
17
2 files changed, 9 insertions(+), 11 deletions(-)
18
2 files changed, 166 insertions(+), 6 deletions(-)
18
19
19
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
20
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/sifive_gpio.h
22
--- a/target/riscv/cpu_bits.h
22
+++ b/include/hw/riscv/sifive_gpio.h
23
+++ b/target/riscv/cpu_bits.h
23
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@
24
/*
25
#define CSR_MISELECT 0x350
25
- * sifive System-on-Chip general purpose input/output register definition
26
#define CSR_MIREG 0x351
26
+ * SiFive System-on-Chip general purpose input/output register definition
27
27
*
28
+/* Machine Indirect Register Alias */
28
* Copyright 2019 AdaCore
29
+#define CSR_MIREG2 0x352
29
*
30
+#define CSR_MIREG3 0x353
31
+#define CSR_MIREG4 0x355
32
+#define CSR_MIREG5 0x356
33
+#define CSR_MIREG6 0x357
34
+
35
/* Machine-Level Interrupts (AIA) */
36
#define CSR_MTOPEI 0x35c
37
#define CSR_MTOPI 0xfb0
30
@@ -XXX,XX +XXX,XX @@
38
@@ -XXX,XX +XXX,XX @@
31
* This code is licensed under the GPL version 2 or later. See
39
#define CSR_SISELECT 0x150
32
* the COPYING file in the top-level directory.
40
#define CSR_SIREG 0x151
33
*/
41
34
+
42
+/* Supervisor Indirect Register Alias */
35
#ifndef SIFIVE_GPIO_H
43
+#define CSR_SIREG2 0x152
36
#define SIFIVE_GPIO_H
44
+#define CSR_SIREG3 0x153
37
45
+#define CSR_SIREG4 0x155
38
#include "hw/sysbus.h"
46
+#define CSR_SIREG5 0x156
39
+
47
+#define CSR_SIREG6 0x157
40
#define TYPE_SIFIVE_GPIO "sifive_soc.gpio"
48
+
41
#define SIFIVE_GPIO(obj) OBJECT_CHECK(SIFIVEGPIOState, (obj), TYPE_SIFIVE_GPIO)
49
/* Supervisor-Level Interrupts (AIA) */
42
50
#define CSR_STOPEI 0x15c
43
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
51
#define CSR_STOPI 0xdb0
44
uint32_t out_xor;
52
@@ -XXX,XX +XXX,XX @@
45
uint32_t in;
53
#define CSR_VSISELECT 0x250
46
uint32_t in_mask;
54
#define CSR_VSIREG 0x251
47
-
55
48
} SIFIVEGPIOState;
56
+/* Virtual Supervisor Indirect Alias */
49
57
+#define CSR_VSIREG2 0x252
50
-#endif
58
+#define CSR_VSIREG3 0x253
51
+#endif /* SIFIVE_GPIO_H */
59
+#define CSR_VSIREG4 0x255
52
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
60
+#define CSR_VSIREG5 0x256
61
+#define CSR_VSIREG6 0x257
62
+
63
/* VS-Level Interrupts (H-extension with AIA) */
64
#define CSR_VSTOPEI 0x25c
65
#define CSR_VSTOPI 0xeb0
66
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
67
#define ISELECT_IMSIC_EIE63 0xff
68
#define ISELECT_IMSIC_FIRST ISELECT_IMSIC_EIDELIVERY
69
#define ISELECT_IMSIC_LAST ISELECT_IMSIC_EIE63
70
-#define ISELECT_MASK 0x1ff
71
+#define ISELECT_MASK_AIA 0x1ff
72
+
73
+/* MISELECT, SISELECT, and VSISELECT bits (AIA) */
74
+#define ISELECT_MASK_SXCSRIND 0xfff
75
76
/* Dummy [M|S|VS]ISELECT value for emulating [M|S|VS]TOPEI CSRs */
77
-#define ISELECT_IMSIC_TOPEI (ISELECT_MASK + 1)
78
+#define ISELECT_IMSIC_TOPEI (ISELECT_MASK_AIA + 1)
79
80
/* IMSIC bits (AIA) */
81
#define IMSIC_TOPEI_IID_SHIFT 16
82
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
53
index XXXXXXX..XXXXXXX 100644
83
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/riscv/sifive_gpio.c
84
--- a/target/riscv/csr.c
55
+++ b/hw/riscv/sifive_gpio.c
85
+++ b/target/riscv/csr.c
56
@@ -XXX,XX +XXX,XX @@
86
@@ -XXX,XX +XXX,XX @@ static RISCVException aia_any32(CPURISCVState *env, int csrno)
57
/*
87
return any32(env, csrno);
58
- * sifive System-on-Chip general purpose input/output register definition
88
}
59
+ * SiFive System-on-Chip general purpose input/output register definition
89
60
*
90
+static RISCVException csrind_any(CPURISCVState *env, int csrno)
61
* Copyright 2019 AdaCore
91
+{
62
*
92
+ if (!riscv_cpu_cfg(env)->ext_smcsrind) {
63
@@ -XXX,XX +XXX,XX @@
93
+ return RISCV_EXCP_ILLEGAL_INST;
64
94
+ }
65
static void update_output_irq(SIFIVEGPIOState *s)
95
+
96
+ return RISCV_EXCP_NONE;
97
+}
98
+
99
static RISCVException csrind_or_aia_any(CPURISCVState *env, int csrno)
66
{
100
{
67
-
101
if (!riscv_cpu_cfg(env)->ext_smaia && !riscv_cpu_cfg(env)->ext_smcsrind) {
68
uint32_t pending;
102
@@ -XXX,XX +XXX,XX @@ static bool csrind_or_aia_extensions_present(CPURISCVState *env)
69
uint32_t pin;
103
return csrind_extensions_present(env) || aia_extensions_present(env);
70
71
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_gpio_read(void *opaque, hwaddr offset, unsigned int size)
72
}
104
}
73
105
74
static void sifive_gpio_write(void *opaque, hwaddr offset,
106
+static RISCVException csrind_smode(CPURISCVState *env, int csrno)
75
- uint64_t value, unsigned int size)
107
+{
76
+ uint64_t value, unsigned int size)
108
+ if (!csrind_extensions_present(env)) {
109
+ return RISCV_EXCP_ILLEGAL_INST;
110
+ }
111
+
112
+ return smode(env, csrno);
113
+}
114
+
115
static RISCVException csrind_or_aia_smode(CPURISCVState *env, int csrno)
77
{
116
{
78
SIFIVEGPIOState *s = SIFIVE_GPIO(opaque);
117
if (!csrind_or_aia_extensions_present(env)) {
79
118
@@ -XXX,XX +XXX,XX @@ static RISCVException hmode32(CPURISCVState *env, int csrno)
80
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_reset(DeviceState *dev)
119
81
s->out_xor = 0;
82
s->in = 0;
83
s->in_mask = 0;
84
-
85
}
120
}
86
121
87
static const VMStateDescription vmstate_sifive_gpio = {
122
+static RISCVException csrind_hmode(CPURISCVState *env, int csrno)
88
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
123
+{
89
VMSTATE_UINT32(iof_en, SIFIVEGPIOState),
124
+ if (!csrind_extensions_present(env)) {
90
VMSTATE_UINT32(iof_sel, SIFIVEGPIOState),
125
+ return RISCV_EXCP_ILLEGAL_INST;
91
VMSTATE_UINT32(out_xor, SIFIVEGPIOState),
126
+ }
92
- VMSTATE_UINT32(in, SIFIVEGPIOState),
127
+
93
- VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
128
+ return hmode(env, csrno);
94
+ VMSTATE_UINT32(in, SIFIVEGPIOState),
129
+}
95
+ VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
130
+
96
VMSTATE_END_OF_LIST()
131
static RISCVException csrind_or_aia_hmode(CPURISCVState *env, int csrno)
97
}
132
{
98
};
133
if (!csrind_or_aia_extensions_present(env)) {
99
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_init(Object *obj)
134
@@ -XXX,XX +XXX,XX @@ static int csrind_xlate_vs_csrno(CPURISCVState *env, int csrno)
100
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
135
case CSR_SISELECT:
101
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
136
return CSR_VSISELECT;
102
137
case CSR_SIREG:
103
-
138
- return CSR_VSIREG;
104
for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
139
+ case CSR_SIREG2:
105
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
140
+ case CSR_SIREG3:
106
}
141
+ case CSR_SIREG4:
107
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_class_init(ObjectClass *klass, void *data)
142
+ case CSR_SIREG5:
108
143
+ case CSR_SIREG6:
109
dc->vmsd = &vmstate_sifive_gpio;
144
+ return CSR_VSIREG + (csrno - CSR_SIREG);
110
dc->reset = sifive_gpio_reset;
145
default:
111
- dc->desc = "sifive GPIO";
146
return csrno;
112
+ dc->desc = "SiFive GPIO";
147
};
148
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_xiselect(CPURISCVState *env, int csrno,
149
*val = *iselect;
150
}
151
152
- wr_mask &= ISELECT_MASK;
153
+ if (riscv_cpu_cfg(env)->ext_smcsrind || riscv_cpu_cfg(env)->ext_sscsrind) {
154
+ wr_mask &= ISELECT_MASK_SXCSRIND;
155
+ } else {
156
+ wr_mask &= ISELECT_MASK_AIA;
157
+ }
158
+
159
if (wr_mask) {
160
*iselect = (*iselect & ~wr_mask) | (new_val & wr_mask);
161
}
162
@@ -XXX,XX +XXX,XX @@ done:
163
return RISCV_EXCP_NONE;
113
}
164
}
114
165
115
static const TypeInfo sifive_gpio_info = {
166
+/*
167
+ * rmw_xireg_csrind: Perform indirect access to xireg and xireg2-xireg6
168
+ *
169
+ * Perform indirect access to xireg and xireg2-xireg6.
170
+ * This is a generic interface for all xireg CSRs. Apart from AIA, all other
171
+ * extension using csrind should be implemented here.
172
+ */
173
+static int rmw_xireg_csrind(CPURISCVState *env, int csrno,
174
+ target_ulong isel, target_ulong *val,
175
+ target_ulong new_val, target_ulong wr_mask)
176
+{
177
+ return -EINVAL;
178
+}
179
+
180
+static int rmw_xiregi(CPURISCVState *env, int csrno, target_ulong *val,
181
+ target_ulong new_val, target_ulong wr_mask)
182
+{
183
+ bool virt = false;
184
+ int ret = -EINVAL;
185
+ target_ulong isel;
186
+
187
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_SVSLCT);
188
+ if (ret != RISCV_EXCP_NONE) {
189
+ return ret;
190
+ }
191
+
192
+ /* Translate CSR number for VS-mode */
193
+ csrno = csrind_xlate_vs_csrno(env, csrno);
194
+
195
+ if (CSR_MIREG <= csrno && csrno <= CSR_MIREG6 &&
196
+ csrno != CSR_MIREG4 - 1) {
197
+ isel = env->miselect;
198
+ } else if (CSR_SIREG <= csrno && csrno <= CSR_SIREG6 &&
199
+ csrno != CSR_SIREG4 - 1) {
200
+ isel = env->siselect;
201
+ } else if (CSR_VSIREG <= csrno && csrno <= CSR_VSIREG6 &&
202
+ csrno != CSR_VSIREG4 - 1) {
203
+ isel = env->vsiselect;
204
+ virt = true;
205
+ } else {
206
+ goto done;
207
+ }
208
+
209
+ return rmw_xireg_csrind(env, csrno, isel, val, new_val, wr_mask);
210
+
211
+done:
212
+ return (env->virt_enabled && virt) ?
213
+ RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
214
+}
215
+
216
static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
217
target_ulong *val, target_ulong new_val,
218
target_ulong wr_mask)
219
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_xireg(CPURISCVState *env, int csrno,
220
goto done;
221
};
222
223
+ /*
224
+ * Use the xiselect range to determine actual op on xireg.
225
+ *
226
+ * Since we only checked the existence of AIA or Indirect Access in the
227
+ * predicate, we should check the existence of the exact extension when
228
+ * we get to a specific range and return illegal instruction exception even
229
+ * in VS-mode.
230
+ */
231
if (xiselect_aia_range(isel)) {
232
return rmw_xireg_aia(env, csrno, isel, val, new_val, wr_mask);
233
+ } else if (riscv_cpu_cfg(env)->ext_smcsrind ||
234
+ riscv_cpu_cfg(env)->ext_sscsrind) {
235
+ return rmw_xireg_csrind(env, csrno, isel, val, new_val, wr_mask);
236
+ } else {
237
+ return RISCV_EXCP_ILLEGAL_INST;
238
}
239
240
done:
241
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
242
wr_mask |= SMSTATEEN0_P1P13;
243
}
244
245
- if (riscv_cpu_cfg(env)->ext_smaia) {
246
+ if (riscv_cpu_cfg(env)->ext_smaia || riscv_cpu_cfg(env)->ext_smcsrind) {
247
wr_mask |= SMSTATEEN0_SVSLCT;
248
}
249
250
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
251
wr_mask |= SMSTATEEN0_FCSR;
252
}
253
254
- if (riscv_cpu_cfg(env)->ext_ssaia) {
255
+ if (riscv_cpu_cfg(env)->ext_ssaia || riscv_cpu_cfg(env)->ext_sscsrind) {
256
wr_mask |= SMSTATEEN0_SVSLCT;
257
}
258
259
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
260
[CSR_MIREG] = { "mireg", csrind_or_aia_any, NULL, NULL,
261
rmw_xireg },
262
263
+ /* Machine Indirect Register Alias */
264
+ [CSR_MIREG2] = { "mireg2", csrind_any, NULL, NULL, rmw_xiregi,
265
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
266
+ [CSR_MIREG3] = { "mireg3", csrind_any, NULL, NULL, rmw_xiregi,
267
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
268
+ [CSR_MIREG4] = { "mireg4", csrind_any, NULL, NULL, rmw_xiregi,
269
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
270
+ [CSR_MIREG5] = { "mireg5", csrind_any, NULL, NULL, rmw_xiregi,
271
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
272
+ [CSR_MIREG6] = { "mireg6", csrind_any, NULL, NULL, rmw_xiregi,
273
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
274
+
275
/* Machine-Level Interrupts (AIA) */
276
[CSR_MTOPEI] = { "mtopei", aia_any, NULL, NULL, rmw_xtopei },
277
[CSR_MTOPI] = { "mtopi", aia_any, read_mtopi },
278
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
279
[CSR_SIREG] = { "sireg", csrind_or_aia_smode, NULL, NULL,
280
rmw_xireg },
281
282
+ /* Supervisor Indirect Register Alias */
283
+ [CSR_SIREG2] = { "sireg2", csrind_smode, NULL, NULL, rmw_xiregi,
284
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
285
+ [CSR_SIREG3] = { "sireg3", csrind_smode, NULL, NULL, rmw_xiregi,
286
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
287
+ [CSR_SIREG4] = { "sireg4", csrind_smode, NULL, NULL, rmw_xiregi,
288
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
289
+ [CSR_SIREG5] = { "sireg5", csrind_smode, NULL, NULL, rmw_xiregi,
290
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
291
+ [CSR_SIREG6] = { "sireg6", csrind_smode, NULL, NULL, rmw_xiregi,
292
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
293
+
294
/* Supervisor-Level Interrupts (AIA) */
295
[CSR_STOPEI] = { "stopei", aia_smode, NULL, NULL, rmw_xtopei },
296
[CSR_STOPI] = { "stopi", aia_smode, read_stopi },
297
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
298
[CSR_VSIREG] = { "vsireg", csrind_or_aia_hmode, NULL, NULL,
299
rmw_xireg },
300
301
+ /* Virtual Supervisor Indirect Alias */
302
+ [CSR_VSIREG2] = { "vsireg2", csrind_hmode, NULL, NULL, rmw_xiregi,
303
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
304
+ [CSR_VSIREG3] = { "vsireg3", csrind_hmode, NULL, NULL, rmw_xiregi,
305
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
306
+ [CSR_VSIREG4] = { "vsireg4", csrind_hmode, NULL, NULL, rmw_xiregi,
307
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
308
+ [CSR_VSIREG5] = { "vsireg5", csrind_hmode, NULL, NULL, rmw_xiregi,
309
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
310
+ [CSR_VSIREG6] = { "vsireg6", csrind_hmode, NULL, NULL, rmw_xiregi,
311
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
312
+
313
/* VS-Level Interrupts (H-extension with AIA) */
314
[CSR_VSTOPEI] = { "vstopei", aia_hmode, NULL, NULL, rmw_xtopei },
315
[CSR_VSTOPI] = { "vstopi", aia_hmode, read_vstopi },
116
--
316
--
117
2.27.0
317
2.48.1
118
119
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
This adds the properties for counter delegation ISA extensions
4
(Smcdeleg/Ssccfg). Definitions of new registers and and implementation
5
will come in the next set of patches.
6
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-ID: <20250110-counter_delegation-v5-5-e83d797ae294@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu_cfg.h | 2 ++
14
target/riscv/cpu.c | 2 ++
15
2 files changed, 4 insertions(+)
16
17
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu_cfg.h
20
+++ b/target/riscv/cpu_cfg.h
21
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
22
bool ext_ztso;
23
bool ext_smstateen;
24
bool ext_sstc;
25
+ bool ext_smcdeleg;
26
+ bool ext_ssccfg;
27
bool ext_smcntrpmf;
28
bool ext_smcsrind;
29
bool ext_sscsrind;
30
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/cpu.c
33
+++ b/target/riscv/cpu.c
34
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
35
ISA_EXT_DATA_ENTRY(shvstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
36
ISA_EXT_DATA_ENTRY(shvstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
37
ISA_EXT_DATA_ENTRY(smaia, PRIV_VERSION_1_12_0, ext_smaia),
38
+ ISA_EXT_DATA_ENTRY(smcdeleg, PRIV_VERSION_1_13_0, ext_smcdeleg),
39
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
40
ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
41
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
42
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
43
ISA_EXT_DATA_ENTRY(smnpm, PRIV_VERSION_1_13_0, ext_smnpm),
44
ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
45
ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
46
+ ISA_EXT_DATA_ENTRY(ssccfg, PRIV_VERSION_1_13_0, ext_ssccfg),
47
ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
48
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
49
ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
50
--
51
2.48.1
diff view generated by jsdifflib
New patch
1
From: Kaiwen Xue <kaiwenx@rivosinc.com>
1
2
3
This adds definitions for counter delegation, including the new
4
scountinhibit register and the mstateen.CD bit.
5
6
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
9
Message-ID: <20250110-counter_delegation-v5-6-e83d797ae294@rivosinc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.h | 1 +
13
target/riscv/cpu_bits.h | 8 +++++++-
14
target/riscv/machine.c | 1 +
15
3 files changed, 9 insertions(+), 1 deletion(-)
16
17
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.h
20
+++ b/target/riscv/cpu.h
21
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
22
uint32_t scounteren;
23
uint32_t mcounteren;
24
25
+ uint32_t scountinhibit;
26
uint32_t mcountinhibit;
27
28
/* PMU cycle & instret privilege mode filtering */
29
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu_bits.h
32
+++ b/target/riscv/cpu_bits.h
33
@@ -XXX,XX +XXX,XX @@
34
#define CSR_SSTATEEN2 0x10E
35
#define CSR_SSTATEEN3 0x10F
36
37
+/* Supervisor Counter Delegation */
38
+#define CSR_SCOUNTINHIBIT 0x120
39
+
40
/* Supervisor Trap Handling */
41
#define CSR_SSCRATCH 0x140
42
#define CSR_SEPC 0x141
43
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
44
#define MENVCFG_CBCFE BIT(6)
45
#define MENVCFG_CBZE BIT(7)
46
#define MENVCFG_PMM (3ULL << 32)
47
+#define MENVCFG_CDE (1ULL << 60)
48
#define MENVCFG_ADUE (1ULL << 61)
49
#define MENVCFG_PBMTE (1ULL << 62)
50
#define MENVCFG_STCE (1ULL << 63)
51
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
52
#define ISELECT_IMSIC_LAST ISELECT_IMSIC_EIE63
53
#define ISELECT_MASK_AIA 0x1ff
54
55
-/* MISELECT, SISELECT, and VSISELECT bits (AIA) */
56
+/* [M|S|VS]SELCT value for Indirect CSR Access Extension */
57
+#define ISELECT_CD_FIRST 0x40
58
+#define ISELECT_CD_LAST 0x5f
59
#define ISELECT_MASK_SXCSRIND 0xfff
60
61
/* Dummy [M|S|VS]ISELECT value for emulating [M|S|VS]TOPEI CSRs */
62
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
63
index XXXXXXX..XXXXXXX 100644
64
--- a/target/riscv/machine.c
65
+++ b/target/riscv/machine.c
66
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
67
VMSTATE_UINTTL(env.siselect, RISCVCPU),
68
VMSTATE_UINT32(env.scounteren, RISCVCPU),
69
VMSTATE_UINT32(env.mcounteren, RISCVCPU),
70
+ VMSTATE_UINT32(env.scountinhibit, RISCVCPU),
71
VMSTATE_UINT32(env.mcountinhibit, RISCVCPU),
72
VMSTATE_STRUCT_ARRAY(env.pmu_ctrs, RISCVCPU, RV_MAX_MHPMCOUNTERS, 0,
73
vmstate_pmu_ctr_state, PMUCTRState),
74
--
75
2.48.1
diff view generated by jsdifflib
1
From: Kaiwen Xue <kaiwenx@rivosinc.com>
2
3
This adds checks in ops performed on xireg and xireg2-xireg6 so that the
4
counter delegation function will receive a valid xiselect value with the
5
proper extensions enabled.
6
7
Co-developed-by: Atish Patra <atishp@rivosinc.com>
8
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Atish Patra <atishp@rivosinc.com>
11
Message-ID: <20250110-counter_delegation-v5-7-e83d797ae294@rivosinc.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
---
13
---
3
include/hw/riscv/sifive_e.h | 1 +
14
target/riscv/csr.c | 36 +++++++++++++++++++++++++++++++++++-
4
hw/riscv/sifive_e.c | 34 ++++++++++++++++++++++++++++++----
15
1 file changed, 35 insertions(+), 1 deletion(-)
5
2 files changed, 31 insertions(+), 4 deletions(-)
6
16
7
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
17
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
8
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
9
--- a/include/hw/riscv/sifive_e.h
19
--- a/target/riscv/csr.c
10
+++ b/include/hw/riscv/sifive_e.h
20
+++ b/target/riscv/csr.c
11
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveEState {
21
@@ -XXX,XX +XXX,XX @@ static bool xiselect_aia_range(target_ulong isel)
12
22
(ISELECT_IMSIC_FIRST <= isel && isel <= ISELECT_IMSIC_LAST);
13
/*< public >*/
14
SiFiveESoCState soc;
15
+ bool revb;
16
} SiFiveEState;
17
18
#define TYPE_RISCV_E_MACHINE MACHINE_TYPE_NAME("sifive_e")
19
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/riscv/sifive_e.c
22
+++ b/hw/riscv/sifive_e.c
23
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
24
memmap[SIFIVE_E_DTIM].base, main_mem);
25
26
/* Mask ROM reset vector */
27
- uint32_t reset_vec[2] = {
28
- 0x204002b7, /* 0x1000: lui t0,0x20400 */
29
- 0x00028067, /* 0x1004: jr t0 */
30
- };
31
+ uint32_t reset_vec[2];
32
+
33
+ if (s->revb) {
34
+ reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
35
+ } else {
36
+ reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
37
+ }
38
+ reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
39
40
/* copy in the reset vector in little_endian byte order */
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
42
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
43
}
44
}
23
}
45
24
46
+static bool sifive_e_machine_get_revb(Object *obj, Error **errp)
25
+static bool xiselect_cd_range(target_ulong isel)
47
+{
26
+{
48
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
27
+ return (ISELECT_CD_FIRST <= isel && isel <= ISELECT_CD_LAST);
49
+
50
+ return s->revb;
51
+}
28
+}
52
+
29
+
53
+static void sifive_e_machine_set_revb(Object *obj, bool value, Error **errp)
30
static int rmw_iprio(target_ulong xlen,
31
target_ulong iselect, uint8_t *iprio,
32
target_ulong *val, target_ulong new_val,
33
@@ -XXX,XX +XXX,XX @@ done:
34
return RISCV_EXCP_NONE;
35
}
36
37
+static int rmw_xireg_cd(CPURISCVState *env, int csrno,
38
+ target_ulong isel, target_ulong *val,
39
+ target_ulong new_val, target_ulong wr_mask)
54
+{
40
+{
55
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
41
+ if (!riscv_cpu_cfg(env)->ext_smcdeleg) {
56
+
42
+ return RISCV_EXCP_ILLEGAL_INST;
57
+ s->revb = value;
43
+ }
44
+ /* TODO: Implement the functionality later */
45
+ return RISCV_EXCP_NONE;
58
+}
46
+}
59
+
47
+
60
static void sifive_e_machine_instance_init(Object *obj)
48
/*
49
* rmw_xireg_csrind: Perform indirect access to xireg and xireg2-xireg6
50
*
51
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg_csrind(CPURISCVState *env, int csrno,
52
target_ulong isel, target_ulong *val,
53
target_ulong new_val, target_ulong wr_mask)
61
{
54
{
62
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
55
- return -EINVAL;
56
+ int ret = -EINVAL;
57
+ bool virt = csrno == CSR_VSIREG ? true : false;
63
+
58
+
64
+ s->revb = false;
59
+ if (xiselect_cd_range(isel)) {
65
+ object_property_add_bool(obj, "revb", sifive_e_machine_get_revb,
60
+ ret = rmw_xireg_cd(env, csrno, isel, val, new_val, wr_mask);
66
+ sifive_e_machine_set_revb);
61
+ } else {
67
+ object_property_set_description(obj, "revb",
62
+ /*
68
+ "Set on to tell QEMU that it should model "
63
+ * As per the specification, access to unimplented region is undefined
69
+ "the revB HiFive1 board");
64
+ * but recommendation is to raise illegal instruction exception.
65
+ */
66
+ return RISCV_EXCP_ILLEGAL_INST;
67
+ }
68
+
69
+ if (ret) {
70
+ return (env->virt_enabled && virt) ?
71
+ RISCV_EXCP_VIRT_INSTRUCTION_FAULT : RISCV_EXCP_ILLEGAL_INST;
72
+ }
73
+
74
+ return RISCV_EXCP_NONE;
70
}
75
}
71
76
72
static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
77
static int rmw_xiregi(CPURISCVState *env, int csrno, target_ulong *val,
73
--
78
--
74
2.27.0
79
2.48.1
75
76
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Kaiwen Xue <kaiwenx@rivosinc.com>
2
2
3
On SiFive FU540 SoC, the value stored at physical address 0x1000
3
The Smcdeleg/Ssccfg adds the support for counter delegation via
4
stores the MSEL pin state that is used to control the next boot
4
S*indcsr and Ssccfg.
5
location that ROM codes jump to.
6
5
7
Add a new property msel to sifive_u machine for this.
6
It also adds a new shadow CSR scountinhibit and menvcfg enable bit (CDE)
7
to enable this extension and scountovf virtualization.
8
8
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Signed-off-by: Kaiwen Xue <kaiwenx@rivosinc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Co-developed-by: Atish Patra <atishp@rivosinc.com>
11
Message-id: 1591625864-31494-12-git-send-email-bmeng.cn@gmail.com
11
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Message-Id: <1591625864-31494-12-git-send-email-bmeng.cn@gmail.com>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Atish Patra <atishp@rivosinc.com>
14
Message-ID: <20250110-counter_delegation-v5-8-e83d797ae294@rivosinc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
16
---
15
include/hw/riscv/sifive_u.h | 1 +
17
target/riscv/csr.c | 304 +++++++++++++++++++++++++++++++++++++++++++--
16
hw/riscv/sifive_u.c | 7 +++++++
18
1 file changed, 292 insertions(+), 12 deletions(-)
17
2 files changed, 8 insertions(+)
18
19
19
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
20
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/riscv/sifive_u.h
22
--- a/target/riscv/csr.c
22
+++ b/include/hw/riscv/sifive_u.h
23
+++ b/target/riscv/csr.c
23
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUState {
24
@@ -XXX,XX +XXX,XX @@ static RISCVException aia_smode32(CPURISCVState *env, int csrno)
24
int fdt_size;
25
return smode32(env, csrno);
25
26
}
26
bool start_in_flash;
27
27
+ uint32_t msel;
28
+static RISCVException scountinhibit_pred(CPURISCVState *env, int csrno)
28
uint32_t serial;
29
+{
29
} SiFiveUState;
30
+ RISCVCPU *cpu = env_archcpu(env);
30
31
+
31
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
32
+ if (!cpu->cfg.ext_ssccfg || !cpu->cfg.ext_smcdeleg) {
32
index XXXXXXX..XXXXXXX 100644
33
+ return RISCV_EXCP_ILLEGAL_INST;
33
--- a/hw/riscv/sifive_u.c
34
+ }
34
+++ b/hw/riscv/sifive_u.c
35
+
35
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
36
+ if (env->virt_enabled) {
36
"Set on to tell QEMU's ROM to jump to "
37
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
37
"flash. Otherwise QEMU will jump to DRAM");
38
+ }
38
39
+
39
+ s->msel = 0;
40
+ return smode(env, csrno);
40
+ object_property_add(obj, "msel", "uint32",
41
+}
41
+ sifive_u_machine_get_uint32_prop,
42
+
42
+ sifive_u_machine_set_uint32_prop, NULL, &s->msel);
43
static bool csrind_extensions_present(CPURISCVState *env)
43
+ object_property_set_description(obj, "msel",
44
{
44
+ "Mode Select (MSEL[3:0]) pin state");
45
return riscv_cpu_cfg(env)->ext_smcsrind || riscv_cpu_cfg(env)->ext_sscsrind;
45
+
46
@@ -XXX,XX +XXX,XX @@ done:
46
s->serial = OTP_SERIAL;
47
return result;
47
object_property_add(obj, "serial", "uint32",
48
}
48
sifive_u_machine_get_uint32_prop,
49
50
-static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
51
- target_ulong val)
52
+static RISCVException riscv_pmu_write_ctr(CPURISCVState *env, target_ulong val,
53
+ uint32_t ctr_idx)
54
{
55
- int ctr_idx = csrno - CSR_MCYCLE;
56
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
57
uint64_t mhpmctr_val = val;
58
59
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mhpmcounter(CPURISCVState *env, int csrno,
60
return RISCV_EXCP_NONE;
61
}
62
63
-static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
64
- target_ulong val)
65
+static RISCVException riscv_pmu_write_ctrh(CPURISCVState *env, target_ulong val,
66
+ uint32_t ctr_idx)
67
{
68
- int ctr_idx = csrno - CSR_MCYCLEH;
69
PMUCTRState *counter = &env->pmu_ctrs[ctr_idx];
70
uint64_t mhpmctr_val = counter->mhpmcounter_val;
71
uint64_t mhpmctrh_val = val;
72
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mhpmcounterh(CPURISCVState *env, int csrno,
73
return RISCV_EXCP_NONE;
74
}
75
76
+static int write_mhpmcounter(CPURISCVState *env, int csrno, target_ulong val)
77
+{
78
+ int ctr_idx = csrno - CSR_MCYCLE;
79
+
80
+ return riscv_pmu_write_ctr(env, val, ctr_idx);
81
+}
82
+
83
+static int write_mhpmcounterh(CPURISCVState *env, int csrno, target_ulong val)
84
+{
85
+ int ctr_idx = csrno - CSR_MCYCLEH;
86
+
87
+ return riscv_pmu_write_ctrh(env, val, ctr_idx);
88
+}
89
+
90
RISCVException riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
91
bool upper_half, uint32_t ctr_idx)
92
{
93
@@ -XXX,XX +XXX,XX @@ static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
94
return riscv_pmu_read_ctr(env, val, true, ctr_index);
95
}
96
97
+static int rmw_cd_mhpmcounter(CPURISCVState *env, int ctr_idx,
98
+ target_ulong *val, target_ulong new_val,
99
+ target_ulong wr_mask)
100
+{
101
+ if (wr_mask != 0 && wr_mask != -1) {
102
+ return -EINVAL;
103
+ }
104
+
105
+ if (!wr_mask && val) {
106
+ riscv_pmu_read_ctr(env, val, false, ctr_idx);
107
+ } else if (wr_mask) {
108
+ riscv_pmu_write_ctr(env, new_val, ctr_idx);
109
+ } else {
110
+ return -EINVAL;
111
+ }
112
+
113
+ return 0;
114
+}
115
+
116
+static int rmw_cd_mhpmcounterh(CPURISCVState *env, int ctr_idx,
117
+ target_ulong *val, target_ulong new_val,
118
+ target_ulong wr_mask)
119
+{
120
+ if (wr_mask != 0 && wr_mask != -1) {
121
+ return -EINVAL;
122
+ }
123
+
124
+ if (!wr_mask && val) {
125
+ riscv_pmu_read_ctr(env, val, true, ctr_idx);
126
+ } else if (wr_mask) {
127
+ riscv_pmu_write_ctrh(env, new_val, ctr_idx);
128
+ } else {
129
+ return -EINVAL;
130
+ }
131
+
132
+ return 0;
133
+}
134
+
135
+static int rmw_cd_mhpmevent(CPURISCVState *env, int evt_index,
136
+ target_ulong *val, target_ulong new_val,
137
+ target_ulong wr_mask)
138
+{
139
+ uint64_t mhpmevt_val = new_val;
140
+
141
+ if (wr_mask != 0 && wr_mask != -1) {
142
+ return -EINVAL;
143
+ }
144
+
145
+ if (!wr_mask && val) {
146
+ *val = env->mhpmevent_val[evt_index];
147
+ if (riscv_cpu_cfg(env)->ext_sscofpmf) {
148
+ *val &= ~MHPMEVENT_BIT_MINH;
149
+ }
150
+ } else if (wr_mask) {
151
+ wr_mask &= ~MHPMEVENT_BIT_MINH;
152
+ mhpmevt_val = (new_val & wr_mask) |
153
+ (env->mhpmevent_val[evt_index] & ~wr_mask);
154
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
155
+ mhpmevt_val = mhpmevt_val |
156
+ ((uint64_t)env->mhpmeventh_val[evt_index] << 32);
157
+ }
158
+ env->mhpmevent_val[evt_index] = mhpmevt_val;
159
+ riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
160
+ } else {
161
+ return -EINVAL;
162
+ }
163
+
164
+ return 0;
165
+}
166
+
167
+static int rmw_cd_mhpmeventh(CPURISCVState *env, int evt_index,
168
+ target_ulong *val, target_ulong new_val,
169
+ target_ulong wr_mask)
170
+{
171
+ uint64_t mhpmevth_val;
172
+ uint64_t mhpmevt_val = env->mhpmevent_val[evt_index];
173
+
174
+ if (wr_mask != 0 && wr_mask != -1) {
175
+ return -EINVAL;
176
+ }
177
+
178
+ if (!wr_mask && val) {
179
+ *val = env->mhpmeventh_val[evt_index];
180
+ if (riscv_cpu_cfg(env)->ext_sscofpmf) {
181
+ *val &= ~MHPMEVENTH_BIT_MINH;
182
+ }
183
+ } else if (wr_mask) {
184
+ wr_mask &= ~MHPMEVENTH_BIT_MINH;
185
+ env->mhpmeventh_val[evt_index] =
186
+ (new_val & wr_mask) | (env->mhpmeventh_val[evt_index] & ~wr_mask);
187
+ mhpmevth_val = env->mhpmeventh_val[evt_index];
188
+ mhpmevt_val = mhpmevt_val | (mhpmevth_val << 32);
189
+ riscv_pmu_update_event_map(env, mhpmevt_val, evt_index);
190
+ } else {
191
+ return -EINVAL;
192
+ }
193
+
194
+ return 0;
195
+}
196
+
197
+static int rmw_cd_ctr_cfg(CPURISCVState *env, int cfg_index, target_ulong *val,
198
+ target_ulong new_val, target_ulong wr_mask)
199
+{
200
+ switch (cfg_index) {
201
+ case 0: /* CYCLECFG */
202
+ if (wr_mask) {
203
+ wr_mask &= ~MCYCLECFG_BIT_MINH;
204
+ env->mcyclecfg = (new_val & wr_mask) | (env->mcyclecfg & ~wr_mask);
205
+ } else {
206
+ *val = env->mcyclecfg &= ~MHPMEVENTH_BIT_MINH;
207
+ }
208
+ break;
209
+ case 2: /* INSTRETCFG */
210
+ if (wr_mask) {
211
+ wr_mask &= ~MINSTRETCFG_BIT_MINH;
212
+ env->minstretcfg = (new_val & wr_mask) |
213
+ (env->minstretcfg & ~wr_mask);
214
+ } else {
215
+ *val = env->minstretcfg &= ~MHPMEVENTH_BIT_MINH;
216
+ }
217
+ break;
218
+ default:
219
+ return -EINVAL;
220
+ }
221
+ return 0;
222
+}
223
+
224
+static int rmw_cd_ctr_cfgh(CPURISCVState *env, int cfg_index, target_ulong *val,
225
+ target_ulong new_val, target_ulong wr_mask)
226
+{
227
+
228
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
229
+ return RISCV_EXCP_ILLEGAL_INST;
230
+ }
231
+
232
+ switch (cfg_index) {
233
+ case 0: /* CYCLECFGH */
234
+ if (wr_mask) {
235
+ wr_mask &= ~MCYCLECFGH_BIT_MINH;
236
+ env->mcyclecfgh = (new_val & wr_mask) |
237
+ (env->mcyclecfgh & ~wr_mask);
238
+ } else {
239
+ *val = env->mcyclecfgh;
240
+ }
241
+ break;
242
+ case 2: /* INSTRETCFGH */
243
+ if (wr_mask) {
244
+ wr_mask &= ~MINSTRETCFGH_BIT_MINH;
245
+ env->minstretcfgh = (new_val & wr_mask) |
246
+ (env->minstretcfgh & ~wr_mask);
247
+ } else {
248
+ *val = env->minstretcfgh;
249
+ }
250
+ break;
251
+ default:
252
+ return -EINVAL;
253
+ }
254
+ return 0;
255
+}
256
+
257
+
258
static RISCVException read_scountovf(CPURISCVState *env, int csrno,
259
target_ulong *val)
260
{
261
@@ -XXX,XX +XXX,XX @@ static RISCVException read_scountovf(CPURISCVState *env, int csrno,
262
target_ulong *mhpm_evt_val;
263
uint64_t of_bit_mask;
264
265
+ /* Virtualize scountovf for counter delegation */
266
+ if (riscv_cpu_cfg(env)->ext_sscofpmf &&
267
+ riscv_cpu_cfg(env)->ext_ssccfg &&
268
+ get_field(env->menvcfg, MENVCFG_CDE) &&
269
+ env->virt_enabled) {
270
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
271
+ }
272
+
273
if (riscv_cpu_mxl(env) == MXL_RV32) {
274
mhpm_evt_val = env->mhpmeventh_val;
275
of_bit_mask = MHPMEVENTH_BIT_OF;
276
@@ -XXX,XX +XXX,XX @@ static int rmw_xireg_cd(CPURISCVState *env, int csrno,
277
target_ulong isel, target_ulong *val,
278
target_ulong new_val, target_ulong wr_mask)
279
{
280
- if (!riscv_cpu_cfg(env)->ext_smcdeleg) {
281
- return RISCV_EXCP_ILLEGAL_INST;
282
+ int ret = -EINVAL;
283
+ int ctr_index = isel - ISELECT_CD_FIRST;
284
+ int isel_hpm_start = ISELECT_CD_FIRST + 3;
285
+
286
+ if (!riscv_cpu_cfg(env)->ext_smcdeleg || !riscv_cpu_cfg(env)->ext_ssccfg) {
287
+ ret = RISCV_EXCP_ILLEGAL_INST;
288
+ goto done;
289
}
290
- /* TODO: Implement the functionality later */
291
- return RISCV_EXCP_NONE;
292
+
293
+ /* Invalid siselect value for reserved */
294
+ if (ctr_index == 1) {
295
+ goto done;
296
+ }
297
+
298
+ /* sireg4 and sireg5 provides access RV32 only CSRs */
299
+ if (((csrno == CSR_SIREG5) || (csrno == CSR_SIREG4)) &&
300
+ (riscv_cpu_mxl(env) != MXL_RV32)) {
301
+ ret = RISCV_EXCP_ILLEGAL_INST;
302
+ goto done;
303
+ }
304
+
305
+ /* Check Sscofpmf dependancy */
306
+ if (!riscv_cpu_cfg(env)->ext_sscofpmf && csrno == CSR_SIREG5 &&
307
+ (isel_hpm_start <= isel && isel <= ISELECT_CD_LAST)) {
308
+ goto done;
309
+ }
310
+
311
+ /* Check smcntrpmf dependancy */
312
+ if (!riscv_cpu_cfg(env)->ext_smcntrpmf &&
313
+ (csrno == CSR_SIREG2 || csrno == CSR_SIREG5) &&
314
+ (ISELECT_CD_FIRST <= isel && isel < isel_hpm_start)) {
315
+ goto done;
316
+ }
317
+
318
+ if (!get_field(env->mcounteren, BIT(ctr_index)) ||
319
+ !get_field(env->menvcfg, MENVCFG_CDE)) {
320
+ goto done;
321
+ }
322
+
323
+ switch (csrno) {
324
+ case CSR_SIREG:
325
+ ret = rmw_cd_mhpmcounter(env, ctr_index, val, new_val, wr_mask);
326
+ break;
327
+ case CSR_SIREG4:
328
+ ret = rmw_cd_mhpmcounterh(env, ctr_index, val, new_val, wr_mask);
329
+ break;
330
+ case CSR_SIREG2:
331
+ if (ctr_index <= 2) {
332
+ ret = rmw_cd_ctr_cfg(env, ctr_index, val, new_val, wr_mask);
333
+ } else {
334
+ ret = rmw_cd_mhpmevent(env, ctr_index, val, new_val, wr_mask);
335
+ }
336
+ break;
337
+ case CSR_SIREG5:
338
+ if (ctr_index <= 2) {
339
+ ret = rmw_cd_ctr_cfgh(env, ctr_index, val, new_val, wr_mask);
340
+ } else {
341
+ ret = rmw_cd_mhpmeventh(env, ctr_index, val, new_val, wr_mask);
342
+ }
343
+ break;
344
+ default:
345
+ goto done;
346
+ }
347
+
348
+done:
349
+ return ret;
350
}
351
352
/*
353
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
354
return RISCV_EXCP_NONE;
355
}
356
357
+static RISCVException read_scountinhibit(CPURISCVState *env, int csrno,
358
+ target_ulong *val)
359
+{
360
+ /* S-mode can only access the bits delegated by M-mode */
361
+ *val = env->mcountinhibit & env->mcounteren;
362
+ return RISCV_EXCP_NONE;
363
+}
364
+
365
+static RISCVException write_scountinhibit(CPURISCVState *env, int csrno,
366
+ target_ulong val)
367
+{
368
+ write_mcountinhibit(env, csrno, val & env->mcounteren);
369
+ return RISCV_EXCP_NONE;
370
+}
371
+
372
static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
373
target_ulong *val)
374
{
375
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
376
target_ulong val)
377
{
378
const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
379
- uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE;
380
+ uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE |
381
+ MENVCFG_CBZE | MENVCFG_CDE;
382
383
if (riscv_cpu_mxl(env) == MXL_RV64) {
384
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
385
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
386
+ (cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
387
(cfg->ext_svadu ? MENVCFG_ADUE : 0);
388
389
if (env_archcpu(env)->cfg.ext_zicfilp) {
390
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
391
const RISCVCPUConfig *cfg = riscv_cpu_cfg(env);
392
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
393
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
394
- (cfg->ext_svadu ? MENVCFG_ADUE : 0);
395
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0) |
396
+ (cfg->ext_smcdeleg ? MENVCFG_CDE : 0);
397
uint64_t valh = (uint64_t)val << 32;
398
399
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
400
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
401
[CSR_MNSTATUS] = { "mnstatus", rnmi, read_mnstatus, write_mnstatus,
402
.min_priv_ver = PRIV_VERSION_1_12_0 },
403
404
+ /* Supervisor Counter Delegation */
405
+ [CSR_SCOUNTINHIBIT] = {"scountinhibit", scountinhibit_pred,
406
+ read_scountinhibit, write_scountinhibit,
407
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
408
+
409
/* Supervisor Trap Setup */
410
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
411
NULL, read_sstatus_i128 },
49
--
412
--
50
2.27.0
413
2.48.1
51
52
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
There is no need to retrieve all PLIC IRQ information in order to
3
The dependant ISA features are enabled at the end of cpu_realize
4
just connect the GEM IRQ. Use qdev_get_gpio_in() directly like
4
in finalize_features. Thus, PMU init should be invoked after that
5
what is done for other peripherals.
5
only. Move the init invocation to riscv_tcg_cpu_finalize_features.
6
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-4-git-send-email-bmeng.cn@gmail.com
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <1591625864-31494-4-git-send-email-bmeng.cn@gmail.com>
9
Message-ID: <20250110-counter_delegation-v5-9-e83d797ae294@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
hw/riscv/sifive_u.c | 7 +------
12
target/riscv/tcg/tcg-cpu.c | 28 ++++++++++++++--------------
14
1 file changed, 1 insertion(+), 6 deletions(-)
13
1 file changed, 14 insertions(+), 14 deletions(-)
15
14
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
15
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
17
--- a/target/riscv/tcg/tcg-cpu.c
19
+++ b/hw/riscv/sifive_u.c
18
+++ b/target/riscv/tcg/tcg-cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
19
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
21
MemoryRegion *system_memory = get_system_memory();
20
error_propagate(errp, local_err);
22
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
21
return;
23
MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
22
}
24
- qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
23
+#ifndef CONFIG_USER_ONLY
25
char *plic_hart_config;
24
+ if (cpu->cfg.pmu_mask) {
26
size_t plic_hart_config_len;
25
+ riscv_pmu_init(cpu, &local_err);
27
int i;
26
+ if (local_err != NULL) {
28
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
27
+ error_propagate(errp, local_err);
29
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
28
+ return;
30
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
29
+ }
31
30
+
32
- for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
31
+ if (cpu->cfg.ext_sscofpmf) {
33
- plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
32
+ cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
33
+ riscv_pmu_timer_cb, cpu);
34
+ }
35
+ }
36
+#endif
37
}
38
39
void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
40
@@ -XXX,XX +XXX,XX @@ static bool riscv_tcg_cpu_realize(CPUState *cs, Error **errp)
41
42
#ifndef CONFIG_USER_ONLY
43
CPURISCVState *env = &cpu->env;
44
- Error *local_err = NULL;
45
46
tcg_cflags_set(CPU(cs), CF_PCREL);
47
48
@@ -XXX,XX +XXX,XX @@ static bool riscv_tcg_cpu_realize(CPUState *cs, Error **errp)
49
riscv_timer_init(cpu);
50
}
51
52
- if (cpu->cfg.pmu_mask) {
53
- riscv_pmu_init(cpu, &local_err);
54
- if (local_err != NULL) {
55
- error_propagate(errp, local_err);
56
- return false;
57
- }
58
-
59
- if (cpu->cfg.ext_sscofpmf) {
60
- cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
61
- riscv_pmu_timer_cb, cpu);
62
- }
34
- }
63
- }
35
-
64
-
36
if (nd->used) {
65
/* With H-Ext, VSSIP, VSTIP, VSEIP and SGEIP are hardwired to one. */
37
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
66
if (riscv_has_ext(env, RVH)) {
38
qdev_set_nic_properties(DEVICE(&s->gem), nd);
67
env->mideleg = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP | MIP_SGEIP;
39
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
40
}
41
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_GEM].base);
42
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
43
- plic_gpios[SIFIVE_U_GEM_IRQ]);
44
+ qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_GEM_IRQ));
45
46
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
47
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
48
--
68
--
49
2.27.0
69
2.48.1
50
51
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
There is no need to have two functions that have almost the same
3
The counter delegation/configuration extensions depend on the following
4
codes for 32-bit and 64-bit gcsu CPUs.
4
extensions.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
1. Smcdeleg - To enable counter delegation from M to S
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
2. S[m|s]csrind - To enable indirect access CSRs
8
Message-Id: <1591837729-27486-2-git-send-email-bmeng.cn@gmail.com>
8
9
Add an implied rule so that these extensions are enabled by default
10
if the sscfg extension is enabled.
11
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Atish Patra <atishp@rivosinc.com>
15
Message-ID: <20250110-counter_delegation-v5-10-e83d797ae294@rivosinc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
17
---
11
target/riscv/cpu.c | 20 ++++++--------------
18
target/riscv/cpu.c | 12 +++++++++++-
12
1 file changed, 6 insertions(+), 14 deletions(-)
19
1 file changed, 11 insertions(+), 1 deletion(-)
13
20
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
21
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
23
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
24
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
25
@@ -XXX,XX +XXX,XX @@ static RISCVCPUImpliedExtsRule ZVKSG_IMPLIED = {
19
set_resetvec(env, DEFAULT_RSTVEC);
26
},
20
}
27
};
21
28
22
-#if defined(TARGET_RISCV32)
29
+static RISCVCPUImpliedExtsRule SSCFG_IMPLIED = {
23
-
30
+ .ext = CPU_CFG_OFFSET(ext_ssccfg),
24
-static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
31
+ .implied_multi_exts = {
25
+static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
32
+ CPU_CFG_OFFSET(ext_smcsrind), CPU_CFG_OFFSET(ext_sscsrind),
26
{
33
+ CPU_CFG_OFFSET(ext_smcdeleg),
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
28
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
30
set_priv_version(env, PRIV_VERSION_1_10_0);
31
set_resetvec(env, DEFAULT_RSTVEC);
32
}
33
34
+#if defined(TARGET_RISCV32)
35
+
34
+
36
static void rv32imcu_nommu_cpu_init(Object *obj)
35
+ RISCV_IMPLIED_EXTS_RULE_END
37
{
36
+ },
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
37
+};
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
38
+
40
39
RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
41
#elif defined(TARGET_RISCV64)
40
&RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
42
41
&RVM_IMPLIED, &RVV_IMPLIED, NULL
43
-static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
42
@@ -XXX,XX +XXX,XX @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
44
-{
43
&ZVE64X_IMPLIED, &ZVFBFMIN_IMPLIED, &ZVFBFWMA_IMPLIED,
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
44
&ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
46
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
45
&ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
47
- set_priv_version(env, PRIV_VERSION_1_10_0);
46
- &ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED,
48
- set_resetvec(env, DEFAULT_RSTVEC);
47
+ &ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SSCFG_IMPLIED,
49
-}
48
NULL
50
-
51
static void rv64imacu_nommu_cpu_init(Object *obj)
52
{
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
55
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
56
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
57
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
58
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
59
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
60
#elif defined(TARGET_RISCV64)
61
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
63
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
64
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
65
#endif
66
};
49
};
67
50
68
--
51
--
69
2.27.0
52
2.48.1
70
71
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Atish Patra <atishp@rivosinc.com>
2
2
3
Current IBEX CPU init routine name seems to be too generic.
3
Add configuration options so that they can be enabled/disabld from
4
Since it uses a different reset vector from the generic one,
4
qemu commandline.
5
it merits a dedicated name.
6
5
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-id: 1592268641-7478-2-git-send-email-bmeng.cn@gmail.com
8
Signed-off-by: Atish Patra <atishp@rivosinc.com>
10
Message-Id: <1592268641-7478-2-git-send-email-bmeng.cn@gmail.com>
9
Message-ID: <20250110-counter_delegation-v5-11-e83d797ae294@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/cpu.c | 4 ++--
12
target/riscv/cpu.c | 4 ++++
14
1 file changed, 2 insertions(+), 2 deletions(-)
13
1 file changed, 4 insertions(+)
15
14
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu.c
17
--- a/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
21
20
/* Defaults for standard extensions */
22
#if defined(TARGET_RISCV32)
21
MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
23
22
MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
24
-static void rv32_imcu_nommu_cpu_init(Object *obj)
23
+ MULTI_EXT_CFG_BOOL("smcsrind", ext_smcsrind, false),
25
+static void rv32_ibex_cpu_init(Object *obj)
24
+ MULTI_EXT_CFG_BOOL("smcdeleg", ext_smcdeleg, false),
26
{
25
+ MULTI_EXT_CFG_BOOL("sscsrind", ext_sscsrind, false),
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
26
+ MULTI_EXT_CFG_BOOL("ssccfg", ext_ssccfg, false),
28
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
27
MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
29
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
28
MULTI_EXT_CFG_BOOL("zicfilp", ext_zicfilp, false),
30
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
29
MULTI_EXT_CFG_BOOL("zicfiss", ext_zicfiss, false),
31
#if defined(TARGET_RISCV32)
32
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
33
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
34
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
35
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
36
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
37
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
38
--
30
--
39
2.27.0
31
2.48.1
40
41
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
In prepration to add more properties to this machine, rename the
3
With the current implementation, if we had the following scenario:
4
existing serial property get/set functions to a generic name.
4
- Set bit x in menvcfg
5
- Set bit x in henvcfg
6
- Clear bit x in menvcfg
7
then, the internal variable env->henvcfg would still contain bit x due
8
to both a wrong menvcfg mask used in write_henvcfg() as well as a
9
missing update of henvcfg upon menvcfg update.
10
This can lead to some wrong interpretation of the context. In order to
11
update henvcfg upon menvcfg writing, call write_henvcfg() after writing
12
menvcfg. Clearing henvcfg upon writing the new value is also needed in
13
write_henvcfg() as well as clearing henvcfg upper part when writing it
14
with write_henvcfgh().
5
15
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
16
Signed-off-by: Clément Léger <cleger@rivosinc.com>
17
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591625864-31494-11-git-send-email-bmeng.cn@gmail.com
19
Message-ID: <20250110125441.3208676-2-cleger@rivosinc.com>
9
Message-Id: <1591625864-31494-11-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
21
---
12
hw/riscv/sifive_u.c | 14 ++++++++------
22
target/riscv/csr.c | 10 ++++++++--
13
1 file changed, 8 insertions(+), 6 deletions(-)
23
1 file changed, 8 insertions(+), 2 deletions(-)
14
24
15
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
25
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/sifive_u.c
27
--- a/target/riscv/csr.c
18
+++ b/hw/riscv/sifive_u.c
28
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error *
29
@@ -XXX,XX +XXX,XX @@ static RISCVException read_menvcfg(CPURISCVState *env, int csrno,
20
s->start_in_flash = value;
30
return RISCV_EXCP_NONE;
21
}
31
}
22
32
23
-static void sifive_u_machine_get_serial(Object *obj, Visitor *v, const char *name,
33
+static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
24
- void *opaque, Error **errp)
34
+ target_ulong val);
25
+static void sifive_u_machine_get_uint32_prop(Object *obj, Visitor *v,
35
static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
26
+ const char *name, void *opaque,
36
target_ulong val)
27
+ Error **errp)
28
{
37
{
29
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
38
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
39
}
40
}
41
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
42
+ write_henvcfg(env, CSR_HENVCFG, env->henvcfg);
43
44
return RISCV_EXCP_NONE;
30
}
45
}
31
46
@@ -XXX,XX +XXX,XX @@ static RISCVException read_menvcfgh(CPURISCVState *env, int csrno,
32
-static void sifive_u_machine_set_serial(Object *obj, Visitor *v, const char *name,
47
return RISCV_EXCP_NONE;
33
- void *opaque, Error **errp)
48
}
34
+static void sifive_u_machine_set_uint32_prop(Object *obj, Visitor *v,
49
35
+ const char *name, void *opaque,
50
+static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
36
+ Error **errp)
51
+ target_ulong val);
52
static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
53
target_ulong val)
37
{
54
{
38
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
55
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
56
uint64_t valh = (uint64_t)val << 32;
57
58
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
59
+ write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32);
60
61
return RISCV_EXCP_NONE;
39
}
62
}
40
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
63
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
41
64
}
42
s->serial = OTP_SERIAL;
65
}
43
object_property_add(obj, "serial", "uint32",
66
44
- sifive_u_machine_get_serial,
67
- env->henvcfg = (env->henvcfg & ~mask) | (val & mask);
45
- sifive_u_machine_set_serial, NULL, &s->serial);
68
+ env->henvcfg = val & mask;
46
+ sifive_u_machine_get_uint32_prop,
69
47
+ sifive_u_machine_set_uint32_prop, NULL, &s->serial);
70
return RISCV_EXCP_NONE;
48
object_property_set_description(obj, "serial", "Board serial number");
49
}
71
}
72
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
73
return ret;
74
}
75
76
- env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
77
+ env->henvcfg = (env->henvcfg & 0xFFFFFFFF) | (valh & mask);
78
return RISCV_EXCP_NONE;
79
}
50
80
51
--
81
--
52
2.27.0
82
2.48.1
53
83
54
84
diff view generated by jsdifflib
1
From: Ian Jiang <ianjiang.ict@gmail.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
The function that makes NaN-boxing when a 32-bit value is assigned
3
Add ext_ssdbltrp in RISCVCPUConfig and implement MSTATUS.SDT,
4
to a 64-bit FP register is split out to a helper gen_nanbox_fpr().
4
{H|M}ENVCFG.DTE and modify the availability of MTVAL2 based on the
5
Then it is applied in translating of the FLW instruction.
5
presence of the Ssdbltrp ISA extension.
6
6
7
Signed-off-by: Ian Jiang <ianjiang.ict@gmail.com>
7
Signed-off-by: Clément Léger <cleger@rivosinc.com>
8
Message-Id: <20200128003707.17028-1-ianjiang.ict@gmail.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-ID: <20250110125441.3208676-3-cleger@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
target/riscv/insn_trans/trans_rvf.inc.c | 17 +++++++++++++++--
13
target/riscv/cpu.h | 1 +
14
1 file changed, 15 insertions(+), 2 deletions(-)
14
target/riscv/cpu_bits.h | 6 ++++
15
15
target/riscv/cpu_cfg.h | 1 +
16
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c
16
target/riscv/cpu_helper.c | 17 ++++++++++
17
index XXXXXXX..XXXXXXX 100644
17
target/riscv/csr.c | 71 ++++++++++++++++++++++++++++++++-------
18
--- a/target/riscv/insn_trans/trans_rvf.inc.c
18
5 files changed, 84 insertions(+), 12 deletions(-)
19
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
19
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
24
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_virt_enabled(CPURISCVState *env, bool enable);
25
int riscv_env_mmu_index(CPURISCVState *env, bool ifetch);
26
bool cpu_get_fcfien(CPURISCVState *env);
27
bool cpu_get_bcfien(CPURISCVState *env);
28
+bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt);
29
G_NORETURN void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
30
MMUAccessType access_type,
31
int mmu_idx, uintptr_t retaddr);
32
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/cpu_bits.h
35
+++ b/target/riscv/cpu_bits.h
20
@@ -XXX,XX +XXX,XX @@
36
@@ -XXX,XX +XXX,XX @@
21
return false; \
37
#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
22
} while (0)
38
#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
23
39
#define MSTATUS_SPELP 0x00800000 /* zicfilp */
24
+/*
40
+#define MSTATUS_SDT 0x01000000
25
+ * RISC-V requires NaN-boxing of narrower width floating
41
#define MSTATUS_MPELP 0x020000000000 /* zicfilp */
26
+ * point values. This applies when a 32-bit value is
42
#define MSTATUS_GVA 0x4000000000ULL
27
+ * assigned to a 64-bit FP register. Thus this does not
43
#define MSTATUS_MPV 0x8000000000ULL
28
+ * apply when the RVD extension is not present.
44
@@ -XXX,XX +XXX,XX @@ typedef enum {
29
+ */
45
#define SSTATUS_SUM 0x00040000 /* since: priv-1.10 */
30
+static void gen_nanbox_fpr(DisasContext *ctx, int regno)
46
#define SSTATUS_MXR 0x00080000
47
#define SSTATUS_SPELP MSTATUS_SPELP /* zicfilp */
48
+#define SSTATUS_SDT MSTATUS_SDT
49
50
#define SSTATUS64_UXL 0x0000000300000000ULL
51
52
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
53
#define MENVCFG_CBCFE BIT(6)
54
#define MENVCFG_CBZE BIT(7)
55
#define MENVCFG_PMM (3ULL << 32)
56
+#define MENVCFG_DTE (1ULL << 59)
57
#define MENVCFG_CDE (1ULL << 60)
58
#define MENVCFG_ADUE (1ULL << 61)
59
#define MENVCFG_PBMTE (1ULL << 62)
60
#define MENVCFG_STCE (1ULL << 63)
61
62
/* For RV32 */
63
+#define MENVCFGH_DTE BIT(27)
64
#define MENVCFGH_ADUE BIT(29)
65
#define MENVCFGH_PBMTE BIT(30)
66
#define MENVCFGH_STCE BIT(31)
67
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
68
#define HENVCFG_CBCFE MENVCFG_CBCFE
69
#define HENVCFG_CBZE MENVCFG_CBZE
70
#define HENVCFG_PMM MENVCFG_PMM
71
+#define HENVCFG_DTE MENVCFG_DTE
72
#define HENVCFG_ADUE MENVCFG_ADUE
73
#define HENVCFG_PBMTE MENVCFG_PBMTE
74
#define HENVCFG_STCE MENVCFG_STCE
75
76
/* For RV32 */
77
+#define HENVCFGH_DTE MENVCFGH_DTE
78
#define HENVCFGH_ADUE MENVCFGH_ADUE
79
#define HENVCFGH_PBMTE MENVCFGH_PBMTE
80
#define HENVCFGH_STCE MENVCFGH_STCE
81
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
82
index XXXXXXX..XXXXXXX 100644
83
--- a/target/riscv/cpu_cfg.h
84
+++ b/target/riscv/cpu_cfg.h
85
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
86
bool ext_smcntrpmf;
87
bool ext_smcsrind;
88
bool ext_sscsrind;
89
+ bool ext_ssdbltrp;
90
bool ext_svadu;
91
bool ext_svinval;
92
bool ext_svnapot;
93
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/target/riscv/cpu_helper.c
96
+++ b/target/riscv/cpu_helper.c
97
@@ -XXX,XX +XXX,XX @@ bool cpu_get_bcfien(CPURISCVState *env)
98
}
99
}
100
101
+bool riscv_env_smode_dbltrp_enabled(CPURISCVState *env, bool virt)
31
+{
102
+{
32
+ if (has_ext(ctx, RVD)) {
103
+#ifdef CONFIG_USER_ONLY
33
+ tcg_gen_ori_i64(cpu_fpr[regno], cpu_fpr[regno],
104
+ return false;
34
+ MAKE_64BIT_MASK(32, 32));
105
+#else
35
+ }
106
+ if (virt) {
107
+ return (env->henvcfg & HENVCFG_DTE) != 0;
108
+ } else {
109
+ return (env->menvcfg & MENVCFG_DTE) != 0;
110
+ }
111
+#endif
36
+}
112
+}
37
+
113
+
38
static bool trans_flw(DisasContext *ctx, arg_flw *a)
114
void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
115
uint64_t *cs_base, uint32_t *pflags)
39
{
116
{
40
TCGv t0 = tcg_temp_new();
117
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
41
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
118
42
tcg_gen_addi_tl(t0, t0, a->imm);
119
g_assert(riscv_has_ext(env, RVH));
43
120
44
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
121
+ if (riscv_env_smode_dbltrp_enabled(env, current_virt)) {
45
- /* RISC-V requires NaN-boxing of narrower width floating point values */
122
+ mstatus_mask |= MSTATUS_SDT;
46
- tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xffffffff00000000ULL);
123
+ }
47
+ gen_nanbox_fpr(ctx, a->rd);
124
+
48
125
if (current_virt) {
49
tcg_temp_free(t0);
126
/* Current V=1 and we are about to change to V=0 */
50
mark_fs_dirty(ctx);
127
env->vsstatus = env->mstatus & mstatus_mask;
128
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
129
index XXXXXXX..XXXXXXX 100644
130
--- a/target/riscv/csr.c
131
+++ b/target/riscv/csr.c
132
@@ -XXX,XX +XXX,XX @@ static RISCVException aia_hmode32(CPURISCVState *env, int csrno)
133
return hmode32(env, csrno);
134
}
135
136
+static RISCVException dbltrp_hmode(CPURISCVState *env, int csrno)
137
+{
138
+ if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
139
+ return RISCV_EXCP_NONE;
140
+ }
141
+
142
+ return hmode(env, csrno);
143
+}
144
+
145
static RISCVException pmp(CPURISCVState *env, int csrno)
146
{
147
if (riscv_cpu_cfg(env)->pmp) {
148
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
149
mask |= MSTATUS_VS;
150
}
151
152
+ if (riscv_env_smode_dbltrp_enabled(env, env->virt_enabled)) {
153
+ mask |= MSTATUS_SDT;
154
+ if ((val & MSTATUS_SDT) != 0) {
155
+ val &= ~MSTATUS_SIE;
156
+ }
157
+ }
158
+
159
if (xl != MXL_RV32 || env->debugger) {
160
if (riscv_has_ext(env, RVH)) {
161
mask |= MSTATUS_MPV | MSTATUS_GVA;
162
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
163
mask |= (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
164
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
165
(cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
166
- (cfg->ext_svadu ? MENVCFG_ADUE : 0);
167
+ (cfg->ext_svadu ? MENVCFG_ADUE : 0) |
168
+ (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
169
170
if (env_archcpu(env)->cfg.ext_zicfilp) {
171
mask |= MENVCFG_LPE;
172
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfg(CPURISCVState *env, int csrno,
173
if (env_archcpu(env)->cfg.ext_smnpm &&
174
get_field(val, MENVCFG_PMM) != PMM_FIELD_RESERVED) {
175
mask |= MENVCFG_PMM;
176
+    }
177
+
178
+ if ((val & MENVCFG_DTE) == 0) {
179
+ env->mstatus &= ~MSTATUS_SDT;
180
}
181
}
182
env->menvcfg = (env->menvcfg & ~mask) | (val & mask);
183
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
184
uint64_t mask = (cfg->ext_svpbmt ? MENVCFG_PBMTE : 0) |
185
(cfg->ext_sstc ? MENVCFG_STCE : 0) |
186
(cfg->ext_svadu ? MENVCFG_ADUE : 0) |
187
- (cfg->ext_smcdeleg ? MENVCFG_CDE : 0);
188
+ (cfg->ext_smcdeleg ? MENVCFG_CDE : 0) |
189
+ (cfg->ext_ssdbltrp ? MENVCFG_DTE : 0);
190
uint64_t valh = (uint64_t)val << 32;
191
192
+ if ((valh & MENVCFG_DTE) == 0) {
193
+ env->mstatus &= ~MSTATUS_SDT;
194
+ }
195
+
196
env->menvcfg = (env->menvcfg & ~mask) | (valh & mask);
197
write_henvcfgh(env, CSR_HENVCFGH, env->henvcfg >> 32);
198
199
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
200
* henvcfg.pbmte is read_only 0 when menvcfg.pbmte = 0
201
* henvcfg.stce is read_only 0 when menvcfg.stce = 0
202
* henvcfg.adue is read_only 0 when menvcfg.adue = 0
203
+ * henvcfg.dte is read_only 0 when menvcfg.dte = 0
204
*/
205
- *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
206
- env->menvcfg);
207
+ *val = env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
208
+ HENVCFG_DTE) | env->menvcfg);
209
return RISCV_EXCP_NONE;
210
}
211
212
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
213
}
214
215
if (riscv_cpu_mxl(env) == MXL_RV64) {
216
- mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE);
217
+ mask |= env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
218
+ HENVCFG_DTE);
219
220
if (env_archcpu(env)->cfg.ext_zicfilp) {
221
mask |= HENVCFG_LPE;
222
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
223
}
224
225
env->henvcfg = val & mask;
226
+ if ((env->henvcfg & HENVCFG_DTE) == 0) {
227
+ env->vsstatus &= ~MSTATUS_SDT;
228
+ }
229
230
return RISCV_EXCP_NONE;
231
}
232
@@ -XXX,XX +XXX,XX @@ static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
233
return ret;
234
}
235
236
- *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE) |
237
- env->menvcfg)) >> 32;
238
+ *val = (env->henvcfg & (~(HENVCFG_PBMTE | HENVCFG_STCE | HENVCFG_ADUE |
239
+ HENVCFG_DTE) | env->menvcfg)) >> 32;
240
return RISCV_EXCP_NONE;
241
}
242
243
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
244
target_ulong val)
245
{
246
uint64_t mask = env->menvcfg & (HENVCFG_PBMTE | HENVCFG_STCE |
247
- HENVCFG_ADUE);
248
+ HENVCFG_ADUE | HENVCFG_DTE);
249
uint64_t valh = (uint64_t)val << 32;
250
RISCVException ret;
251
252
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
253
if (ret != RISCV_EXCP_NONE) {
254
return ret;
255
}
256
-
257
env->henvcfg = (env->henvcfg & 0xFFFFFFFF) | (valh & mask);
258
+ if ((env->henvcfg & HENVCFG_DTE) == 0) {
259
+ env->vsstatus &= ~MSTATUS_SDT;
260
+ }
261
return RISCV_EXCP_NONE;
262
}
263
264
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
265
if (env->xl != MXL_RV32 || env->debugger) {
266
mask |= SSTATUS64_UXL;
267
}
268
+ if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
269
+ mask |= SSTATUS_SDT;
270
+ }
271
272
if (env_archcpu(env)->cfg.ext_zicfilp) {
273
mask |= SSTATUS_SPELP;
274
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
275
if (env_archcpu(env)->cfg.ext_zicfilp) {
276
mask |= SSTATUS_SPELP;
277
}
278
-
279
+ if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
280
+ mask |= SSTATUS_SDT;
281
+ }
282
/* TODO: Use SXL not MXL. */
283
*val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
284
return RISCV_EXCP_NONE;
285
@@ -XXX,XX +XXX,XX @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
286
if (env_archcpu(env)->cfg.ext_zicfilp) {
287
mask |= SSTATUS_SPELP;
288
}
289
-
290
+ if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
291
+ mask |= SSTATUS_SDT;
292
+ }
293
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
294
return write_mstatus(env, CSR_MSTATUS, newval);
295
}
296
@@ -XXX,XX +XXX,XX @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
297
if ((val & VSSTATUS64_UXL) == 0) {
298
mask &= ~VSSTATUS64_UXL;
299
}
300
+ if ((env->henvcfg & HENVCFG_DTE)) {
301
+ if ((val & SSTATUS_SDT) != 0) {
302
+ val &= ~SSTATUS_SIE;
303
+ }
304
+ } else {
305
+ val &= ~SSTATUS_SDT;
306
+ }
307
env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
308
return RISCV_EXCP_NONE;
309
}
310
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
311
[CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp,
312
.min_priv_ver = PRIV_VERSION_1_12_0 },
313
314
- [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2,
315
+ [CSR_MTVAL2] = { "mtval2", dbltrp_hmode, read_mtval2, write_mtval2,
316
.min_priv_ver = PRIV_VERSION_1_12_0 },
317
[CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst,
318
.min_priv_ver = PRIV_VERSION_1_12_0 },
51
--
319
--
52
2.27.0
320
2.48.1
53
321
54
322
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
Upstream U-Boot v2020.07 codes switch to access SiFive FU540 OTP
3
When the Ssdbltrp extension is enabled, SSTATUS.SDT field is cleared
4
based on device tree information. Let's generate the device tree
4
when executing sret. When executing mret/mnret, SSTATUS.SDT is cleared
5
node for OTP.
5
when returning to U, VS or VU and VSSTATUS.SDT is cleared when returning
6
to VU from HS.
6
7
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Signed-off-by: Clément Léger <cleger@rivosinc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-5-git-send-email-bmeng.cn@gmail.com
10
Message-ID: <20250110125441.3208676-4-cleger@rivosinc.com>
10
Message-Id: <1591625864-31494-5-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
12
---
13
hw/riscv/sifive_u.c | 11 +++++++++++
13
target/riscv/op_helper.c | 35 ++++++++++++++++++++++++++++++++++-
14
1 file changed, 11 insertions(+)
14
1 file changed, 34 insertions(+), 1 deletion(-)
15
15
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
16
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
18
--- a/target/riscv/op_helper.c
19
+++ b/hw/riscv/sifive_u.c
19
+++ b/target/riscv/op_helper.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
20
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
21
g_free(cells);
21
get_field(mstatus, MSTATUS_SPIE));
22
g_free(nodename);
22
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
23
23
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
24
+ nodename = g_strdup_printf("/soc/otp@%lx",
25
+ (long)memmap[SIFIVE_U_OTP].base);
26
+ qemu_fdt_add_subnode(fdt, nodename);
27
+ qemu_fdt_setprop_cell(fdt, nodename, "fuse-count", SIFIVE_U_OTP_REG_SIZE);
28
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
29
+ 0x0, memmap[SIFIVE_U_OTP].base,
30
+ 0x0, memmap[SIFIVE_U_OTP].size);
31
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
32
+ "sifive,fu540-c000-otp");
33
+ g_free(nodename);
34
+
24
+
35
prci_phandle = phandle++;
25
+ if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
36
nodename = g_strdup_printf("/soc/clock-controller@%lx",
26
+ if (riscv_has_ext(env, RVH)) {
37
(long)memmap[SIFIVE_U_PRCI].base);
27
+ target_ulong prev_vu = get_field(env->hstatus, HSTATUS_SPV) &&
28
+ prev_priv == PRV_U;
29
+ /* Returning to VU from HS, vsstatus.sdt = 0 */
30
+ if (!env->virt_enabled && prev_vu) {
31
+ env->vsstatus = set_field(env->vsstatus, MSTATUS_SDT, 0);
32
+ }
33
+ }
34
+ mstatus = set_field(mstatus, MSTATUS_SDT, 0);
35
+ }
36
if (env->priv_ver >= PRIV_VERSION_1_12_0) {
37
mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
38
}
39
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
40
target_ulong hstatus = env->hstatus;
41
42
prev_virt = get_field(hstatus, HSTATUS_SPV);
43
-
44
hstatus = set_field(hstatus, HSTATUS_SPV, 0);
45
46
env->hstatus = hstatus;
47
@@ -XXX,XX +XXX,XX @@ static void check_ret_from_m_mode(CPURISCVState *env, target_ulong retpc,
48
riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
49
}
50
}
51
+static target_ulong ssdbltrp_mxret(CPURISCVState *env, target_ulong mstatus,
52
+ target_ulong prev_priv,
53
+ target_ulong prev_virt)
54
+{
55
+ /* If returning to U, VS or VU, sstatus.sdt = 0 */
56
+ if (prev_priv == PRV_U || (prev_virt &&
57
+ (prev_priv == PRV_S || prev_priv == PRV_U))) {
58
+ mstatus = set_field(mstatus, MSTATUS_SDT, 0);
59
+ /* If returning to VU, vsstatus.sdt = 0 */
60
+ if (prev_virt && prev_priv == PRV_U) {
61
+ env->vsstatus = set_field(env->vsstatus, MSTATUS_SDT, 0);
62
+ }
63
+ }
64
+
65
+ return mstatus;
66
+}
67
68
target_ulong helper_mret(CPURISCVState *env)
69
{
70
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
71
mstatus = set_field(mstatus, MSTATUS_MPP,
72
riscv_has_ext(env, RVU) ? PRV_U : PRV_M);
73
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
74
+ if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
75
+ mstatus = ssdbltrp_mxret(env, mstatus, prev_priv, prev_virt);
76
+ }
77
if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
78
mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
79
}
80
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mnret(CPURISCVState *env)
81
if (prev_priv < PRV_M) {
82
env->mstatus = set_field(env->mstatus, MSTATUS_MPRV, false);
83
}
84
+ if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
85
+ env->mstatus = ssdbltrp_mxret(env, env->mstatus, prev_priv, prev_virt);
86
+ }
87
88
if (riscv_has_ext(env, RVH) && prev_virt) {
89
riscv_cpu_swap_hypervisor_regs(env);
38
--
90
--
39
2.27.0
91
2.48.1
40
92
41
93
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
At present the GPIO output IRQs are triggered each time any GPIO
3
When the Ssdbltrp ISA extension is enabled, if a trap happens in S-mode
4
register is written. However this is not correct. We should only
4
while SSTATUS.SDT isn't cleared, generate a double trap exception to
5
trigger the output IRQ when the pin is configured as output enable.
5
M-mode.
6
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Clément Léger <cleger@rivosinc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-9-git-send-email-bmeng.cn@gmail.com
9
Message-ID: <20250110125441.3208676-5-cleger@rivosinc.com>
10
Message-Id: <1591625864-31494-9-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
hw/riscv/sifive_gpio.c | 4 +++-
12
target/riscv/cpu_bits.h | 1 +
14
1 file changed, 3 insertions(+), 1 deletion(-)
13
target/riscv/cpu.c | 2 +-
14
target/riscv/cpu_helper.c | 42 ++++++++++++++++++++++++++++++++++-----
15
3 files changed, 39 insertions(+), 6 deletions(-)
15
16
16
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
17
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_gpio.c
19
--- a/target/riscv/cpu_bits.h
19
+++ b/hw/riscv/sifive_gpio.c
20
+++ b/target/riscv/cpu_bits.h
20
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
21
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
21
actual_value = pull;
22
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
23
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
24
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
25
+ RISCV_EXCP_DOUBLE_TRAP = 0x10,
26
RISCV_EXCP_SW_CHECK = 0x12, /* since: priv-1.13.0 */
27
RISCV_EXCP_HW_ERR = 0x13, /* since: priv-1.13.0 */
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static const char * const riscv_excp_names[] = {
34
"load_page_fault",
35
"reserved",
36
"store_page_fault",
37
- "reserved",
38
+ "double_trap",
39
"reserved",
40
"reserved",
41
"reserved",
42
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/cpu_helper.c
45
+++ b/target/riscv/cpu_helper.c
46
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
47
bool virt = env->virt_enabled;
48
bool write_gva = false;
49
bool always_storeamo = (env->excp_uw2 & RISCV_UW2_ALWAYS_STORE_AMO);
50
+ bool vsmode_exc;
51
uint64_t s;
52
int mode;
53
54
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
55
!(env->mip & (1ULL << cause));
56
bool vs_injected = env->hvip & (1ULL << cause) & env->hvien &&
57
!(env->mip & (1ULL << cause));
58
+ bool smode_double_trap = false;
59
+ uint64_t hdeleg = async ? env->hideleg : env->hedeleg;
60
target_ulong tval = 0;
61
target_ulong tinst = 0;
62
target_ulong htval = 0;
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
64
mode = env->priv <= PRV_S && cause < 64 &&
65
(((deleg >> cause) & 1) || s_injected || vs_injected) ? PRV_S : PRV_M;
66
67
+ vsmode_exc = env->virt_enabled && (((hdeleg >> cause) & 1) || vs_injected);
68
+ /*
69
+ * Check double trap condition only if already in S-mode and targeting
70
+ * S-mode
71
+ */
72
+ if (cpu->cfg.ext_ssdbltrp && env->priv == PRV_S && mode == PRV_S) {
73
+ bool dte = (env->menvcfg & MENVCFG_DTE) != 0;
74
+ bool sdt = (env->mstatus & MSTATUS_SDT) != 0;
75
+ /* In VS or HS */
76
+ if (riscv_has_ext(env, RVH)) {
77
+ if (vsmode_exc) {
78
+ /* VS -> VS, use henvcfg instead of menvcfg*/
79
+ dte = (env->henvcfg & HENVCFG_DTE) != 0;
80
+ } else if (env->virt_enabled) {
81
+ /* VS -> HS, use mstatus_hs */
82
+ sdt = (env->mstatus_hs & MSTATUS_SDT) != 0;
83
+ }
84
+ }
85
+ smode_double_trap = dte && sdt;
86
+ if (smode_double_trap) {
87
+ mode = PRV_M;
88
+ }
89
+ }
90
+
91
if (mode == PRV_S) {
92
/* handle the trap in S-mode */
93
/* save elp status */
94
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
22
}
95
}
23
96
24
- qemu_set_irq(s->output[i], actual_value);
97
if (riscv_has_ext(env, RVH)) {
25
+ if (output_en) {
98
- uint64_t hdeleg = async ? env->hideleg : env->hedeleg;
26
+ qemu_set_irq(s->output[i], actual_value);
99
-
100
- if (env->virt_enabled &&
101
- (((hdeleg >> cause) & 1) || vs_injected)) {
102
+ if (vsmode_exc) {
103
/* Trap to VS mode */
104
/*
105
* See if we need to adjust cause. Yes if its VS mode interrupt
106
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
107
s = set_field(s, MSTATUS_SPIE, get_field(s, MSTATUS_SIE));
108
s = set_field(s, MSTATUS_SPP, env->priv);
109
s = set_field(s, MSTATUS_SIE, 0);
110
+ if (riscv_env_smode_dbltrp_enabled(env, virt)) {
111
+ s = set_field(s, MSTATUS_SDT, 1);
27
+ }
112
+ }
28
113
env->mstatus = s;
29
/* Input value */
114
sxlen = 16 << riscv_cpu_sxl(env);
30
ival = input_en && actual_value;
115
env->scause = cause | ((target_ulong)async << (sxlen - 1));
116
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
117
s = set_field(s, MSTATUS_MIE, 0);
118
env->mstatus = s;
119
env->mcause = cause | ((target_ulong)async << (mxlen - 1));
120
+ if (smode_double_trap) {
121
+ env->mtval2 = env->mcause;
122
+ env->mcause = RISCV_EXCP_DOUBLE_TRAP;
123
+ } else {
124
+ env->mtval2 = mtval2;
125
+ }
126
env->mepc = env->pc;
127
env->mtval = tval;
128
- env->mtval2 = mtval2;
129
env->mtinst = tinst;
130
131
/*
31
--
132
--
32
2.27.0
133
2.48.1
33
134
34
135
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
There is no need to have two functions that have almost the same
3
Add the switch to enable the Ssdbltrp ISA extension.
4
codes for 32-bit and 64-bit imacu CPUs.
5
4
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
5
Signed-off-by: Clément Léger <cleger@rivosinc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <1591837729-27486-3-git-send-email-bmeng.cn@gmail.com>
7
Message-ID: <20250110125441.3208676-6-cleger@rivosinc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
9
---
11
target/riscv/cpu.c | 31 ++++++++++---------------------
10
target/riscv/cpu.c | 2 ++
12
1 file changed, 10 insertions(+), 21 deletions(-)
11
1 file changed, 2 insertions(+)
13
12
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
15
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
17
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
19
set_resetvec(env, DEFAULT_RSTVEC);
18
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
20
}
19
ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
21
20
ISA_EXT_DATA_ENTRY(sscsrind, PRIV_VERSION_1_12_0, ext_sscsrind),
22
-#if defined(TARGET_RISCV32)
21
+ ISA_EXT_DATA_ENTRY(ssdbltrp, PRIV_VERSION_1_13_0, ext_ssdbltrp),
23
-
22
ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_13_0, ext_ssnpm),
24
-static void rv32imcu_nommu_cpu_init(Object *obj)
23
ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
25
+static void rvxx_imacu_nommu_cpu_init(Object *obj)
24
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
26
{
25
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
26
MULTI_EXT_CFG_BOOL("smnpm", ext_smnpm, false),
28
- set_misa(env, RV32 | RVI | RVM | RVC | RVU);
27
MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
28
MULTI_EXT_CFG_BOOL("ssaia", ext_ssaia, false),
30
set_priv_version(env, PRIV_VERSION_1_10_0);
29
+ MULTI_EXT_CFG_BOOL("ssdbltrp", ext_ssdbltrp, false),
31
- set_resetvec(env, 0x8090);
30
MULTI_EXT_CFG_BOOL("svade", ext_svade, false),
32
+ set_resetvec(env, DEFAULT_RSTVEC);
31
MULTI_EXT_CFG_BOOL("svadu", ext_svadu, true),
33
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
32
MULTI_EXT_CFG_BOOL("svinval", ext_svinval, false),
34
}
35
36
-static void rv32imacu_nommu_cpu_init(Object *obj)
37
+#if defined(TARGET_RISCV32)
38
+
39
+static void rv32imcu_nommu_cpu_init(Object *obj)
40
{
41
CPURISCVState *env = &RISCV_CPU(obj)->env;
42
- set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
43
+ set_misa(env, RV32 | RVI | RVM | RVC | RVU);
44
set_priv_version(env, PRIV_VERSION_1_10_0);
45
- set_resetvec(env, DEFAULT_RSTVEC);
46
+ set_resetvec(env, 0x8090);
47
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
51
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
52
}
53
54
-#elif defined(TARGET_RISCV64)
55
-
56
-static void rv64imacu_nommu_cpu_init(Object *obj)
57
-{
58
- CPURISCVState *env = &RISCV_CPU(obj)->env;
59
- set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
60
- set_priv_version(env, PRIV_VERSION_1_10_0);
61
- set_resetvec(env, DEFAULT_RSTVEC);
62
- qdev_prop_set_bit(DEVICE(obj), "mmu", false);
63
-}
64
-
65
#endif
66
67
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
68
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
69
#if defined(TARGET_RISCV32)
70
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
71
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
72
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
73
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
74
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
75
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
76
#elif defined(TARGET_RISCV64)
77
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
78
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
79
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
80
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
81
#endif
82
};
83
--
33
--
84
2.27.0
34
2.48.1
85
35
86
36
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
SiFive FU540 SoC integrates a GPIO controller with 16 GPIO lines.
3
Add `ext_smdbltrp`in RISCVCPUConfig and implement MSTATUS.MDT behavior.
4
This hooks the exsiting SiFive GPIO model to the SoC, and adds its
4
Also set MDT to 1 at reset according to the specification.
5
device tree data as well.
6
5
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Clément Léger <cleger@rivosinc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 1591625864-31494-8-git-send-email-bmeng.cn@gmail.com
8
Message-ID: <20250110125441.3208676-7-cleger@rivosinc.com>
10
Message-Id: <1591625864-31494-8-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
10
---
13
include/hw/riscv/sifive_u.h | 19 ++++++++++++++++
11
target/riscv/cpu_bits.h | 1 +
14
hw/riscv/sifive_u.c | 43 +++++++++++++++++++++++++++++++++++--
12
target/riscv/cpu_cfg.h | 1 +
15
2 files changed, 60 insertions(+), 2 deletions(-)
13
target/riscv/cpu.c | 3 +++
14
target/riscv/csr.c | 13 +++++++++++++
15
4 files changed, 18 insertions(+)
16
16
17
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
17
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/sifive_u.h
19
--- a/target/riscv/cpu_bits.h
20
+++ b/include/hw/riscv/sifive_u.h
20
+++ b/target/riscv/cpu_bits.h
21
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@
22
#include "hw/net/cadence_gem.h"
22
#define MSTATUS_MPELP 0x020000000000 /* zicfilp */
23
#include "hw/riscv/riscv_hart.h"
23
#define MSTATUS_GVA 0x4000000000ULL
24
#include "hw/riscv/sifive_cpu.h"
24
#define MSTATUS_MPV 0x8000000000ULL
25
+#include "hw/riscv/sifive_gpio.h"
25
+#define MSTATUS_MDT 0x40000000000ULL /* Smdbltrp extension */
26
#include "hw/riscv/sifive_u_prci.h"
26
27
#include "hw/riscv/sifive_u_otp.h"
27
#define MSTATUS64_UXL 0x0000000300000000ULL
28
28
#define MSTATUS64_SXL 0x0000000C00000000ULL
29
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUSoCState {
29
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
30
RISCVHartArrayState u_cpus;
31
DeviceState *plic;
32
SiFiveUPRCIState prci;
33
+ SIFIVEGPIOState gpio;
34
SiFiveUOTPState otp;
35
CadenceGEMState gem;
36
37
@@ -XXX,XX +XXX,XX @@ enum {
38
SIFIVE_U_PRCI,
39
SIFIVE_U_UART0,
40
SIFIVE_U_UART1,
41
+ SIFIVE_U_GPIO,
42
SIFIVE_U_OTP,
43
SIFIVE_U_FLASH0,
44
SIFIVE_U_DRAM,
45
@@ -XXX,XX +XXX,XX @@ enum {
46
enum {
47
SIFIVE_U_UART0_IRQ = 4,
48
SIFIVE_U_UART1_IRQ = 5,
49
+ SIFIVE_U_GPIO_IRQ0 = 7,
50
+ SIFIVE_U_GPIO_IRQ1 = 8,
51
+ SIFIVE_U_GPIO_IRQ2 = 9,
52
+ SIFIVE_U_GPIO_IRQ3 = 10,
53
+ SIFIVE_U_GPIO_IRQ4 = 11,
54
+ SIFIVE_U_GPIO_IRQ5 = 12,
55
+ SIFIVE_U_GPIO_IRQ6 = 13,
56
+ SIFIVE_U_GPIO_IRQ7 = 14,
57
+ SIFIVE_U_GPIO_IRQ8 = 15,
58
+ SIFIVE_U_GPIO_IRQ9 = 16,
59
+ SIFIVE_U_GPIO_IRQ10 = 17,
60
+ SIFIVE_U_GPIO_IRQ11 = 18,
61
+ SIFIVE_U_GPIO_IRQ12 = 19,
62
+ SIFIVE_U_GPIO_IRQ13 = 20,
63
+ SIFIVE_U_GPIO_IRQ14 = 21,
64
+ SIFIVE_U_GPIO_IRQ15 = 22,
65
SIFIVE_U_GEM_IRQ = 0x35
66
};
67
68
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
69
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/riscv/sifive_u.c
31
--- a/target/riscv/cpu_cfg.h
71
+++ b/hw/riscv/sifive_u.c
32
+++ b/target/riscv/cpu_cfg.h
72
@@ -XXX,XX +XXX,XX @@
33
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
73
* 1) CLINT (Core Level Interruptor)
34
bool ext_smcsrind;
74
* 2) PLIC (Platform Level Interrupt Controller)
35
bool ext_sscsrind;
75
* 3) PRCI (Power, Reset, Clock, Interrupt)
36
bool ext_ssdbltrp;
76
- * 4) OTP (One-Time Programmable) memory with stored serial number
37
+ bool ext_smdbltrp;
77
- * 5) GEM (Gigabit Ethernet Controller) and management block
38
bool ext_svadu;
78
+ * 4) GPIO (General Purpose Input/Output Controller)
39
bool ext_svinval;
79
+ * 5) OTP (One-Time Programmable) memory with stored serial number
40
bool ext_svnapot;
80
+ * 6) GEM (Gigabit Ethernet Controller) and management block
41
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
81
*
42
index XXXXXXX..XXXXXXX 100644
82
* This board currently generates devicetree dynamically that indicates at least
43
--- a/target/riscv/cpu.c
83
* two harts and up to five harts.
44
+++ b/target/riscv/cpu.c
84
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
45
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj, ResetType type)
85
[SIFIVE_U_PRCI] = { 0x10000000, 0x1000 },
46
env->mstatus_hs = set_field(env->mstatus_hs,
86
[SIFIVE_U_UART0] = { 0x10010000, 0x1000 },
47
MSTATUS64_UXL, env->misa_mxl);
87
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
48
}
88
+ [SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
49
+ if (riscv_cpu_cfg(env)->ext_smdbltrp) {
89
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
50
+ env->mstatus = set_field(env->mstatus, MSTATUS_MDT, 1);
90
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
51
+ }
91
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
52
}
92
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
53
env->mcause = 0;
93
g_free(cells);
54
env->miclaim = MIP_SGEIP;
94
g_free(nodename);
55
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
95
56
index XXXXXXX..XXXXXXX 100644
96
+ nodename = g_strdup_printf("/soc/gpio@%lx",
57
--- a/target/riscv/csr.c
97
+ (long)memmap[SIFIVE_U_GPIO].base);
58
+++ b/target/riscv/csr.c
98
+ qemu_fdt_add_subnode(fdt, nodename);
59
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
99
+ qemu_fdt_setprop_cells(fdt, nodename, "clocks",
60
}
100
+ prci_phandle, PRCI_CLK_TLCLK);
61
}
101
+ qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
62
102
+ qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
63
+ if (riscv_cpu_cfg(env)->ext_smdbltrp) {
103
+ qemu_fdt_setprop_cell(fdt, nodename, "#gpio-cells", 2);
64
+ mask |= MSTATUS_MDT;
104
+ qemu_fdt_setprop(fdt, nodename, "gpio-controller", NULL, 0);
65
+ if ((val & MSTATUS_MDT) != 0) {
105
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
66
+ val &= ~MSTATUS_MIE;
106
+ 0x0, memmap[SIFIVE_U_GPIO].base,
67
+ }
107
+ 0x0, memmap[SIFIVE_U_GPIO].size);
108
+ qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GPIO_IRQ0,
109
+ SIFIVE_U_GPIO_IRQ1, SIFIVE_U_GPIO_IRQ2, SIFIVE_U_GPIO_IRQ3,
110
+ SIFIVE_U_GPIO_IRQ4, SIFIVE_U_GPIO_IRQ5, SIFIVE_U_GPIO_IRQ6,
111
+ SIFIVE_U_GPIO_IRQ7, SIFIVE_U_GPIO_IRQ8, SIFIVE_U_GPIO_IRQ9,
112
+ SIFIVE_U_GPIO_IRQ10, SIFIVE_U_GPIO_IRQ11, SIFIVE_U_GPIO_IRQ12,
113
+ SIFIVE_U_GPIO_IRQ13, SIFIVE_U_GPIO_IRQ14, SIFIVE_U_GPIO_IRQ15);
114
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
115
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
116
+ g_free(nodename);
117
+
118
phy_phandle = phandle++;
119
nodename = g_strdup_printf("/soc/ethernet@%lx",
120
(long)memmap[SIFIVE_U_GEM].base);
121
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_instance_init(Object *obj)
122
object_initialize_child(obj, "prci", &s->prci, TYPE_SIFIVE_U_PRCI);
123
object_initialize_child(obj, "otp", &s->otp, TYPE_SIFIVE_U_OTP);
124
object_initialize_child(obj, "gem", &s->gem, TYPE_CADENCE_GEM);
125
+ object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
126
}
127
128
static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
129
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
130
sysbus_realize(SYS_BUS_DEVICE(&s->prci), &err);
131
sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base);
132
133
+ qdev_prop_set_uint32(DEVICE(&s->gpio), "ngpio", 16);
134
+ sysbus_realize(SYS_BUS_DEVICE(&s->gpio), &err);
135
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_U_GPIO].base);
136
+
137
+ /* Pass all GPIOs to the SOC layer so they are available to the board */
138
+ qdev_pass_gpios(DEVICE(&s->gpio), dev, NULL);
139
+
140
+ /* Connect GPIO interrupts to the PLIC */
141
+ for (i = 0; i < 16; i++) {
142
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), i,
143
+ qdev_get_gpio_in(DEVICE(s->plic),
144
+ SIFIVE_U_GPIO_IRQ0 + i));
145
+ }
68
+ }
146
+
69
+
147
qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
70
if (xl != MXL_RV32 || env->debugger) {
148
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
71
if (riscv_has_ext(env, RVH)) {
149
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
72
mask |= MSTATUS_MPV | MSTATUS_GVA;
73
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatush(CPURISCVState *env, int csrno,
74
uint64_t valh = (uint64_t)val << 32;
75
uint64_t mask = riscv_has_ext(env, RVH) ? MSTATUS_MPV | MSTATUS_GVA : 0;
76
77
+ if (riscv_cpu_cfg(env)->ext_smdbltrp) {
78
+ mask |= MSTATUS_MDT;
79
+ if ((valh & MSTATUS_MDT) != 0) {
80
+ mask |= MSTATUS_MIE;
81
+ }
82
+ }
83
env->mstatus = (env->mstatus & ~mask) | (valh & mask);
84
85
return RISCV_EXCP_NONE;
150
--
86
--
151
2.27.0
87
2.48.1
152
88
153
89
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
This was done in the virt & sifive_u codes, but sifive_e codes were
3
When the Ssdbltrp extension is enabled, SSTATUS.MDT field is cleared
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
4
when executing sret if executed in M-mode. When executing mret/mnret,
5
SSTATUS.MDT is cleared.
5
6
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Clément Léger <cleger@rivosinc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1591625864-31494-2-git-send-email-bmeng.cn@gmail.com
9
Message-ID: <20250110125441.3208676-8-cleger@rivosinc.com>
9
Message-Id: <1591625864-31494-2-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
hw/riscv/sifive_e.c | 24 ++++++++++++------------
12
target/riscv/op_helper.c | 12 ++++++++++++
13
1 file changed, 12 insertions(+), 12 deletions(-)
13
1 file changed, 12 insertions(+)
14
14
15
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
15
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/sifive_e.c
17
--- a/target/riscv/op_helper.c
18
+++ b/hw/riscv/sifive_e.c
18
+++ b/target/riscv/op_helper.c
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
19
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
20
[SIFIVE_E_DTIM] = { 0x80000000, 0x4000 }
20
}
21
};
21
mstatus = set_field(mstatus, MSTATUS_SDT, 0);
22
22
}
23
-static void riscv_sifive_e_init(MachineState *machine)
23
+ if (riscv_cpu_cfg(env)->ext_smdbltrp && env->priv >= PRV_M) {
24
+static void sifive_e_machine_init(MachineState *machine)
24
+ mstatus = set_field(mstatus, MSTATUS_MDT, 0);
25
{
25
+ }
26
const struct MemmapEntry *memmap = sifive_e_memmap;
26
if (env->priv_ver >= PRIV_VERSION_1_12_0) {
27
27
mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
28
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
28
}
29
MachineClass *mc = MACHINE_CLASS(oc);
29
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
30
30
if (riscv_cpu_cfg(env)->ext_ssdbltrp) {
31
mc->desc = "RISC-V Board compatible with SiFive E SDK";
31
mstatus = ssdbltrp_mxret(env, mstatus, prev_priv, prev_virt);
32
- mc->init = riscv_sifive_e_init;
32
}
33
+ mc->init = sifive_e_machine_init;
33
+ if (riscv_cpu_cfg(env)->ext_smdbltrp) {
34
mc->max_cpus = 1;
34
+ mstatus = set_field(mstatus, MSTATUS_MDT, 0);
35
mc->default_cpu_type = SIFIVE_E_CPU;
35
+ }
36
}
36
if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
37
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init_register_types(void)
37
mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
38
38
}
39
type_init(sifive_e_machine_init_register_types)
39
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mnret(CPURISCVState *env)
40
40
env->mstatus = ssdbltrp_mxret(env, env->mstatus, prev_priv, prev_virt);
41
-static void riscv_sifive_e_soc_init(Object *obj)
41
}
42
+static void sifive_e_soc_init(Object *obj)
42
43
{
43
+ if (riscv_cpu_cfg(env)->ext_smdbltrp) {
44
MachineState *ms = MACHINE(qdev_get_machine());
44
+ if (prev_priv < PRV_M) {
45
SiFiveESoCState *s = RISCV_E_SOC(obj);
45
+ env->mstatus = set_field(env->mstatus, MSTATUS_MDT, 0);
46
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_init(Object *obj)
46
+ }
47
TYPE_SIFIVE_GPIO);
47
+ }
48
}
48
+
49
49
if (riscv_has_ext(env, RVH) && prev_virt) {
50
-static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
50
riscv_cpu_swap_hypervisor_regs(env);
51
+static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
51
}
52
{
53
MachineState *ms = MACHINE(qdev_get_machine());
54
const struct MemmapEntry *memmap = sifive_e_memmap;
55
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
56
&s->xip_mem);
57
}
58
59
-static void riscv_sifive_e_soc_class_init(ObjectClass *oc, void *data)
60
+static void sifive_e_soc_class_init(ObjectClass *oc, void *data)
61
{
62
DeviceClass *dc = DEVICE_CLASS(oc);
63
64
- dc->realize = riscv_sifive_e_soc_realize;
65
+ dc->realize = sifive_e_soc_realize;
66
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
67
dc->user_creatable = false;
68
}
69
70
-static const TypeInfo riscv_sifive_e_soc_type_info = {
71
+static const TypeInfo sifive_e_soc_type_info = {
72
.name = TYPE_RISCV_E_SOC,
73
.parent = TYPE_DEVICE,
74
.instance_size = sizeof(SiFiveESoCState),
75
- .instance_init = riscv_sifive_e_soc_init,
76
- .class_init = riscv_sifive_e_soc_class_init,
77
+ .instance_init = sifive_e_soc_init,
78
+ .class_init = sifive_e_soc_class_init,
79
};
80
81
-static void riscv_sifive_e_soc_register_types(void)
82
+static void sifive_e_soc_register_types(void)
83
{
84
- type_register_static(&riscv_sifive_e_soc_type_info);
85
+ type_register_static(&sifive_e_soc_type_info);
86
}
87
88
-type_init(riscv_sifive_e_soc_register_types)
89
+type_init(sifive_e_soc_register_types)
90
--
52
--
91
2.27.0
53
2.48.1
92
54
93
55
diff view generated by jsdifflib
1
From: Clément Léger <cleger@rivosinc.com>
2
3
When the Smsdbltrp ISA extension is enabled, if a trap happens while
4
MSTATUS.MDT is already set, it will trigger an abort or an NMI is the
5
Smrnmi extension is available.
6
7
Signed-off-by: Clément Léger <cleger@rivosinc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20250110125441.3208676-9-cleger@rivosinc.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
3
---
11
---
4
target/riscv/cpu_helper.c | 2 +-
12
target/riscv/cpu_helper.c | 57 ++++++++++++++++++++++++++++-----------
5
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 41 insertions(+), 16 deletions(-)
6
14
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
8
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
9
--- a/target/riscv/cpu_helper.c
17
--- a/target/riscv/cpu_helper.c
10
+++ b/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
11
@@ -XXX,XX +XXX,XX @@ restart:
19
@@ -XXX,XX +XXX,XX @@ static target_ulong promote_load_fault(target_ulong orig_cause)
12
hwaddr vbase;
20
/* if no promotion, return original cause */
13
21
return orig_cause;
14
/* Do the second stage translation on the base PTE address. */
22
}
15
- get_physical_address(env, &vbase, &vbase_prot, base, access_type,
23
+
16
+ get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
24
+static void riscv_do_nmi(CPURISCVState *env, target_ulong cause, bool virt)
17
mmu_idx, false, true);
25
+{
18
26
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, false);
19
pte_addr = vbase + idx * ptesize;
27
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPV, virt);
28
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPP, env->priv);
29
+ env->mncause = cause;
30
+ env->mnepc = env->pc;
31
+ env->pc = env->rnmi_irqvec;
32
+
33
+ if (cpu_get_fcfien(env)) {
34
+ env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPELP, env->elp);
35
+ }
36
+
37
+ /* Trapping to M mode, virt is disabled */
38
+ riscv_cpu_set_mode(env, PRV_M, false);
39
+}
40
+
41
/*
42
* Handle Traps
43
*
44
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
45
bool nnmi_excep = false;
46
47
if (cpu->cfg.ext_smrnmi && env->rnmip && async) {
48
- env->mnstatus = set_field(env->mnstatus, MNSTATUS_NMIE, false);
49
- env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPV,
50
- env->virt_enabled);
51
- env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPP,
52
- env->priv);
53
- env->mncause = cause | ((target_ulong)1U << (mxlen - 1));
54
- env->mnepc = env->pc;
55
- env->pc = env->rnmi_irqvec;
56
-
57
- if (cpu_get_fcfien(env)) {
58
- env->mnstatus = set_field(env->mnstatus, MNSTATUS_MNPELP, env->elp);
59
- }
60
-
61
- /* Trapping to M mode, virt is disabled */
62
- riscv_cpu_set_mode(env, PRV_M, false);
63
-
64
+ riscv_do_nmi(env, cause | ((target_ulong)1U << (mxlen - 1)),
65
+ env->virt_enabled);
66
return;
67
}
68
69
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
70
/* Trapping to M mode, virt is disabled */
71
virt = false;
72
}
73
+ /*
74
+ * If the hart encounters an exception while executing in M-mode,
75
+ * with the mnstatus.NMIE bit clear, the program counter is set to
76
+ * the RNMI exception trap handler address.
77
+ */
78
+ nnmi_excep = cpu->cfg.ext_smrnmi &&
79
+ !get_field(env->mnstatus, MNSTATUS_NMIE) &&
80
+ !async;
81
82
s = env->mstatus;
83
s = set_field(s, MSTATUS_MPIE, get_field(s, MSTATUS_MIE));
84
s = set_field(s, MSTATUS_MPP, env->priv);
85
s = set_field(s, MSTATUS_MIE, 0);
86
+ if (cpu->cfg.ext_smdbltrp) {
87
+ if (env->mstatus & MSTATUS_MDT) {
88
+ assert(env->priv == PRV_M);
89
+ if (!cpu->cfg.ext_smrnmi || nnmi_excep) {
90
+ cpu_abort(CPU(cpu), "M-mode double trap\n");
91
+ } else {
92
+ riscv_do_nmi(env, cause, false);
93
+ return;
94
+ }
95
+ }
96
+
97
+ s = set_field(s, MSTATUS_MDT, 1);
98
+ }
99
env->mstatus = s;
100
env->mcause = cause | ((target_ulong)async << (mxlen - 1));
101
if (smode_double_trap) {
20
--
102
--
21
2.27.0
103
2.48.1
22
104
23
105
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
There is no need to have two functions that have exactly the same
3
Add the switch to enable the Smdbltrp ISA extension and disable it for
4
codes for 32-bit and 64-bit base CPUs.
4
the max cpu. Indeed, OpenSBI when Smdbltrp is present, M-mode double
5
trap is enabled by default and MSTATUS.MDT needs to be cleared to avoid
6
taking a double trap. OpenSBI does not currently support it so disable
7
it for the max cpu to avoid breaking regression tests.
5
8
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
Signed-off-by: Clément Léger <cleger@rivosinc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Message-id: 1591837729-27486-1-git-send-email-bmeng.cn@gmail.com
11
Message-ID: <20250116131539.2475785-1-cleger@rivosinc.com>
9
Message-Id: <1591837729-27486-1-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
13
---
12
target/riscv/cpu.c | 18 +++++-------------
14
target/riscv/cpu.c | 2 ++
13
1 file changed, 5 insertions(+), 13 deletions(-)
15
target/riscv/tcg/tcg-cpu.c | 10 ++++++++++
16
2 files changed, 12 insertions(+)
14
17
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
20
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
21
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj)
22
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
20
set_resetvec(env, DEFAULT_RSTVEC);
23
ISA_EXT_DATA_ENTRY(smcdeleg, PRIV_VERSION_1_13_0, ext_smcdeleg),
24
ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
25
ISA_EXT_DATA_ENTRY(smcsrind, PRIV_VERSION_1_13_0, ext_smcsrind),
26
+ ISA_EXT_DATA_ENTRY(smdbltrp, PRIV_VERSION_1_13_0, ext_smdbltrp),
27
ISA_EXT_DATA_ENTRY(smepmp, PRIV_VERSION_1_12_0, ext_smepmp),
28
ISA_EXT_DATA_ENTRY(smrnmi, PRIV_VERSION_1_12_0, ext_smrnmi),
29
ISA_EXT_DATA_ENTRY(smmpm, PRIV_VERSION_1_13_0, ext_smmpm),
30
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
31
MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false),
32
33
MULTI_EXT_CFG_BOOL("smaia", ext_smaia, false),
34
+ MULTI_EXT_CFG_BOOL("smdbltrp", ext_smdbltrp, false),
35
MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
36
MULTI_EXT_CFG_BOOL("smrnmi", ext_smrnmi, false),
37
MULTI_EXT_CFG_BOOL("smmpm", ext_smmpm, false),
38
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/tcg/tcg-cpu.c
41
+++ b/target/riscv/tcg/tcg-cpu.c
42
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
43
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_smrnmi), false);
44
qemu_log("Smrnmi is disabled in the 'max' type CPU\n");
45
}
46
+
47
+ /*
48
+ * ext_smdbltrp requires the firmware to clear MSTATUS.MDT on startup to
49
+ * avoid generating a double trap. OpenSBI does not currently support it,
50
+ * disable it for now.
51
+ */
52
+ if (cpu->cfg.ext_smdbltrp) {
53
+ isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_smdbltrp), false);
54
+ qemu_log("Smdbltrp is disabled in the 'max' type CPU\n");
55
+ }
21
}
56
}
22
57
23
-#if defined(TARGET_RISCV32)
58
static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
24
-
25
-static void riscv_base32_cpu_init(Object *obj)
26
+static void riscv_base_cpu_init(Object *obj)
27
{
28
CPURISCVState *env = &RISCV_CPU(obj)->env;
29
/* We set this in the realise function */
30
@@ -XXX,XX +XXX,XX @@ static void riscv_base32_cpu_init(Object *obj)
31
set_resetvec(env, DEFAULT_RSTVEC);
32
}
33
34
+#if defined(TARGET_RISCV32)
35
+
36
static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
37
{
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
40
41
#elif defined(TARGET_RISCV64)
42
43
-static void riscv_base64_cpu_init(Object *obj)
44
-{
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
46
- /* We set this in the realise function */
47
- set_misa(env, 0);
48
- set_resetvec(env, DEFAULT_RSTVEC);
49
-}
50
-
51
static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
52
{
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
55
},
56
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
57
#if defined(TARGET_RISCV32)
58
- DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
59
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
60
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
61
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
63
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
64
#elif defined(TARGET_RISCV64)
65
- DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
66
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
67
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
68
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
69
#endif
70
--
59
--
71
2.27.0
60
2.48.1
72
61
73
62
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
SiFive FU540 SoC supports booting from several sources, which are
3
This commit introduces a translation tag to avoid invalidating an entry
4
controlled using the Mode Select (MSEL[3:0]) pins on the chip.
4
that should not be invalidated when IOMMU executes invalidation commands.
5
Typically, the boot process runs through several stages before it
5
E.g. IOTINVAL.VMA with GV=0, AV=0, PSCV=1 invalidates both a mapping
6
begins execution of user-provided programs.
6
of single stage translation and a mapping of nested translation with
7
the same PSCID, but only the former one should be invalidated.
7
8
8
The SoC supports booting from memory-mapped QSPI flash, which is
9
Signed-off-by: Jason Chien <jason.chien@sifive.com>
9
how start_in_flash property is used for at present. This matches
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
MSEL = 1 configuration (QSPI0).
11
Message-ID: <20241108110147.11178-1-jason.chien@sifive.com>
11
12
Typical booting flows involve the Zeroth Stage Boot Loader (ZSBL).
13
It's not necessary for QEMU to implement the full ZSBL ROM codes,
14
because we know ZSBL downloads the next stage program into the L2
15
LIM at address 0x8000000 and executes from there. We can bypass
16
the whole ZSBL execution and use "-bios" to load the next stage
17
program directly if MSEL indicates a ZSBL booting flow.
18
19
Signed-off-by: Bin Meng <bin.meng@windriver.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-id: 1592268641-7478-4-git-send-email-bmeng.cn@gmail.com
22
Message-Id: <1592268641-7478-4-git-send-email-bmeng.cn@gmail.com>
23
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
---
13
---
25
include/hw/riscv/sifive_u.h | 6 ++++++
14
hw/riscv/riscv-iommu.c | 205 ++++++++++++++++++++++++++++++-----------
26
hw/riscv/sifive_u.c | 39 +++++++++++++++++++++++++++++--------
15
1 file changed, 153 insertions(+), 52 deletions(-)
27
2 files changed, 37 insertions(+), 8 deletions(-)
28
16
29
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
17
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/riscv/sifive_u.h
19
--- a/hw/riscv/riscv-iommu.c
32
+++ b/include/hw/riscv/sifive_u.h
20
+++ b/hw/riscv/riscv-iommu.c
33
@@ -XXX,XX +XXX,XX @@ enum {
21
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUContext {
34
SIFIVE_U_RTCCLK_FREQ = 1000000
22
uint64_t msiptp; /* MSI redirection page table pointer */
35
};
23
};
36
24
37
+enum {
25
+typedef enum RISCVIOMMUTransTag {
38
+ MSEL_MEMMAP_QSPI0_FLASH = 1,
26
+ RISCV_IOMMU_TRANS_TAG_BY, /* Bypass */
39
+ MSEL_L2LIM_QSPI0_FLASH = 6,
27
+ RISCV_IOMMU_TRANS_TAG_SS, /* Single Stage */
40
+ MSEL_L2LIM_QSPI2_SD = 11
28
+ RISCV_IOMMU_TRANS_TAG_VG, /* G-stage only */
41
+};
29
+ RISCV_IOMMU_TRANS_TAG_VN, /* Nested translation */
42
+
30
+} RISCVIOMMUTransTag;
43
#define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
31
+
44
#define SIFIVE_U_COMPUTE_CPU_COUNT 4
32
/* Address translation cache entry */
45
33
struct RISCVIOMMUEntry {
46
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
34
+ RISCVIOMMUTransTag tag; /* Translation Tag */
47
index XXXXXXX..XXXXXXX 100644
35
uint64_t iova:44; /* IOVA Page Number */
48
--- a/hw/riscv/sifive_u.c
36
uint64_t pscid:20; /* Process Soft-Context identifier */
49
+++ b/hw/riscv/sifive_u.c
37
uint64_t phys:44; /* Physical Page Number */
50
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
38
@@ -XXX,XX +XXX,XX @@ static gboolean riscv_iommu_iot_equal(gconstpointer v1, gconstpointer v2)
51
/* create device tree */
39
RISCVIOMMUEntry *t1 = (RISCVIOMMUEntry *) v1;
52
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
40
RISCVIOMMUEntry *t2 = (RISCVIOMMUEntry *) v2;
53
41
return t1->gscid == t2->gscid && t1->pscid == t2->pscid &&
54
- riscv_find_and_load_firmware(machine, BIOS_FILENAME,
42
- t1->iova == t2->iova;
55
- memmap[SIFIVE_U_DRAM].base, NULL);
43
+ t1->iova == t2->iova && t1->tag == t2->tag;
56
+ if (s->start_in_flash) {
44
}
57
+ /*
45
58
+ * If start_in_flash property is given, assign s->msel to a value
46
static guint riscv_iommu_iot_hash(gconstpointer v)
59
+ * that representing booting from QSPI0 memory-mapped flash.
47
@@ -XXX,XX +XXX,XX @@ static guint riscv_iommu_iot_hash(gconstpointer v)
60
+ *
48
return (guint)t->iova;
61
+ * This also means that when both start_in_flash and msel properties
49
}
62
+ * are given, start_in_flash takes the precedence over msel.
50
63
+ *
51
-/* GV: 1 PSCV: 1 AV: 1 */
64
+ * Note this is to keep backward compatibility not to break existing
52
+/* GV: 0 AV: 0 PSCV: 0 GVMA: 0 */
65
+ * users that use start_in_flash property.
53
+/* GV: 0 AV: 0 GVMA: 1 */
66
+ */
54
+static
67
+ s->msel = MSEL_MEMMAP_QSPI0_FLASH;
55
+void riscv_iommu_iot_inval_all(gpointer key, gpointer value, gpointer data)
68
+ }
56
+{
69
+
57
+ RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
70
+ switch (s->msel) {
58
+ RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
71
+ case MSEL_MEMMAP_QSPI0_FLASH:
59
+ if (iot->tag == arg->tag) {
72
+ start_addr = memmap[SIFIVE_U_FLASH0].base;
60
+ iot->perm = IOMMU_NONE;
73
+ break;
61
+ }
74
+ case MSEL_L2LIM_QSPI0_FLASH:
62
+}
75
+ case MSEL_L2LIM_QSPI2_SD:
63
+
76
+ start_addr = memmap[SIFIVE_U_L2LIM].base;
64
+/* GV: 0 AV: 0 PSCV: 1 GVMA: 0 */
77
+ break;
65
+static
78
+ default:
66
+void riscv_iommu_iot_inval_pscid(gpointer key, gpointer value, gpointer data)
79
+ start_addr = memmap[SIFIVE_U_DRAM].base;
67
+{
80
+ break;
68
+ RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
81
+ }
69
+ RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
82
+
70
+ if (iot->tag == arg->tag &&
83
+ riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL);
71
+ iot->pscid == arg->pscid) {
84
72
+ iot->perm = IOMMU_NONE;
85
if (machine->kernel_filename) {
73
+ }
86
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
74
+}
87
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
75
+
76
+/* GV: 0 AV: 1 PSCV: 0 GVMA: 0 */
77
+static
78
+void riscv_iommu_iot_inval_iova(gpointer key, gpointer value, gpointer data)
79
+{
80
+ RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
81
+ RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
82
+ if (iot->tag == arg->tag &&
83
+ iot->iova == arg->iova) {
84
+ iot->perm = IOMMU_NONE;
85
+ }
86
+}
87
+
88
+/* GV: 0 AV: 1 PSCV: 1 GVMA: 0 */
89
static void riscv_iommu_iot_inval_pscid_iova(gpointer key, gpointer value,
90
gpointer data)
91
{
92
RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
93
RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
94
- if (iot->gscid == arg->gscid &&
95
+ if (iot->tag == arg->tag &&
96
iot->pscid == arg->pscid &&
97
iot->iova == arg->iova) {
98
iot->perm = IOMMU_NONE;
99
}
100
}
101
102
-/* GV: 1 PSCV: 1 AV: 0 */
103
-static void riscv_iommu_iot_inval_pscid(gpointer key, gpointer value,
104
- gpointer data)
105
+/* GV: 1 AV: 0 PSCV: 0 GVMA: 0 */
106
+/* GV: 1 AV: 0 GVMA: 1 */
107
+static
108
+void riscv_iommu_iot_inval_gscid(gpointer key, gpointer value, gpointer data)
109
{
110
RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
111
RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
112
- if (iot->gscid == arg->gscid &&
113
- iot->pscid == arg->pscid) {
114
+ if (iot->tag == arg->tag &&
115
+ iot->gscid == arg->gscid) {
116
iot->perm = IOMMU_NONE;
117
}
118
}
119
120
-/* GV: 1 GVMA: 1 */
121
-static void riscv_iommu_iot_inval_gscid_gpa(gpointer key, gpointer value,
122
- gpointer data)
123
+/* GV: 1 AV: 0 PSCV: 1 GVMA: 0 */
124
+static void riscv_iommu_iot_inval_gscid_pscid(gpointer key, gpointer value,
125
+ gpointer data)
126
{
127
RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
128
RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
129
- if (iot->gscid == arg->gscid) {
130
- /* simplified cache, no GPA matching */
131
+ if (iot->tag == arg->tag &&
132
+ iot->gscid == arg->gscid &&
133
+ iot->pscid == arg->pscid) {
134
iot->perm = IOMMU_NONE;
135
}
136
}
137
138
-/* GV: 1 GVMA: 0 */
139
-static void riscv_iommu_iot_inval_gscid(gpointer key, gpointer value,
140
- gpointer data)
141
+/* GV: 1 AV: 1 PSCV: 0 GVMA: 0 */
142
+/* GV: 1 AV: 1 GVMA: 1 */
143
+static void riscv_iommu_iot_inval_gscid_iova(gpointer key, gpointer value,
144
+ gpointer data)
145
{
146
RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
147
RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
148
- if (iot->gscid == arg->gscid) {
149
+ if (iot->tag == arg->tag &&
150
+ iot->gscid == arg->gscid &&
151
+ iot->iova == arg->iova) {
152
iot->perm = IOMMU_NONE;
153
}
154
}
155
156
-/* GV: 0 */
157
-static void riscv_iommu_iot_inval_all(gpointer key, gpointer value,
158
- gpointer data)
159
+/* GV: 1 AV: 1 PSCV: 1 GVMA: 0 */
160
+static void riscv_iommu_iot_inval_gscid_pscid_iova(gpointer key, gpointer value,
161
+ gpointer data)
162
{
163
RISCVIOMMUEntry *iot = (RISCVIOMMUEntry *) value;
164
- iot->perm = IOMMU_NONE;
165
+ RISCVIOMMUEntry *arg = (RISCVIOMMUEntry *) data;
166
+ if (iot->tag == arg->tag &&
167
+ iot->gscid == arg->gscid &&
168
+ iot->pscid == arg->pscid &&
169
+ iot->iova == arg->iova) {
170
+ iot->perm = IOMMU_NONE;
171
+ }
172
}
173
174
/* caller should keep ref-count for iot_cache object */
175
static RISCVIOMMUEntry *riscv_iommu_iot_lookup(RISCVIOMMUContext *ctx,
176
- GHashTable *iot_cache, hwaddr iova)
177
+ GHashTable *iot_cache, hwaddr iova, RISCVIOMMUTransTag transtag)
178
{
179
RISCVIOMMUEntry key = {
180
+ .tag = transtag,
181
.gscid = get_field(ctx->gatp, RISCV_IOMMU_DC_IOHGATP_GSCID),
182
.pscid = get_field(ctx->ta, RISCV_IOMMU_DC_TA_PSCID),
183
.iova = PPN_DOWN(iova),
184
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_iot_update(RISCVIOMMUState *s,
185
}
186
187
static void riscv_iommu_iot_inval(RISCVIOMMUState *s, GHFunc func,
188
- uint32_t gscid, uint32_t pscid, hwaddr iova)
189
+ uint32_t gscid, uint32_t pscid, hwaddr iova, RISCVIOMMUTransTag transtag)
190
{
191
GHashTable *iot_cache;
192
RISCVIOMMUEntry key = {
193
+ .tag = transtag,
194
.gscid = gscid,
195
.pscid = pscid,
196
.iova = PPN_DOWN(iova),
197
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_iot_inval(RISCVIOMMUState *s, GHFunc func,
198
g_hash_table_unref(iot_cache);
199
}
200
201
+static RISCVIOMMUTransTag riscv_iommu_get_transtag(RISCVIOMMUContext *ctx)
202
+{
203
+ uint64_t satp = get_field(ctx->satp, RISCV_IOMMU_ATP_MODE_FIELD);
204
+ uint64_t gatp = get_field(ctx->gatp, RISCV_IOMMU_ATP_MODE_FIELD);
205
+
206
+ if (satp == RISCV_IOMMU_DC_FSC_MODE_BARE) {
207
+ return (gatp == RISCV_IOMMU_DC_IOHGATP_MODE_BARE) ?
208
+ RISCV_IOMMU_TRANS_TAG_BY : RISCV_IOMMU_TRANS_TAG_VG;
209
+ } else {
210
+ return (gatp == RISCV_IOMMU_DC_IOHGATP_MODE_BARE) ?
211
+ RISCV_IOMMU_TRANS_TAG_SS : RISCV_IOMMU_TRANS_TAG_VN;
212
+ }
213
+}
214
+
215
static int riscv_iommu_translate(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
216
IOMMUTLBEntry *iotlb, bool enable_cache)
217
{
218
+ RISCVIOMMUTransTag transtag = riscv_iommu_get_transtag(ctx);
219
RISCVIOMMUEntry *iot;
220
IOMMUAccessFlags perm;
221
bool enable_pid;
222
@@ -XXX,XX +XXX,XX @@ static int riscv_iommu_translate(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
88
}
223
}
89
}
224
}
90
225
91
- if (s->start_in_flash) {
226
- iot = riscv_iommu_iot_lookup(ctx, iot_cache, iotlb->iova);
92
- start_addr = memmap[SIFIVE_U_FLASH0].base;
227
+ iot = riscv_iommu_iot_lookup(ctx, iot_cache, iotlb->iova, transtag);
93
- }
228
perm = iot ? iot->perm : IOMMU_NONE;
94
-
229
if (perm != IOMMU_NONE) {
95
/* reset vector */
230
iotlb->translated_addr = PPN_PHYS(iot->phys);
96
uint32_t reset_vec[8] = {
231
@@ -XXX,XX +XXX,XX @@ static int riscv_iommu_translate(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
97
- 0x00000000,
232
iot->gscid = get_field(ctx->gatp, RISCV_IOMMU_DC_IOHGATP_GSCID);
98
+ s->msel, /* MSEL pin state */
233
iot->pscid = get_field(ctx->ta, RISCV_IOMMU_DC_TA_PSCID);
99
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
234
iot->perm = iotlb->perm;
100
0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
235
+ iot->tag = transtag;
101
0xf1402573, /* csrr a0, mhartid */
236
riscv_iommu_iot_update(s, iot_cache, iot);
102
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
237
}
103
sifive_u_machine_set_start_in_flash);
238
104
object_property_set_description(obj, "start-in-flash",
239
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_process_cq_tail(RISCVIOMMUState *s)
105
"Set on to tell QEMU's ROM to jump to "
240
106
- "flash. Otherwise QEMU will jump to DRAM");
241
case RISCV_IOMMU_CMD(RISCV_IOMMU_CMD_IOTINVAL_FUNC_GVMA,
107
+ "flash. Otherwise QEMU will jump to DRAM "
242
RISCV_IOMMU_CMD_IOTINVAL_OPCODE):
108
+ "or L2LIM depending on the msel value");
243
- if (cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_PSCV) {
109
244
+ {
110
s->msel = 0;
245
+ bool gv = !!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_GV);
111
object_property_add(obj, "msel", "uint32",
246
+ bool av = !!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_AV);
247
+ bool pscv = !!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_PSCV);
248
+ uint32_t gscid = get_field(cmd.dword0,
249
+ RISCV_IOMMU_CMD_IOTINVAL_GSCID);
250
+ uint32_t pscid = get_field(cmd.dword0,
251
+ RISCV_IOMMU_CMD_IOTINVAL_PSCID);
252
+ hwaddr iova = (cmd.dword1 << 2) & TARGET_PAGE_MASK;
253
+
254
+ if (pscv) {
255
/* illegal command arguments IOTINVAL.GVMA & PSCV == 1 */
256
goto cmd_ill;
257
- } else if (!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_GV)) {
258
- /* invalidate all cache mappings */
259
- func = riscv_iommu_iot_inval_all;
260
- } else if (!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_AV)) {
261
- /* invalidate cache matching GSCID */
262
- func = riscv_iommu_iot_inval_gscid;
263
- } else {
264
- /* invalidate cache matching GSCID and ADDR (GPA) */
265
- func = riscv_iommu_iot_inval_gscid_gpa;
266
}
267
- riscv_iommu_iot_inval(s, func,
268
- get_field(cmd.dword0, RISCV_IOMMU_CMD_IOTINVAL_GSCID), 0,
269
- cmd.dword1 << 2 & TARGET_PAGE_MASK);
270
+
271
+ func = riscv_iommu_iot_inval_all;
272
+
273
+ if (gv) {
274
+ func = (av) ? riscv_iommu_iot_inval_gscid_iova :
275
+ riscv_iommu_iot_inval_gscid;
276
+ }
277
+
278
+ riscv_iommu_iot_inval(
279
+ s, func, gscid, pscid, iova, RISCV_IOMMU_TRANS_TAG_VG);
280
+
281
+ riscv_iommu_iot_inval(
282
+ s, func, gscid, pscid, iova, RISCV_IOMMU_TRANS_TAG_VN);
283
break;
284
+ }
285
286
case RISCV_IOMMU_CMD(RISCV_IOMMU_CMD_IOTINVAL_FUNC_VMA,
287
RISCV_IOMMU_CMD_IOTINVAL_OPCODE):
288
- if (!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_GV)) {
289
- /* invalidate all cache mappings, simplified model */
290
- func = riscv_iommu_iot_inval_all;
291
- } else if (!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_PSCV)) {
292
- /* invalidate cache matching GSCID, simplified model */
293
- func = riscv_iommu_iot_inval_gscid;
294
- } else if (!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_AV)) {
295
- /* invalidate cache matching GSCID and PSCID */
296
- func = riscv_iommu_iot_inval_pscid;
297
+ {
298
+ bool gv = !!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_GV);
299
+ bool av = !!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_AV);
300
+ bool pscv = !!(cmd.dword0 & RISCV_IOMMU_CMD_IOTINVAL_PSCV);
301
+ uint32_t gscid = get_field(cmd.dword0,
302
+ RISCV_IOMMU_CMD_IOTINVAL_GSCID);
303
+ uint32_t pscid = get_field(cmd.dword0,
304
+ RISCV_IOMMU_CMD_IOTINVAL_PSCID);
305
+ hwaddr iova = (cmd.dword1 << 2) & TARGET_PAGE_MASK;
306
+ RISCVIOMMUTransTag transtag;
307
+
308
+ if (gv) {
309
+ transtag = RISCV_IOMMU_TRANS_TAG_VN;
310
+ if (pscv) {
311
+ func = (av) ? riscv_iommu_iot_inval_gscid_pscid_iova :
312
+ riscv_iommu_iot_inval_gscid_pscid;
313
+ } else {
314
+ func = (av) ? riscv_iommu_iot_inval_gscid_iova :
315
+ riscv_iommu_iot_inval_gscid;
316
+ }
317
} else {
318
- /* invalidate cache matching GSCID and PSCID and ADDR (IOVA) */
319
- func = riscv_iommu_iot_inval_pscid_iova;
320
+ transtag = RISCV_IOMMU_TRANS_TAG_SS;
321
+ if (pscv) {
322
+ func = (av) ? riscv_iommu_iot_inval_pscid_iova :
323
+ riscv_iommu_iot_inval_pscid;
324
+ } else {
325
+ func = (av) ? riscv_iommu_iot_inval_iova :
326
+ riscv_iommu_iot_inval_all;
327
+ }
328
}
329
- riscv_iommu_iot_inval(s, func,
330
- get_field(cmd.dword0, RISCV_IOMMU_CMD_IOTINVAL_GSCID),
331
- get_field(cmd.dword0, RISCV_IOMMU_CMD_IOTINVAL_PSCID),
332
- cmd.dword1 << 2 & TARGET_PAGE_MASK);
333
+
334
+ riscv_iommu_iot_inval(s, func, gscid, pscid, iova, transtag);
335
break;
336
+ }
337
338
case RISCV_IOMMU_CMD(RISCV_IOMMU_CMD_IODIR_FUNC_INVAL_DDT,
339
RISCV_IOMMU_CMD_IODIR_OPCODE):
112
--
340
--
113
2.27.0
341
2.48.1
114
115
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Alexey Baturo <baturo.alexey@gmail.com>
2
2
3
Add a new property to represent the number of GPIO pins supported
3
The Zjpm v1.0 spec states there should be Supm and Sspm extensions that
4
by the GPIO controller.
4
are used in profile specification. Enabling Supm extension enables both
5
Ssnpm and Smnpm, while Sspm enables only Smnpm.
5
6
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Alexey Baturo <baturo.alexey@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Message-id: 1591625864-31494-7-git-send-email-bmeng.cn@gmail.com
9
Message-ID: <20250113194410.1307494-1-baturo.alexey@gmail.com>
9
Message-Id: <1591625864-31494-7-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
include/hw/riscv/sifive_gpio.h | 3 +++
12
target/riscv/cpu_cfg.h | 2 ++
13
hw/riscv/sifive_gpio.c | 30 +++++++++++++++++++-----------
13
target/riscv/cpu.c | 23 +++++++++++++++++++++++
14
2 files changed, 22 insertions(+), 11 deletions(-)
14
2 files changed, 25 insertions(+)
15
15
16
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
16
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/riscv/sifive_gpio.h
18
--- a/target/riscv/cpu_cfg.h
19
+++ b/include/hw/riscv/sifive_gpio.h
19
+++ b/target/riscv/cpu_cfg.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
20
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
21
uint32_t out_xor;
21
bool ext_ssnpm;
22
uint32_t in;
22
bool ext_smnpm;
23
uint32_t in_mask;
23
bool ext_smmpm;
24
+ bool ext_sspm;
25
+ bool ext_supm;
26
bool rvv_ta_all_1s;
27
bool rvv_ma_all_1s;
28
bool rvv_vl_half_avl;
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
33
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
34
ISA_EXT_DATA_ENTRY(sscsrind, PRIV_VERSION_1_12_0, ext_sscsrind),
35
ISA_EXT_DATA_ENTRY(ssdbltrp, PRIV_VERSION_1_13_0, ext_ssdbltrp),
36
ISA_EXT_DATA_ENTRY(ssnpm, PRIV_VERSION_1_13_0, ext_ssnpm),
37
+ ISA_EXT_DATA_ENTRY(sspm, PRIV_VERSION_1_13_0, ext_sspm),
38
ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
39
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
40
ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
41
ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
42
+ ISA_EXT_DATA_ENTRY(supm, PRIV_VERSION_1_13_0, ext_supm),
43
ISA_EXT_DATA_ENTRY(svade, PRIV_VERSION_1_11_0, ext_svade),
44
ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
45
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
46
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
47
MULTI_EXT_CFG_BOOL("zvfhmin", ext_zvfhmin, false),
48
MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
49
MULTI_EXT_CFG_BOOL("ssnpm", ext_ssnpm, false),
50
+ MULTI_EXT_CFG_BOOL("sspm", ext_sspm, false),
51
+ MULTI_EXT_CFG_BOOL("supm", ext_supm, false),
52
53
MULTI_EXT_CFG_BOOL("smaia", ext_smaia, false),
54
MULTI_EXT_CFG_BOOL("smdbltrp", ext_smdbltrp, false),
55
@@ -XXX,XX +XXX,XX @@ static RISCVCPUImpliedExtsRule SSCFG_IMPLIED = {
56
},
57
};
58
59
+static RISCVCPUImpliedExtsRule SUPM_IMPLIED = {
60
+ .ext = CPU_CFG_OFFSET(ext_supm),
61
+ .implied_multi_exts = {
62
+ CPU_CFG_OFFSET(ext_ssnpm), CPU_CFG_OFFSET(ext_smnpm),
24
+
63
+
25
+ /* config */
64
+ RISCV_IMPLIED_EXTS_RULE_END
26
+ uint32_t ngpio;
65
+ },
27
} SIFIVEGPIOState;
28
29
#endif /* SIFIVE_GPIO_H */
30
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/sifive_gpio.c
33
+++ b/hw/riscv/sifive_gpio.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "qemu/osdep.h"
36
#include "qemu/log.h"
37
#include "hw/irq.h"
38
+#include "hw/qdev-properties.h"
39
#include "hw/riscv/sifive_gpio.h"
40
#include "migration/vmstate.h"
41
#include "trace.h"
42
@@ -XXX,XX +XXX,XX @@ static void update_output_irq(SIFIVEGPIOState *s)
43
pending |= s->rise_ip & s->rise_ie;
44
pending |= s->fall_ip & s->fall_ie;
45
46
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
47
+ for (int i = 0; i < s->ngpio; i++) {
48
pin = 1 << i;
49
qemu_set_irq(s->irq[i], (pending & pin) != 0);
50
trace_sifive_gpio_update_output_irq(i, (pending & pin) != 0);
51
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
52
bool prev_ival, in, in_mask, port, out_xor, pull, output_en, input_en,
53
rise_ip, fall_ip, low_ip, high_ip, oval, actual_value, ival;
54
55
- for (i = 0; i < SIFIVE_GPIO_PINS; i++) {
56
+ for (i = 0; i < s->ngpio; i++) {
57
58
prev_ival = extract32(s->value, i, 1);
59
in = extract32(s->in, i, 1);
60
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
61
}
62
};
63
64
-static void sifive_gpio_init(Object *obj)
65
+static Property sifive_gpio_properties[] = {
66
+ DEFINE_PROP_UINT32("ngpio", SIFIVEGPIOState, ngpio, SIFIVE_GPIO_PINS),
67
+ DEFINE_PROP_END_OF_LIST(),
68
+};
66
+};
69
+
67
+
70
+static void sifive_gpio_realize(DeviceState *dev, Error **errp)
68
+static RISCVCPUImpliedExtsRule SSPM_IMPLIED = {
71
{
69
+ .ext = CPU_CFG_OFFSET(ext_sspm),
72
- SIFIVEGPIOState *s = SIFIVE_GPIO(obj);
70
+ .implied_multi_exts = {
73
+ SIFIVEGPIOState *s = SIFIVE_GPIO(dev);
71
+ CPU_CFG_OFFSET(ext_smnpm),
74
75
- memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
76
+ memory_region_init_io(&s->mmio, OBJECT(dev), &gpio_ops, s,
77
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
78
- sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
79
80
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
81
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
82
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
83
+
72
+
84
+ for (int i = 0; i < s->ngpio; i++) {
73
+ RISCV_IMPLIED_EXTS_RULE_END
85
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
74
+ },
86
}
75
+};
87
76
+
88
- qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, SIFIVE_GPIO_PINS);
77
RISCVCPUImpliedExtsRule *riscv_misa_ext_implied_rules[] = {
89
- qdev_init_gpio_out(DEVICE(s), s->output, SIFIVE_GPIO_PINS);
78
&RVA_IMPLIED, &RVD_IMPLIED, &RVF_IMPLIED,
90
+ qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, s->ngpio);
79
&RVM_IMPLIED, &RVV_IMPLIED, NULL
91
+ qdev_init_gpio_out(DEVICE(s), s->output, s->ngpio);
80
@@ -XXX,XX +XXX,XX @@ RISCVCPUImpliedExtsRule *riscv_multi_ext_implied_rules[] = {
92
}
81
&ZVFH_IMPLIED, &ZVFHMIN_IMPLIED, &ZVKN_IMPLIED,
93
82
&ZVKNC_IMPLIED, &ZVKNG_IMPLIED, &ZVKNHB_IMPLIED,
94
static void sifive_gpio_class_init(ObjectClass *klass, void *data)
83
&ZVKS_IMPLIED, &ZVKSC_IMPLIED, &ZVKSG_IMPLIED, &SSCFG_IMPLIED,
95
{
84
+ &SUPM_IMPLIED, &SSPM_IMPLIED,
96
DeviceClass *dc = DEVICE_CLASS(klass);
85
NULL
97
98
+ device_class_set_props(dc, sifive_gpio_properties);
99
dc->vmsd = &vmstate_sifive_gpio;
100
+ dc->realize = sifive_gpio_realize;
101
dc->reset = sifive_gpio_reset;
102
dc->desc = "SiFive GPIO";
103
}
104
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sifive_gpio_info = {
105
.name = TYPE_SIFIVE_GPIO,
106
.parent = TYPE_SYS_BUS_DEVICE,
107
.instance_size = sizeof(SIFIVEGPIOState),
108
- .instance_init = sifive_gpio_init,
109
.class_init = sifive_gpio_class_init
110
};
86
};
111
87
112
--
88
--
113
2.27.0
89
2.48.1
114
115
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-ID: <20250116223609.81594-1-philmd@linaro.org>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reported-by: Damien Hedde <damien.hedde@greensocs.com>
3
---
7
---
4
hw/riscv/opentitan.c | 3 ++-
8
hw/char/riscv_htif.c | 15 +++------------
5
1 file changed, 2 insertions(+), 1 deletion(-)
9
hw/char/trace-events | 4 ++++
10
2 files changed, 7 insertions(+), 12 deletions(-)
6
11
7
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
12
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
8
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
9
--- a/hw/riscv/opentitan.c
14
--- a/hw/char/riscv_htif.c
10
+++ b/hw/riscv/opentitan.c
15
+++ b/hw/char/riscv_htif.c
11
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
12
#include "hw/misc/unimp.h"
17
#include "exec/tswap.h"
13
#include "hw/riscv/boot.h"
18
#include "system/dma.h"
14
#include "exec/address-spaces.h"
19
#include "system/runstate.h"
15
+#include "qemu/units.h"
20
-
16
21
-#define RISCV_DEBUG_HTIF 0
17
static const struct MemmapEntry {
22
-#define HTIF_DEBUG(fmt, ...) \
18
hwaddr base;
23
- do { \
19
hwaddr size;
24
- if (RISCV_DEBUG_HTIF) { \
20
} ibex_memmap[] = {
25
- qemu_log_mask(LOG_TRACE, "%s: " fmt "\n", __func__, ##__VA_ARGS__);\
21
- [IBEX_ROM] = { 0x00008000, 0xc000 },
26
- } \
22
+ [IBEX_ROM] = { 0x00008000, 16 * KiB },
27
- } while (0)
23
[IBEX_RAM] = { 0x10000000, 0x10000 },
28
+#include "trace.h"
24
[IBEX_FLASH] = { 0x20000000, 0x80000 },
29
25
[IBEX_UART] = { 0x40000000, 0x10000 },
30
#define HTIF_DEV_SHIFT 56
31
#define HTIF_CMD_SHIFT 48
32
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
33
uint64_t payload = val_written & 0xFFFFFFFFFFFFULL;
34
int resp = 0;
35
36
- HTIF_DEBUG("mtohost write: device: %d cmd: %d what: %02" PRIx64
37
- " -payload: %016" PRIx64 "\n", device, cmd, payload & 0xFF, payload);
38
+ trace_htif_uart_write_to_host(device, cmd, payload);
39
40
/*
41
* Currently, there is a fixed mapping of devices:
42
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
43
}
44
} else {
45
qemu_log("HTIF unknown device or command\n");
46
- HTIF_DEBUG("device: %d cmd: %d what: %02" PRIx64
47
- " payload: %016" PRIx64, device, cmd, payload & 0xFF, payload);
48
+ trace_htif_uart_unknown_device_command(device, cmd, payload);
49
}
50
/*
51
* Latest bbl does not set fromhost to 0 if there is a value in tohost.
52
diff --git a/hw/char/trace-events b/hw/char/trace-events
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/char/trace-events
55
+++ b/hw/char/trace-events
56
@@ -XXX,XX +XXX,XX @@ stm32f2xx_usart_read(char *id, unsigned size, uint64_t ofs, uint64_t val) " %s s
57
stm32f2xx_usart_write(char *id, unsigned size, uint64_t ofs, uint64_t val) "%s size %d ofs 0x%02" PRIx64 " <- 0x%02" PRIx64
58
stm32f2xx_usart_drop(char *id) " %s dropping the chars"
59
stm32f2xx_usart_receive(char *id, uint8_t chr) " %s receiving '%c'"
60
+
61
+# riscv_htif.c
62
+htif_uart_write_to_host(uint8_t device, uint8_t cmd, uint64_t payload) "device: %u cmd: %02u payload: %016" PRIx64
63
+htif_uart_unknown_device_command(uint8_t device, uint8_t cmd, uint64_t payload) "device: %u cmd: %02u payload: %016" PRIx64
26
--
64
--
27
2.27.0
65
2.48.1
28
66
29
67
diff view generated by jsdifflib