1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
3
The following changes since commit 222059a0fccf4af3be776fe35a5ea2d6a68f9a0b:
4
5
Merge tag 'pull-ppc-20221221' of https://gitlab.com/danielhb/qemu into staging (2022-12-21 18:08:09 +0000)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
9
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20221222-1
8
10
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
11
for you to fetch changes up to 71a9bc59728a054036f3db7dd82dab8f8bd2baf9:
10
12
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
13
hw/intc: sifive_plic: Fix the pending register range check (2022-12-22 08:36:30 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
RISC-V PR for 9.1
16
First RISC-V PR for QEMU 8.0
15
17
16
* APLICs add child earlier than realize
18
* Fix PMP propagation for tlb
17
* Fix exposure of Zkr
19
* Collection of bug fixes
18
* Raise exceptions on wrs.nto
20
* Add the `FIELDx_1CLEAR()` macro
19
* Implement SBI debug console (DBCN) calls for KVM
21
* Bump the OpenTitan supported version
20
* Support 64-bit addresses for initrd
22
* Add smstateen support
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
23
* Support native debug icount trigger
22
* Tolerate KVM disable ext errors
24
* Remove the redundant ipi-id property in the virt machine
23
* Set tval in breakpoints
25
* Support cache-related PMU events in virtual mode
24
* Add support for Zve32x extension
26
* Add some missing PolarFire SoC io regions
25
* Add support for Zve64x extension
27
* Fix mret exception cause when no pmp rule is configured
26
* Relax vector register check in RISCV gdbstub
28
* Fix bug where disabling compressed instructions would crash QEMU
27
* Fix the element agnostic Vector function problem
29
* Add Zawrs ISA extension support
28
* Fix Zvkb extension config
30
* A range of code refactoring and cleanups
29
* Implement dynamic establishment of custom decoder
30
* Add th.sxstatus CSR emulation
31
* Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
32
* Check single width operator for vector fp widen instructions
33
* Check single width operator for vfncvt.rod.f.f.w
34
* Remove redudant SEW checking for vector fp narrow/widen instructions
35
* Prioritize pmp errors in raise_mmu_exception()
36
* Do not set mtval2 for non guest-page faults
37
* Remove experimental prefix from "B" extension
38
* Fixup CBO extension register calculation
39
* Fix the hart bit setting of AIA
40
* Fix reg_width in ricsv_gen_dynamic_vector_feature()
41
* Decode all of the pmpcfg and pmpaddr CSRs
42
* Raise an exception when CSRRS/CSRRC writes a read-only CSR
43
31
44
----------------------------------------------------------------
32
----------------------------------------------------------------
45
Alexei Filippov (1):
33
Anup Patel (1):
46
target/riscv: do not set mtval2 for non guest-page faults
34
target/riscv: Typo fix in sstc() predicate
47
35
48
Alistair Francis (2):
36
Atish Patra (1):
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
37
hw/riscv: virt: Remove the redundant ipi-id property
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
51
38
52
Andrew Jones (2):
39
Bin Meng (20):
53
target/riscv/kvm: Fix exposure of Zkr
40
target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()
54
target/riscv: Raise exceptions on wrs.nto
41
target/riscv: Fix mret exception cause when no pmp rule is configured
42
target/riscv: Simplify helper_sret() a little bit
43
target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+
44
hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC
45
hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers
46
hw/riscv: Fix opentitan dependency to SIFIVE_PLIC
47
hw/riscv: Sort machines Kconfig options in alphabetical order
48
hw/riscv: spike: Remove misleading comments
49
hw/intc: sifive_plic: Drop PLICMode_H
50
hw/intc: sifive_plic: Improve robustness of the PLIC config parser
51
hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp in sifive_plic_realize()
52
hw/intc: sifive_plic: Update "num-sources" property default value
53
hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC
54
hw/riscv: sifive_e: Fix the number of interrupt sources of PLIC
55
hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev"
56
hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb
57
hw/intc: sifive_plic: Change "priority-base" to start from interrupt source 0
58
hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization
59
hw/intc: sifive_plic: Fix the pending register range check
55
60
56
Cheng Yang (1):
61
Christoph Muellner (1):
57
hw/riscv/boot.c: Support 64-bit address for initrd
62
RISC-V: Add Zawrs ISA extension support
58
63
59
Christoph Müllner (1):
64
Conor Dooley (3):
60
riscv: thead: Add th.sxstatus CSR emulation
65
hw/misc: pfsoc: add fabric clocks to ioscb
66
hw/riscv: pfsoc: add missing FICs as unimplemented
67
hw/{misc, riscv}: pfsoc: add system controller as unimplemented
61
68
62
Clément Léger (1):
69
Frédéric Pétrot (1):
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
70
hw/intc: sifive_plic: Renumber the S irqs for numa support
64
71
65
Daniel Henrique Barboza (6):
72
Jim Shu (2):
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
73
target/riscv: support cache-related PMU events in virtual mode
67
target/riscv/kvm: tolerate KVM disable ext errors
74
hw/intc: sifive_plic: fix out-of-bound access of source_priority array
68
target/riscv/debug: set tval=pc in breakpoint exceptions
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
72
75
73
Huang Tao (2):
76
LIU Zhiwei (5):
74
target/riscv: Fix the element agnostic function problem
77
target/riscv: Fix PMP propagation for tlb
75
target/riscv: Implement dynamic establishment of custom decoder
78
target/riscv: Add itrigger support when icount is not enabled
79
target/riscv: Add itrigger support when icount is enabled
80
target/riscv: Enable native debug itrigger
81
target/riscv: Add itrigger_enabled field to CPURISCVState
76
82
77
Jason Chien (3):
83
Mayuresh Chitale (3):
78
target/riscv: Add support for Zve32x extension
84
target/riscv: Add smstateen support
79
target/riscv: Add support for Zve64x extension
85
target/riscv: smstateen check for h/s/envcfg
80
target/riscv: Relax vector register check in RISCV gdbstub
86
target/riscv: generate virtual instruction exception
81
87
82
Max Chou (4):
88
Richard Henderson (4):
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
89
tcg/riscv: Fix range matched by TCG_CT_CONST_M12
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
90
tcg/riscv: Fix reg overlap case in tcg_out_addsub2
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
91
tcg/riscv: Fix base register for user-only qemu_ld/st
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
92
target/riscv: Set pc_succ_insn for !rvc illegal insn
87
93
88
Rob Bradford (1):
94
Wilfred Mallawa (4):
89
target/riscv: Remove experimental prefix from "B" extension
95
hw/registerfields: add `FIELDx_1CLEAR()` macro
96
hw/ssi/ibex_spi: implement `FIELD32_1CLEAR` macro
97
hw/riscv/opentitan: bump opentitan
98
hw/riscv/opentitan: add aon_timer base unimpl
90
99
91
Yangyu Chen (1):
100
include/hw/intc/sifive_plic.h | 1 -
92
target/riscv/cpu.c: fix Zvkb extension config
101
include/hw/misc/mchp_pfsoc_ioscb.h | 4 +
93
102
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
94
Yong-Xuan Wang (1):
103
include/hw/registerfields.h | 22 ++
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
104
include/hw/riscv/microchip_pfsoc.h | 7 +-
96
105
include/hw/riscv/opentitan.h | 10 +-
97
Yu-Ming Chang (1):
106
include/hw/riscv/shakti_c.h | 2 +-
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
107
include/hw/riscv/sifive_e.h | 9 +-
99
108
include/hw/riscv/sifive_u.h | 2 +-
100
yang.zhang (1):
109
include/hw/riscv/virt.h | 8 +-
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
110
target/riscv/cpu.h | 10 +
102
111
target/riscv/cpu_bits.h | 37 +++
103
MAINTAINERS | 1 +
112
target/riscv/debug.h | 13 +
104
target/riscv/cpu.h | 11 ++
113
target/riscv/helper.h | 2 +
105
target/riscv/cpu_bits.h | 2 +-
114
target/riscv/pmp.h | 6 +-
106
target/riscv/cpu_cfg.h | 2 +
115
target/riscv/insn32.decode | 4 +
107
target/riscv/helper.h | 1 +
116
hw/intc/sifive_plic.c | 66 +++--
108
target/riscv/sbi_ecall_interface.h | 17 +++
117
hw/misc/mchp_pfsoc_ioscb.c | 78 ++++-
109
target/riscv/tcg/tcg-cpu.h | 15 +++
118
hw/misc/mchp_pfsoc_sysreg.c | 18 +-
110
disas/riscv.c | 65 +++++++++-
119
hw/riscv/microchip_pfsoc.c | 121 ++++----
111
hw/intc/riscv_aplic.c | 8 +-
120
hw/riscv/opentitan.c | 26 +-
112
hw/riscv/boot.c | 4 +-
121
hw/riscv/sifive_u.c | 3 +-
113
target/riscv/cpu.c | 10 +-
122
hw/riscv/spike.c | 1 -
114
target/riscv/cpu_helper.c | 37 +++---
123
hw/riscv/virt.c | 7 +-
115
target/riscv/csr.c | 71 +++++++++--
124
hw/ssi/ibex_spi_host.c | 21 +-
116
target/riscv/debug.c | 3 +
125
target/riscv/cpu.c | 11 +
117
target/riscv/gdbstub.c | 8 +-
126
target/riscv/cpu_helper.c | 26 +-
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
127
target/riscv/csr.c | 393 ++++++++++++++++++++++++-
119
target/riscv/op_helper.c | 17 ++-
128
target/riscv/debug.c | 205 +++++++++++++
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
129
target/riscv/machine.c | 36 +++
121
target/riscv/th_csr.c | 79 +++++++++++++
130
target/riscv/op_helper.c | 28 +-
122
target/riscv/translate.c | 31 +++--
131
target/riscv/pmp.c | 90 ++----
123
target/riscv/vector_internals.c | 22 ++++
132
target/riscv/translate.c | 54 +++-
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
133
target/riscv/insn_trans/trans_privileged.c.inc | 4 +-
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
134
target/riscv/insn_trans/trans_rvi.c.inc | 8 +-
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
135
target/riscv/insn_trans/trans_rvv.c.inc | 4 +-
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
136
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 ++++
128
target/riscv/meson.build | 1 +
137
tcg/riscv/tcg-target.c.inc | 68 +++--
129
26 files changed, 596 insertions(+), 109 deletions(-)
138
hw/intc/Kconfig | 3 +
130
create mode 100644 target/riscv/th_csr.c
139
hw/riscv/Kconfig | 22 +-
131
140
tests/tcg/Makefile.target | 2 +
141
tests/tcg/riscv64/Makefile.target | 6 +
142
tests/tcg/riscv64/test-noc.S | 32 ++
143
43 files changed, 1256 insertions(+), 266 deletions(-)
144
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
145
create mode 100644 tests/tcg/riscv64/test-noc.S
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
3
Only the pmp index that be checked by pmp_hart_has_privs can be used
4
checking first if virt_enabled && !first_stage, and then considering the
4
by pmp_get_tlb_size to avoid an error pmp index.
5
regular inst/load/store faults.
5
6
6
Before modification, we may use an error pmp index. For example,
7
There's no mention in the spec about guest page fault being a higher
7
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
8
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
9
9
will return true;
10
"Attempting to fetch an instruction from a PMP region that does not have
10
11
execute permissions raises an instruction access-fault exception.
11
However, this checked pmp index is discarded as pmp_hart_has_privs
12
Attempting to execute a load or load-reserved instruction which accesses
12
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
13
a physical address within a PMP region without read permissions raises a
13
rules. The tlb_sa will be 0x0, and tlb_ea will be 0xfff. If there is
14
load access-fault exception. Attempting to execute a store,
14
a pmp rule [0x10, 0x14), it will be misused as it is legal in
15
store-conditional, or AMO instruction which accesses a physical address
15
pmp_get_tlb_size.
16
within a PMP region without write permissions raises a store
16
17
access-fault exception."
17
As we have already known the correct pmp index, just remove the
18
18
remove the pmp_is_range_in_tlb and get tlb size directly from
19
So, in fact, we're doing it wrong - PMP faults should always be thrown,
19
pmp_get_tlb_size.
20
regardless of also being a first or second stage fault.
20
21
21
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
The way riscv_cpu_tlb_fill() and get_physical_address() work is
23
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
24
reflected in the 'pmp_violation' flag. What we need is to change
25
raise_mmu_exception() to prioritize it.
26
27
Reported-by: Joseph Chan <jchan@ventanamicro.com>
28
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
29
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
23
Message-Id: <20221012060016.30856-1-zhiwei_liu@linux.alibaba.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
25
---
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
26
target/riscv/pmp.h | 6 +--
36
1 file changed, 12 insertions(+), 10 deletions(-)
27
target/riscv/cpu_helper.c | 16 ++++---
37
28
target/riscv/pmp.c | 90 +++++++++++++--------------------------
29
3 files changed, 42 insertions(+), 70 deletions(-)
30
31
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/pmp.h
34
+++ b/target/riscv/pmp.h
35
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
36
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
37
target_ulong val);
38
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
39
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
40
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
41
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
42
target_ulong mode);
43
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
44
- target_ulong *tlb_size);
45
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
46
+ target_ulong tlb_sa, target_ulong tlb_ea);
47
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
48
void pmp_update_rule_nums(CPURISCVState *env);
49
uint32_t pmp_get_num_rules(CPURISCVState *env);
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
50
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
52
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
53
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
54
@@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
43
55
int mode)
44
switch (access_type) {
56
{
45
case MMU_INST_FETCH:
57
pmp_priv_t pmp_priv;
46
- if (env->virt_enabled && !first_stage) {
58
- target_ulong tlb_size_pmp = 0;
47
+ if (pmp_violation) {
59
+ int pmp_index = -1;
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
60
49
+ } else if (env->virt_enabled && !first_stage) {
61
if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
62
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
51
} else {
63
return TRANSLATE_SUCCESS;
52
- cs->exception_index = pmp_violation ?
64
}
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
65
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
66
- if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
67
- mode)) {
68
+ pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
69
+ &pmp_priv, mode);
70
+ if (pmp_index < 0) {
71
*prot = 0;
72
return TRANSLATE_PMP_FAIL;
73
}
74
75
*prot = pmp_priv_to_page_prot(pmp_priv);
76
- if (tlb_size != NULL) {
77
- if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
78
- *tlb_size = tlb_size_pmp;
79
- }
80
+ if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
81
+ target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
82
+ target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
83
+
84
+ *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
85
}
86
87
return TRANSLATE_SUCCESS;
88
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/riscv/pmp.c
91
+++ b/target/riscv/pmp.c
92
@@ -XXX,XX +XXX,XX @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
93
94
/*
95
* Check if the address has required RWX privs to complete desired operation
96
+ * Return PMP rule index if a pmp rule match
97
+ * Return MAX_RISCV_PMPS if default match
98
+ * Return negtive value if no match
99
*/
100
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
101
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
102
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
103
target_ulong mode)
104
{
105
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
106
107
/* Short cut if no rules */
108
if (0 == pmp_get_num_rules(env)) {
109
- return pmp_hart_has_privs_default(env, addr, size, privs,
110
- allowed_privs, mode);
111
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
112
+ allowed_privs, mode)) {
113
+ ret = MAX_RISCV_PMPS;
114
+ }
115
}
116
117
if (size == 0) {
118
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
119
if ((s + e) == 1) {
120
qemu_log_mask(LOG_GUEST_ERROR,
121
"pmp violation - access is partially inside\n");
122
- ret = 0;
123
+ ret = -1;
124
break;
55
}
125
}
56
break;
126
57
case MMU_DATA_LOAD:
127
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
58
- if (two_stage && !first_stage) {
128
}
59
+ if (pmp_violation) {
129
}
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
130
61
+ } else if (two_stage && !first_stage) {
131
- ret = ((privs & *allowed_privs) == privs);
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
132
+ if ((privs & *allowed_privs) == privs) {
63
} else {
133
+ ret = i;
64
- cs->exception_index = pmp_violation ?
134
+ }
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
135
break;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
67
}
136
}
68
break;
137
}
69
case MMU_DATA_STORE:
138
70
- if (two_stage && !first_stage) {
139
/* No rule matched */
71
+ if (pmp_violation) {
140
if (ret == -1) {
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
141
- return pmp_hart_has_privs_default(env, addr, size, privs,
73
+ } else if (two_stage && !first_stage) {
142
- allowed_privs, mode);
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
143
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
75
} else {
144
+ allowed_privs, mode)) {
76
- cs->exception_index = pmp_violation ?
145
+ ret = MAX_RISCV_PMPS;
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
146
+ }
78
- RISCV_EXCP_STORE_PAGE_FAULT;
147
}
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
148
80
}
149
- return ret == 1 ? true : false;
81
break;
150
+ return ret;
82
default:
151
}
152
153
/*
154
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
155
* Calculate the TLB size if the start address or the end address of
156
* PMP entry is presented in the TLB page.
157
*/
158
-static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
159
- target_ulong tlb_sa, target_ulong tlb_ea)
160
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
161
+ target_ulong tlb_sa, target_ulong tlb_ea)
162
{
163
target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
164
target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
165
166
- if (pmp_sa >= tlb_sa && pmp_ea <= tlb_ea) {
167
- return pmp_ea - pmp_sa + 1;
168
- }
169
-
170
- if (pmp_sa >= tlb_sa && pmp_sa <= tlb_ea && pmp_ea >= tlb_ea) {
171
- return tlb_ea - pmp_sa + 1;
172
- }
173
-
174
- if (pmp_ea <= tlb_ea && pmp_ea >= tlb_sa && pmp_sa <= tlb_sa) {
175
- return pmp_ea - tlb_sa + 1;
176
- }
177
-
178
- return 0;
179
-}
180
-
181
-/*
182
- * Check is there a PMP entry which range covers this page. If so,
183
- * try to find the minimum granularity for the TLB size.
184
- */
185
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
186
- target_ulong *tlb_size)
187
-{
188
- int i;
189
- target_ulong val;
190
- target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
191
-
192
- for (i = 0; i < MAX_RISCV_PMPS; i++) {
193
- val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
194
- if (val) {
195
- if (*tlb_size == 0 || *tlb_size > val) {
196
- *tlb_size = val;
197
- }
198
- }
199
- }
200
-
201
- if (*tlb_size != 0) {
202
+ if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
203
+ return TARGET_PAGE_SIZE;
204
+ } else {
205
/*
206
- * At this point we have a tlb_size that is the smallest possible size
207
- * That fits within a TARGET_PAGE_SIZE and the PMP region.
208
- *
209
- * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
210
- * This means the result isn't cached in the TLB and is only used for
211
- * a single translation.
212
- */
213
- if (*tlb_size < TARGET_PAGE_SIZE) {
214
- *tlb_size = 1;
215
- }
216
-
217
- return true;
218
+ * At this point we have a tlb_size that is the smallest possible size
219
+ * That fits within a TARGET_PAGE_SIZE and the PMP region.
220
+ *
221
+ * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
222
+ * This means the result isn't cached in the TLB and is only used for
223
+ * a single translation.
224
+ */
225
+ return 1;
226
}
227
-
228
- return false;
229
}
230
231
/*
83
--
232
--
84
2.45.1
233
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
Adds a helper macro that implements the register `w1c`
4
functionality.
5
6
Ex:
7
uint32_t data = FIELD32_1CLEAR(val, REG, FIELD);
8
9
If ANY bits of the specified `FIELD` is set
10
then the respective field is cleared and returned to `data`.
11
12
If the field is cleared (0), then no change and
13
val is returned.
14
15
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20221017054950.317584-2-wilfred.mallawa@opensource.wdc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
20
include/hw/registerfields.h | 22 ++++++++++++++++++++++
21
1 file changed, 22 insertions(+)
22
23
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/registerfields.h
26
+++ b/include/hw/registerfields.h
27
@@ -XXX,XX +XXX,XX @@
28
R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
29
_d; })
30
31
+/*
32
+ * Clear the specified field in storage if
33
+ * any field bits are set, else no changes made. Implements
34
+ * single/multi-bit `w1c`
35
+ *
36
+ */
37
+#define FIELD8_1CLEAR(storage, reg, field) \
38
+ (FIELD_EX8(storage, reg, field) ? \
39
+ FIELD_DP8(storage, reg, field, 0x00) : storage)
40
+
41
+#define FIELD16_1CLEAR(storage, reg, field) \
42
+ (FIELD_EX16(storage, reg, field) ? \
43
+ FIELD_DP16(storage, reg, field, 0x00) : storage)
44
+
45
+#define FIELD32_1CLEAR(storage, reg, field) \
46
+ (FIELD_EX32(storage, reg, field) ? \
47
+ FIELD_DP32(storage, reg, field, 0x00) : storage)
48
+
49
+#define FIELD64_1CLEAR(storage, reg, field) \
50
+ (FIELD_EX64(storage, reg, field) ? \
51
+ FIELD_DP64(storage, reg, field, 0x00) : storage)
52
+
53
#define FIELD_SDP8(storage, reg, field, val) ({ \
54
struct { \
55
signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
56
--
57
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
use the `FIELD32_1CLEAR` macro to implement register
4
`rw1c` functionality to `ibex_spi`.
5
6
This change was tested by running the `SPI_HOST` from TockOS.
7
8
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221017054950.317584-3-wilfred.mallawa@opensource.wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/ssi/ibex_spi_host.c | 21 +++++++++------------
14
1 file changed, 9 insertions(+), 12 deletions(-)
15
16
diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/ibex_spi_host.c
19
+++ b/hw/ssi/ibex_spi_host.c
20
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
21
{
22
IbexSPIHostState *s = opaque;
23
uint32_t val32 = val64;
24
- uint32_t shift_mask = 0xff, status = 0, data = 0;
25
+ uint32_t shift_mask = 0xff, status = 0;
26
uint8_t txqd_len;
27
28
trace_ibex_spi_host_write(addr, size, val64);
29
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
30
case IBEX_SPI_HOST_INTR_STATE:
31
/* rw1c status register */
32
if (FIELD_EX32(val32, INTR_STATE, ERROR)) {
33
- data = FIELD_DP32(data, INTR_STATE, ERROR, 0);
34
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, ERROR);
35
}
36
if (FIELD_EX32(val32, INTR_STATE, SPI_EVENT)) {
37
- data = FIELD_DP32(data, INTR_STATE, SPI_EVENT, 0);
38
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, SPI_EVENT);
39
}
40
- s->regs[addr] = data;
41
break;
42
case IBEX_SPI_HOST_INTR_ENABLE:
43
s->regs[addr] = val32;
44
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
45
* When an error occurs, the corresponding bit must be cleared
46
* here before issuing any further commands
47
*/
48
- status = s->regs[addr];
49
/* rw1c status register */
50
if (FIELD_EX32(val32, ERROR_STATUS, CMDBUSY)) {
51
- status = FIELD_DP32(status, ERROR_STATUS, CMDBUSY, 0);
52
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CMDBUSY);
53
}
54
if (FIELD_EX32(val32, ERROR_STATUS, OVERFLOW)) {
55
- status = FIELD_DP32(status, ERROR_STATUS, OVERFLOW, 0);
56
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, OVERFLOW);
57
}
58
if (FIELD_EX32(val32, ERROR_STATUS, UNDERFLOW)) {
59
- status = FIELD_DP32(status, ERROR_STATUS, UNDERFLOW, 0);
60
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, UNDERFLOW);
61
}
62
if (FIELD_EX32(val32, ERROR_STATUS, CMDINVAL)) {
63
- status = FIELD_DP32(status, ERROR_STATUS, CMDINVAL, 0);
64
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CMDINVAL);
65
}
66
if (FIELD_EX32(val32, ERROR_STATUS, CSIDINVAL)) {
67
- status = FIELD_DP32(status, ERROR_STATUS, CSIDINVAL, 0);
68
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CSIDINVAL);
69
}
70
if (FIELD_EX32(val32, ERROR_STATUS, ACCESSINVAL)) {
71
- status = FIELD_DP32(status, ERROR_STATUS, ACCESSINVAL, 0);
72
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, ACCESSINVAL);
73
}
74
- s->regs[addr] = status;
75
break;
76
case IBEX_SPI_HOST_EVENT_ENABLE:
77
/* Controls which classes of SPI events raise an interrupt. */
78
--
79
2.38.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We were matching a signed 13-bit range, not a 12-bit range.
4
Expand the commentary within the function and be explicit
5
about all of the ranges.
6
7
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221022095821.2441874-1-richard.henderson@linaro.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
tcg/riscv/tcg-target.c.inc | 19 ++++++++++++++++---
15
1 file changed, 16 insertions(+), 3 deletions(-)
16
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
20
+++ b/tcg/riscv/tcg-target.c.inc
21
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
22
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
23
return 1;
24
}
25
- if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
26
+ /*
27
+ * Sign extended from 12 bits: [-0x800, 0x7ff].
28
+ * Used for most arithmetic, as this is the isa field.
29
+ */
30
+ if ((ct & TCG_CT_CONST_S12) && val >= -0x800 && val <= 0x7ff) {
31
return 1;
32
}
33
- if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
34
+ /*
35
+ * Sign extended from 12 bits, negated: [-0x7ff, 0x800].
36
+ * Used for subtraction, where a constant must be handled by ADDI.
37
+ */
38
+ if ((ct & TCG_CT_CONST_N12) && val >= -0x7ff && val <= 0x800) {
39
return 1;
40
}
41
- if ((ct & TCG_CT_CONST_M12) && val >= -0xfff && val <= 0xfff) {
42
+ /*
43
+ * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
44
+ * Used by addsub2, which may need the negative operation,
45
+ * and requires the modified constant to be representable.
46
+ */
47
+ if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
48
return 1;
49
}
50
return 0;
51
--
52
2.38.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
There was a typo using opc_addi instead of opc_add with the
4
two registers. While we're at it, simplify the gating test
5
to al == bl to improve dynamic scheduling even when the
6
output register does not overlap the inputs.
7
8
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221020233836.2341671-1-richard.henderson@linaro.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
tcg/riscv/tcg-target.c.inc | 10 ++++++++--
15
1 file changed, 8 insertions(+), 2 deletions(-)
16
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
20
+++ b/tcg/riscv/tcg-target.c.inc
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_addsub2(TCGContext *s,
22
if (cbl) {
23
tcg_out_opc_imm(s, opc_addi, rl, al, bl);
24
tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, rl, bl);
25
- } else if (rl == al && rl == bl) {
26
+ } else if (al == bl) {
27
+ /*
28
+ * If the input regs overlap, this is a simple doubling
29
+ * and carry-out is the input msb. This special case is
30
+ * required when the output reg overlaps the input,
31
+ * but we might as well use it always.
32
+ */
33
tcg_out_opc_imm(s, OPC_SLTI, TCG_REG_TMP0, al, 0);
34
- tcg_out_opc_reg(s, opc_addi, rl, al, bl);
35
+ tcg_out_opc_reg(s, opc_add, rl, al, al);
36
} else {
37
tcg_out_opc_reg(s, opc_add, rl, al, bl);
38
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0,
39
--
40
2.38.1
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
When running the instruction
3
When guest_base != 0, we were not coordinating the usage of
4
TCG_REG_TMP0 as base properly, leading to a previous zero-extend
5
of the input address being discarded.
4
6
5
```
7
Shuffle the alignment check to the front, because that does not
6
cbo.flush 0(x0)
8
depend on the zero-extend, and it keeps the register usage clear.
7
```
9
Set base after each step of the address arithmetic instead of before.
8
10
9
QEMU would segfault.
11
Return the base register used from tcg_out_tlb_load, so as to
12
keep that register choice localized to that function.
10
13
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
14
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
allocated.
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
In order to fix this let's use the existing get_address()
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
helper. This also has the benefit of performing pointer mask
18
Message-Id: <20221023233337.2846860-1-richard.henderson@linaro.org>
16
calculations on the address specified in rs1.
17
18
The pointer masking specificiation specifically states:
19
20
"""
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
20
---
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
21
tcg/riscv/tcg-target.c.inc | 39 +++++++++++++++++++++-----------------
36
1 file changed, 12 insertions(+), 4 deletions(-)
22
1 file changed, 22 insertions(+), 17 deletions(-)
37
23
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
24
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
39
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
26
--- a/tcg/riscv/tcg-target.c.inc
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
27
+++ b/tcg/riscv/tcg-target.c.inc
42
@@ -XXX,XX +XXX,XX @@
28
@@ -XXX,XX +XXX,XX @@ static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
29
tcg_debug_assert(ok);
30
}
31
32
-static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
33
- TCGReg addrh, MemOpIdx oi,
34
- tcg_insn_unit **label_ptr, bool is_load)
35
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
36
+ TCGReg addrh, MemOpIdx oi,
37
+ tcg_insn_unit **label_ptr, bool is_load)
44
{
38
{
45
REQUIRE_ZICBOM(ctx);
39
MemOp opc = get_memop(oi);
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
40
unsigned s_bits = opc & MO_SIZE;
47
+ TCGv src = get_address(ctx, a->rs1, 0);
41
@@ -XXX,XX +XXX,XX @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
48
+
42
addrl = TCG_REG_TMP0;
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
43
}
50
return true;
44
tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
45
+ return TCG_REG_TMP0;
51
}
46
}
52
47
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
48
static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
54
{
49
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
55
REQUIRE_ZICBOM(ctx);
50
#else
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
51
unsigned a_bits;
57
+ TCGv src = get_address(ctx, a->rs1, 0);
52
#endif
58
+
53
- TCGReg base = TCG_REG_TMP0;
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
54
+ TCGReg base;
60
return true;
55
61
}
56
data_regl = *args++;
62
57
data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
58
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
64
{
59
opc = get_memop(oi);
65
REQUIRE_ZICBOM(ctx);
60
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
61
#if defined(CONFIG_SOFTMMU)
67
+ TCGv src = get_address(ctx, a->rs1, 0);
62
- tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
68
+
63
+ base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
69
+ gen_helper_cbo_inval(tcg_env, src);
64
tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
70
return true;
65
add_qemu_ldst_label(s, 1, oi,
71
}
66
(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
72
67
data_regl, data_regh, addr_regl, addr_regh,
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
68
s->code_ptr, label_ptr);
74
{
69
#else
75
REQUIRE_ZICBOZ(ctx);
70
- if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
71
- tcg_out_ext32u(s, base, addr_regl);
77
+ TCGv src = get_address(ctx, a->rs1, 0);
72
- addr_regl = base;
78
+
73
- }
79
+ gen_helper_cbo_zero(tcg_env, src);
74
a_bits = get_alignment_bits(opc);
80
return true;
75
if (a_bits) {
81
}
76
tcg_out_test_alignment(s, true, addr_regl, a_bits);
77
}
78
+ base = addr_regl;
79
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
80
+ tcg_out_ext32u(s, TCG_REG_TMP0, base);
81
+ base = TCG_REG_TMP0;
82
+ }
83
if (guest_base != 0) {
84
- tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
85
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
86
+ base = TCG_REG_TMP0;
87
}
88
tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
89
#endif
90
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
91
#else
92
unsigned a_bits;
93
#endif
94
- TCGReg base = TCG_REG_TMP0;
95
+ TCGReg base;
96
97
data_regl = *args++;
98
data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
99
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
100
opc = get_memop(oi);
101
102
#if defined(CONFIG_SOFTMMU)
103
- tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
104
+ base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
105
tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
106
add_qemu_ldst_label(s, 0, oi,
107
(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
108
data_regl, data_regh, addr_regl, addr_regh,
109
s->code_ptr, label_ptr);
110
#else
111
- if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
112
- tcg_out_ext32u(s, base, addr_regl);
113
- addr_regl = base;
114
- }
115
a_bits = get_alignment_bits(opc);
116
if (a_bits) {
117
tcg_out_test_alignment(s, false, addr_regl, a_bits);
118
}
119
+ base = addr_regl;
120
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
121
+ tcg_out_ext32u(s, TCG_REG_TMP0, base);
122
+ base = TCG_REG_TMP0;
123
+ }
124
if (guest_base != 0) {
125
- tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
126
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
127
+ base = TCG_REG_TMP0;
128
}
129
tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
130
#endif
82
--
131
--
83
2.45.1
132
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
This patch updates the OpenTitan model to match
4
the specified register layout as per [1]. Which is also the latest
5
commit of OpenTitan supported by TockOS.
6
7
Note: Pinmux and Padctrl has been merged into Pinmux [2][3], this patch removes
8
any references to Padctrl. Note: OpenTitan doc [2] has not yet specified
9
much detail regarding this, except for a note that states `TODO: this
10
section needs to be updated to reflect the pinmux/padctrl merger`
11
12
[1] https://github.com/lowRISC/opentitan/blob/d072ac505f82152678d6e04be95c72b728a347b8/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
13
[2] https://docs.opentitan.org/hw/top_earlgrey/doc/design/
14
[3] https://docs.opentitan.org/hw/ip/pinmux/doc/#overview
15
16
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
19
Message-Id: <20221025043335.339815-2-wilfred.mallawa@opensource.wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
include/hw/riscv/opentitan.h | 9 ++++-----
23
hw/riscv/opentitan.c | 21 +++++++++++++--------
24
2 files changed, 17 insertions(+), 13 deletions(-)
25
26
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/riscv/opentitan.h
29
+++ b/include/hw/riscv/opentitan.h
30
@@ -XXX,XX +XXX,XX @@ enum {
31
IBEX_DEV_RSTMGR,
32
IBEX_DEV_CLKMGR,
33
IBEX_DEV_PINMUX,
34
- IBEX_DEV_PADCTRL,
35
IBEX_DEV_USBDEV,
36
IBEX_DEV_FLASH_CTRL,
37
IBEX_DEV_PLIC,
38
@@ -XXX,XX +XXX,XX @@ enum {
39
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
40
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
41
IBEX_TIMER_TIMEREXPIRED0_0 = 127,
42
- IBEX_SPI_HOST0_ERR_IRQ = 151,
43
- IBEX_SPI_HOST0_SPI_EVENT_IRQ = 152,
44
- IBEX_SPI_HOST1_ERR_IRQ = 153,
45
- IBEX_SPI_HOST1_SPI_EVENT_IRQ = 154,
46
+ IBEX_SPI_HOST0_ERR_IRQ = 134,
47
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 135,
48
+ IBEX_SPI_HOST1_ERR_IRQ = 136,
49
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 137,
50
};
51
52
#endif
53
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/riscv/opentitan.c
56
+++ b/hw/riscv/opentitan.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "qemu/units.h"
59
#include "sysemu/sysemu.h"
60
61
+/*
62
+ * This version of the OpenTitan machine currently supports
63
+ * OpenTitan RTL version:
64
+ * <lowRISC/opentitan@d072ac505f82152678d6e04be95c72b728a347b8>
65
+ *
66
+ * MMIO mapping as per (specified commit):
67
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
68
+ */
69
static const MemMapEntry ibex_memmap[] = {
70
- [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
71
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
72
[IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
73
[IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
74
[IBEX_DEV_UART] = { 0x40000000, 0x1000 },
75
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
76
[IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
77
[IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
78
[IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
79
- [IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
80
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
81
[IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
82
- [IBEX_DEV_USBDEV] = { 0x40150000, 0x1000 },
83
+ [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x1000 },
84
[IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
85
[IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
86
+ [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
87
[IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
88
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
89
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
90
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
91
- [IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
92
+ [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
93
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
94
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
95
[IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
96
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
97
[IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
98
[IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
99
[IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
100
- [IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
101
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
102
[IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
103
- [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
104
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
105
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
106
};
107
108
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
109
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
110
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
111
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
112
- create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
113
- memmap[IBEX_DEV_PADCTRL].base, memmap[IBEX_DEV_PADCTRL].size);
114
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
115
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
116
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
117
--
118
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
Adds the updated `aon_timer` base as an unimplemented device. This is
4
used by TockOS, patch ensures the guest doesn't hit load faults.
5
6
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221025043335.339815-3-wilfred.mallawa@opensource.wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
include/hw/riscv/opentitan.h | 1 +
13
hw/riscv/opentitan.c | 3 +++
14
2 files changed, 4 insertions(+)
15
16
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/riscv/opentitan.h
19
+++ b/include/hw/riscv/opentitan.h
20
@@ -XXX,XX +XXX,XX @@ enum {
21
IBEX_DEV_RSTMGR,
22
IBEX_DEV_CLKMGR,
23
IBEX_DEV_PINMUX,
24
+ IBEX_DEV_AON_TIMER,
25
IBEX_DEV_USBDEV,
26
IBEX_DEV_FLASH_CTRL,
27
IBEX_DEV_PLIC,
28
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/riscv/opentitan.c
31
+++ b/hw/riscv/opentitan.c
32
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
33
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
34
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
35
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
36
+ [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x1000 },
37
[IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
38
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
39
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
40
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
41
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
42
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
43
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
44
+ create_unimplemented_device("riscv.lowrisc.ibex.aon_timer",
45
+ memmap[IBEX_DEV_AON_TIMER].base, memmap[IBEX_DEV_AON_TIMER].size);
46
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
47
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
48
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
49
--
50
2.38.1
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
2
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
3
Smstateen extension specifies a mechanism to close
4
implements the SEED CSR. Use the same implementation as TCG.
4
the potential covert channels that could cause security issues.
5
5
6
Without this patch, running with a KVM which does not forward the
6
This patch adds the CSRs defined in the specification and
7
SEED CSR access to QEMU will result in an ILL exception being
7
the corresponding predicates and read/write functions.
8
injected into the guest (this results in Linux guests crashing on
9
boot). And, when running with a KVM which does forward the access,
10
QEMU will crash, since QEMU doesn't know what to do with the exit.
11
8
12
Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
9
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
13
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-Id: <20221016124726.102129-2-mchitale@ventanamicro.com>
16
Message-ID: <20240422134605.534207-2-ajones@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
14
---
19
target/riscv/cpu.h | 3 +++
15
target/riscv/cpu.h | 4 +
20
target/riscv/csr.c | 18 ++++++++++++++----
16
target/riscv/cpu_bits.h | 37 +++++
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
17
target/riscv/csr.c | 316 ++++++++++++++++++++++++++++++++++++++++
22
3 files changed, 42 insertions(+), 4 deletions(-)
18
target/riscv/machine.c | 21 +++
19
4 files changed, 378 insertions(+)
23
20
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
23
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
24
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
25
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
29
26
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
27
/* CSRs for execution enviornment configuration */
31
28
uint64_t menvcfg;
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
29
+ uint64_t mstateen[SMSTATEEN_MAX_COUNT];
33
+ target_ulong write_mask);
30
+ uint64_t hstateen[SMSTATEEN_MAX_COUNT];
34
+
31
+ uint64_t sstateen[SMSTATEEN_MAX_COUNT];
35
uint8_t satp_mode_max_from_map(uint32_t map);
32
target_ulong senvcfg;
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
33
uint64_t henvcfg;
37
34
#endif
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_ifencei;
37
bool ext_icsr;
38
bool ext_zihintpause;
39
+ bool ext_smstateen;
40
bool ext_sstc;
41
bool ext_svinval;
42
bool ext_svnapot;
43
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu_bits.h
46
+++ b/target/riscv/cpu_bits.h
47
@@ -XXX,XX +XXX,XX @@
48
/* Supervisor Configuration CSRs */
49
#define CSR_SENVCFG 0x10A
50
51
+/* Supervisor state CSRs */
52
+#define CSR_SSTATEEN0 0x10C
53
+#define CSR_SSTATEEN1 0x10D
54
+#define CSR_SSTATEEN2 0x10E
55
+#define CSR_SSTATEEN3 0x10F
56
+
57
/* Supervisor Trap Handling */
58
#define CSR_SSCRATCH 0x140
59
#define CSR_SEPC 0x141
60
@@ -XXX,XX +XXX,XX @@
61
#define CSR_HENVCFG 0x60A
62
#define CSR_HENVCFGH 0x61A
63
64
+/* Hypervisor state CSRs */
65
+#define CSR_HSTATEEN0 0x60C
66
+#define CSR_HSTATEEN0H 0x61C
67
+#define CSR_HSTATEEN1 0x60D
68
+#define CSR_HSTATEEN1H 0x61D
69
+#define CSR_HSTATEEN2 0x60E
70
+#define CSR_HSTATEEN2H 0x61E
71
+#define CSR_HSTATEEN3 0x60F
72
+#define CSR_HSTATEEN3H 0x61F
73
+
74
/* Virtual CSRs */
75
#define CSR_VSSTATUS 0x200
76
#define CSR_VSIE 0x204
77
@@ -XXX,XX +XXX,XX @@
78
#define CSR_MENVCFG 0x30A
79
#define CSR_MENVCFGH 0x31A
80
81
+/* Machine state CSRs */
82
+#define CSR_MSTATEEN0 0x30C
83
+#define CSR_MSTATEEN0H 0x31C
84
+#define CSR_MSTATEEN1 0x30D
85
+#define CSR_MSTATEEN1H 0x31D
86
+#define CSR_MSTATEEN2 0x30E
87
+#define CSR_MSTATEEN2H 0x31E
88
+#define CSR_MSTATEEN3 0x30F
89
+#define CSR_MSTATEEN3H 0x31F
90
+
91
+/* Common defines for all smstateen */
92
+#define SMSTATEEN_MAX_COUNT 4
93
+#define SMSTATEEN0_CS (1ULL << 0)
94
+#define SMSTATEEN0_FCSR (1ULL << 1)
95
+#define SMSTATEEN0_HSCONTXT (1ULL << 57)
96
+#define SMSTATEEN0_IMSIC (1ULL << 58)
97
+#define SMSTATEEN0_AIA (1ULL << 59)
98
+#define SMSTATEEN0_SVSLCT (1ULL << 60)
99
+#define SMSTATEEN0_HSENVCFG (1ULL << 62)
100
+#define SMSTATEEN_STATEEN (1ULL << 63)
101
+
102
/* Enhanced Physical Memory Protection (ePMP) */
103
#define CSR_MSECCFG 0x747
104
#define CSR_MSECCFGH 0x757
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
105
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
39
index XXXXXXX..XXXXXXX 100644
106
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/csr.c
107
--- a/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
108
+++ b/target/riscv/csr.c
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
109
@@ -XXX,XX +XXX,XX @@ static RISCVException umode32(CPURISCVState *env, int csrno)
43
#endif
110
return umode(env, csrno);
44
111
}
45
/* Crypto Extension */
112
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
113
+static RISCVException mstateen(CPURISCVState *env, int csrno)
47
- target_ulong *ret_value,
114
+{
48
- target_ulong new_value,
115
+ CPUState *cs = env_cpu(env);
49
- target_ulong write_mask)
116
+ RISCVCPU *cpu = RISCV_CPU(cs);
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
117
+
51
+ target_ulong write_mask)
118
+ if (!cpu->cfg.ext_smstateen) {
119
+ return RISCV_EXCP_ILLEGAL_INST;
120
+ }
121
+
122
+ return any(env, csrno);
123
+}
124
+
125
+static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
126
+{
127
+ CPUState *cs = env_cpu(env);
128
+ RISCVCPU *cpu = RISCV_CPU(cs);
129
+
130
+ if (!cpu->cfg.ext_smstateen) {
131
+ return RISCV_EXCP_ILLEGAL_INST;
132
+ }
133
+
134
+ if (env->priv < PRV_M) {
135
+ if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
136
+ return RISCV_EXCP_ILLEGAL_INST;
137
+ }
138
+ }
139
+
140
+ return hmode(env, csrno);
141
+}
142
+
143
+static RISCVException hstateen(CPURISCVState *env, int csrno)
144
+{
145
+ return hstateen_pred(env, csrno, CSR_HSTATEEN0);
146
+}
147
+
148
+static RISCVException hstateenh(CPURISCVState *env, int csrno)
149
+{
150
+ return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
151
+}
152
+
153
+static RISCVException sstateen(CPURISCVState *env, int csrno)
154
+{
155
+ bool virt = riscv_cpu_virt_enabled(env);
156
+ int index = csrno - CSR_SSTATEEN0;
157
+ CPUState *cs = env_cpu(env);
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
159
+
160
+ if (!cpu->cfg.ext_smstateen) {
161
+ return RISCV_EXCP_ILLEGAL_INST;
162
+ }
163
+
164
+ if (env->priv < PRV_M) {
165
+ if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
166
+ return RISCV_EXCP_ILLEGAL_INST;
167
+ }
168
+
169
+ if (virt) {
170
+ if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
171
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
172
+ }
173
+ }
174
+ }
175
+
176
+ return smode(env, csrno);
177
+}
178
+
179
/* Checks if PointerMasking registers could be accessed */
180
static RISCVException pointer_masking(CPURISCVState *env, int csrno)
52
{
181
{
53
uint16_t random_v;
182
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
54
Error *random_e = NULL;
183
return RISCV_EXCP_NONE;
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
184
}
56
rval = random_v | SEED_OPST_ES16;
185
186
+static RISCVException read_mstateen(CPURISCVState *env, int csrno,
187
+ target_ulong *val)
188
+{
189
+ *val = env->mstateen[csrno - CSR_MSTATEEN0];
190
+
191
+ return RISCV_EXCP_NONE;
192
+}
193
+
194
+static RISCVException write_mstateen(CPURISCVState *env, int csrno,
195
+ uint64_t wr_mask, target_ulong new_val)
196
+{
197
+ uint64_t *reg;
198
+
199
+ reg = &env->mstateen[csrno - CSR_MSTATEEN0];
200
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
201
+
202
+ return RISCV_EXCP_NONE;
203
+}
204
+
205
+static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
206
+ target_ulong new_val)
207
+{
208
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
209
+
210
+ return write_mstateen(env, csrno, wr_mask, new_val);
211
+}
212
+
213
+static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
214
+ target_ulong new_val)
215
+{
216
+ return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
217
+}
218
+
219
+static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
220
+ target_ulong *val)
221
+{
222
+ *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
223
+
224
+ return RISCV_EXCP_NONE;
225
+}
226
+
227
+static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
228
+ uint64_t wr_mask, target_ulong new_val)
229
+{
230
+ uint64_t *reg, val;
231
+
232
+ reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
233
+ val = (uint64_t)new_val << 32;
234
+ val |= *reg & 0xFFFFFFFF;
235
+ *reg = (*reg & ~wr_mask) | (val & wr_mask);
236
+
237
+ return RISCV_EXCP_NONE;
238
+}
239
+
240
+static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
241
+ target_ulong new_val)
242
+{
243
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
244
+
245
+ return write_mstateenh(env, csrno, wr_mask, new_val);
246
+}
247
+
248
+static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
249
+ target_ulong new_val)
250
+{
251
+ return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
252
+}
253
+
254
+static RISCVException read_hstateen(CPURISCVState *env, int csrno,
255
+ target_ulong *val)
256
+{
257
+ int index = csrno - CSR_HSTATEEN0;
258
+
259
+ *val = env->hstateen[index] & env->mstateen[index];
260
+
261
+ return RISCV_EXCP_NONE;
262
+}
263
+
264
+static RISCVException write_hstateen(CPURISCVState *env, int csrno,
265
+ uint64_t mask, target_ulong new_val)
266
+{
267
+ int index = csrno - CSR_HSTATEEN0;
268
+ uint64_t *reg, wr_mask;
269
+
270
+ reg = &env->hstateen[index];
271
+ wr_mask = env->mstateen[index] & mask;
272
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
273
+
274
+ return RISCV_EXCP_NONE;
275
+}
276
+
277
+static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
278
+ target_ulong new_val)
279
+{
280
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
281
+
282
+ return write_hstateen(env, csrno, wr_mask, new_val);
283
+}
284
+
285
+static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
286
+ target_ulong new_val)
287
+{
288
+ return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
289
+}
290
+
291
+static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
292
+ target_ulong *val)
293
+{
294
+ int index = csrno - CSR_HSTATEEN0H;
295
+
296
+ *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
297
+
298
+ return RISCV_EXCP_NONE;
299
+}
300
+
301
+static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
302
+ uint64_t mask, target_ulong new_val)
303
+{
304
+ int index = csrno - CSR_HSTATEEN0H;
305
+ uint64_t *reg, wr_mask, val;
306
+
307
+ reg = &env->hstateen[index];
308
+ val = (uint64_t)new_val << 32;
309
+ val |= *reg & 0xFFFFFFFF;
310
+ wr_mask = env->mstateen[index] & mask;
311
+ *reg = (*reg & ~wr_mask) | (val & wr_mask);
312
+
313
+ return RISCV_EXCP_NONE;
314
+}
315
+
316
+static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
317
+ target_ulong new_val)
318
+{
319
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
320
+
321
+ return write_hstateenh(env, csrno, wr_mask, new_val);
322
+}
323
+
324
+static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
325
+ target_ulong new_val)
326
+{
327
+ return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
328
+}
329
+
330
+static RISCVException read_sstateen(CPURISCVState *env, int csrno,
331
+ target_ulong *val)
332
+{
333
+ bool virt = riscv_cpu_virt_enabled(env);
334
+ int index = csrno - CSR_SSTATEEN0;
335
+
336
+ *val = env->sstateen[index] & env->mstateen[index];
337
+ if (virt) {
338
+ *val &= env->hstateen[index];
339
+ }
340
+
341
+ return RISCV_EXCP_NONE;
342
+}
343
+
344
+static RISCVException write_sstateen(CPURISCVState *env, int csrno,
345
+ uint64_t mask, target_ulong new_val)
346
+{
347
+ bool virt = riscv_cpu_virt_enabled(env);
348
+ int index = csrno - CSR_SSTATEEN0;
349
+ uint64_t wr_mask;
350
+ uint64_t *reg;
351
+
352
+ wr_mask = env->mstateen[index] & mask;
353
+ if (virt) {
354
+ wr_mask &= env->hstateen[index];
355
+ }
356
+
357
+ reg = &env->sstateen[index];
358
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
359
+
360
+ return RISCV_EXCP_NONE;
361
+}
362
+
363
+static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
364
+ target_ulong new_val)
365
+{
366
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
367
+
368
+ return write_sstateen(env, csrno, wr_mask, new_val);
369
+}
370
+
371
+static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
372
+ target_ulong new_val)
373
+{
374
+ return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
375
+}
376
+
377
static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
378
uint64_t *ret_val,
379
uint64_t new_val, uint64_t wr_mask)
380
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
381
[CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
382
.min_priv_ver = PRIV_VERSION_1_12_0 },
383
384
+ /* Smstateen extension CSRs */
385
+ [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
386
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
387
+ [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
388
+ write_mstateen0h,
389
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
390
+ [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
391
+ write_mstateen_1_3,
392
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
393
+ [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
394
+ write_mstateenh_1_3,
395
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
396
+ [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
397
+ write_mstateen_1_3,
398
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
399
+ [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
400
+ write_mstateenh_1_3,
401
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
402
+ [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
403
+ write_mstateen_1_3,
404
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
405
+ [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
406
+ write_mstateenh_1_3,
407
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
408
+ [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
409
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
410
+ [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
411
+ write_hstateen0h,
412
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
413
+ [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
414
+ write_hstateen_1_3,
415
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
416
+ [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
417
+ write_hstateenh_1_3,
418
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
419
+ [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
420
+ write_hstateen_1_3,
421
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
422
+ [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
423
+ write_hstateenh_1_3,
424
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
425
+ [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
426
+ write_hstateen_1_3,
427
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
428
+ [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
429
+ write_hstateenh_1_3,
430
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
431
+ [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
432
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
433
+ [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
434
+ write_sstateen_1_3,
435
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
436
+ [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
437
+ write_sstateen_1_3,
438
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
439
+ [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
440
+ write_sstateen_1_3,
441
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
442
+
443
/* Supervisor Trap Setup */
444
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
445
NULL, read_sstatus_i128 },
446
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
447
index XXXXXXX..XXXXXXX 100644
448
--- a/target/riscv/machine.c
449
+++ b/target/riscv/machine.c
450
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_post_load(void *opaque, int version_id)
451
return 0;
452
}
453
454
+static bool smstateen_needed(void *opaque)
455
+{
456
+ RISCVCPU *cpu = opaque;
457
+
458
+ return cpu->cfg.ext_smstateen;
459
+}
460
+
461
+static const VMStateDescription vmstate_smstateen = {
462
+ .name = "cpu/smtateen",
463
+ .version_id = 1,
464
+ .minimum_version_id = 1,
465
+ .needed = smstateen_needed,
466
+ .fields = (VMStateField[]) {
467
+ VMSTATE_UINT64_ARRAY(env.mstateen, RISCVCPU, 4),
468
+ VMSTATE_UINT64_ARRAY(env.hstateen, RISCVCPU, 4),
469
+ VMSTATE_UINT64_ARRAY(env.sstateen, RISCVCPU, 4),
470
+ VMSTATE_END_OF_LIST()
471
+ }
472
+};
473
+
474
static bool envcfg_needed(void *opaque)
475
{
476
RISCVCPU *cpu = opaque;
477
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
478
&vmstate_kvmtimer,
479
&vmstate_envcfg,
480
&vmstate_debug,
481
+ &vmstate_smstateen,
482
NULL
57
}
483
}
58
484
};
59
+ return rval;
60
+}
61
+
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
63
+ target_ulong *ret_value,
64
+ target_ulong new_value,
65
+ target_ulong write_mask)
66
+{
67
+ target_ulong rval;
68
+
69
+ rval = riscv_new_csr_seed(new_value, write_mask);
70
+
71
if (ret_value) {
72
*ret_value = rval;
73
}
74
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
75
index XXXXXXX..XXXXXXX 100644
76
--- a/target/riscv/kvm/kvm-cpu.c
77
+++ b/target/riscv/kvm/kvm-cpu.c
78
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
79
return ret;
80
}
81
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
83
+{
84
+ target_ulong csr_num = run->riscv_csr.csr_num;
85
+ target_ulong new_value = run->riscv_csr.new_value;
86
+ target_ulong write_mask = run->riscv_csr.write_mask;
87
+ int ret = 0;
88
+
89
+ switch (csr_num) {
90
+ case CSR_SEED:
91
+ run->riscv_csr.ret_value = riscv_new_csr_seed(new_value, write_mask);
92
+ break;
93
+ default:
94
+ qemu_log_mask(LOG_UNIMP,
95
+ "%s: un-handled CSR EXIT for CSR %lx\n",
96
+ __func__, csr_num);
97
+ ret = -1;
98
+ break;
99
+ }
100
+
101
+ return ret;
102
+}
103
+
104
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
105
{
106
int ret = 0;
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
108
case KVM_EXIT_RISCV_SBI:
109
ret = kvm_riscv_handle_sbi(cs, run);
110
break;
111
+ case KVM_EXIT_RISCV_CSR:
112
+ ret = kvm_riscv_handle_csr(cs, run);
113
+ break;
114
default:
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
116
__func__, run->exit_reason);
117
--
485
--
118
2.45.1
486
2.38.1
diff view generated by jsdifflib
1
From: Yu-Ming Chang <yumin686@andestech.com>
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
2
2
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
3
Accesses to henvcfg, henvcfgh and senvcfg are allowed only if the corresponding
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
4
bit in mstateen0/hstateen0 is enabled. Otherwise an illegal instruction trap is
5
holding a zero value other than x0, the instruction will still attempt to write
5
generated.
6
the unmodified value back to the CSR and will cause any attendant side effects.
7
6
8
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
9
a register holding a zero value, an illegal instruction exception should be
8
Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn>
10
raised.
11
12
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
10
Message-Id: <20221016124726.102129-3-mchitale@ventanamicro.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
12
---
17
target/riscv/cpu.h | 4 ++++
13
target/riscv/csr.c | 87 ++++++++++++++++++++++++++++++++++++++++++----
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
14
1 file changed, 80 insertions(+), 7 deletions(-)
19
target/riscv/op_helper.c | 6 ++---
20
3 files changed, 53 insertions(+), 8 deletions(-)
21
15
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.h
25
+++ b/target/riscv/cpu.h
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
27
void riscv_cpu_update_mask(CPURISCVState *env);
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
29
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
31
+ target_ulong *ret_value);
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
33
target_ulong *ret_value,
34
target_ulong new_value, target_ulong write_mask);
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
36
target_ulong new_value,
37
target_ulong write_mask);
38
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
40
+ Int128 *ret_value);
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
42
Int128 *ret_value,
43
Int128 new_value, Int128 write_mask);
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
45
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/csr.c
18
--- a/target/riscv/csr.c
47
+++ b/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
20
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
49
21
}
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
22
51
int csrno,
23
/* Predicates */
52
- bool write_mask)
24
+#if !defined(CONFIG_USER_ONLY)
53
+ bool write)
25
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
26
+ uint64_t bit)
27
+{
28
+ bool virt = riscv_cpu_virt_enabled(env);
29
+ CPUState *cs = env_cpu(env);
30
+ RISCVCPU *cpu = RISCV_CPU(cs);
31
+
32
+ if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
33
+ return RISCV_EXCP_NONE;
34
+ }
35
+
36
+ if (!(env->mstateen[index] & bit)) {
37
+ return RISCV_EXCP_ILLEGAL_INST;
38
+ }
39
+
40
+ if (virt) {
41
+ if (!(env->hstateen[index] & bit)) {
42
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
43
+ }
44
+
45
+ if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
46
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
47
+ }
48
+ }
49
+
50
+ if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
51
+ if (!(env->sstateen[index] & bit)) {
52
+ return RISCV_EXCP_ILLEGAL_INST;
53
+ }
54
+ }
55
+
56
+ return RISCV_EXCP_NONE;
57
+}
58
+#endif
59
+
60
static RISCVException fs(CPURISCVState *env, int csrno)
54
{
61
{
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
62
#if !defined(CONFIG_USER_ONLY)
56
bool read_only = get_field(csrno, 0xC00) == 3;
63
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
64
static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
58
}
65
target_ulong *val)
59
66
{
60
/* read / write check */
67
+ RISCVException ret;
61
- if (write_mask && read_only) {
68
+
62
+ if (write && read_only) {
69
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
63
return RISCV_EXCP_ILLEGAL_INST;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
67
return RISCV_EXCP_NONE;
68
}
69
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
71
+ target_ulong *ret_value)
72
+{
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
74
+ if (ret != RISCV_EXCP_NONE) {
70
+ if (ret != RISCV_EXCP_NONE) {
75
+ return ret;
71
+ return ret;
76
+ }
72
+ }
77
+
73
+
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
74
*val = env->senvcfg;
79
+}
80
+
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
82
target_ulong *ret_value,
83
target_ulong new_value, target_ulong write_mask)
84
{
85
- RISCVException ret = riscv_csrrw_check(env, csrno, write_mask);
86
+ RISCVException ret = riscv_csrrw_check(env, csrno, true);
87
if (ret != RISCV_EXCP_NONE) {
88
return ret;
89
}
90
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do128(CPURISCVState *env, int csrno,
91
return RISCV_EXCP_NONE;
75
return RISCV_EXCP_NONE;
92
}
76
}
93
77
@@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
94
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
78
target_ulong val)
95
+ Int128 *ret_value)
79
{
96
+{
80
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
81
+ RISCVException ret;
82
83
- env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
84
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
85
+ if (ret != RISCV_EXCP_NONE) {
86
+ return ret;
87
+ }
88
89
+ env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
90
return RISCV_EXCP_NONE;
91
}
92
93
static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
94
target_ulong *val)
95
{
97
+ RISCVException ret;
96
+ RISCVException ret;
98
+
97
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
98
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
100
+ if (ret != RISCV_EXCP_NONE) {
99
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
100
+ return ret;
102
+ }
101
+ }
103
+
102
+
104
+ if (csr_ops[csrno].read128) {
103
*val = env->henvcfg;
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
104
return RISCV_EXCP_NONE;
106
+ int128_zero(), int128_zero());
105
}
106
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
107
target_ulong val)
108
{
109
uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
110
+ RISCVException ret;
111
+
112
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
113
+ if (ret != RISCV_EXCP_NONE) {
114
+ return ret;
115
+ }
116
117
if (riscv_cpu_mxl(env) == MXL_RV64) {
118
mask |= HENVCFG_PBMTE | HENVCFG_STCE;
119
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
120
static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
121
target_ulong *val)
122
{
123
+ RISCVException ret;
124
+
125
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
126
+ if (ret != RISCV_EXCP_NONE) {
127
+ return ret;
107
+ }
128
+ }
108
+
129
+
109
+ /*
130
*val = env->henvcfg >> 32;
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
131
return RISCV_EXCP_NONE;
111
+ * at all defined.
132
}
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
133
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
113
+ * significant), for those, this fallback is correctly handling the
134
{
114
+ * accesses
135
uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
115
+ */
136
uint64_t valh = (uint64_t)val << 32;
116
+ target_ulong old_value;
137
+ RISCVException ret;
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
138
118
+ (target_ulong)0,
139
- env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
119
+ (target_ulong)0);
140
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
141
+ if (ret != RISCV_EXCP_NONE) {
121
+ *ret_value = int128_make64(old_value);
142
+ return ret;
122
+ }
143
+ }
123
+ return ret;
144
124
+}
145
+ env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
125
+
146
return RISCV_EXCP_NONE;
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
147
}
127
Int128 *ret_value,
148
128
Int128 new_value, Int128 write_mask)
149
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
150
static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
151
target_ulong new_val)
129
{
152
{
130
RISCVException ret;
153
- uint64_t wr_mask = SMSTATEEN_STATEEN;
131
154
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
155
133
+ ret = riscv_csrrw_check(env, csrno, true);
156
return write_mstateen(env, csrno, wr_mask, new_val);
134
if (ret != RISCV_EXCP_NONE) {
157
}
135
return ret;
158
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
136
}
159
static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
160
target_ulong new_val)
138
index XXXXXXX..XXXXXXX 100644
139
--- a/target/riscv/op_helper.c
140
+++ b/target/riscv/op_helper.c
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
142
}
143
144
target_ulong val = 0;
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
147
148
if (ret != RISCV_EXCP_NONE) {
149
riscv_raise_exception(env, ret, GETPC());
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
152
{
161
{
153
Int128 rv = int128_zero();
162
- uint64_t wr_mask = SMSTATEEN_STATEEN;
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
163
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
155
- int128_zero(),
164
156
- int128_zero());
165
return write_mstateenh(env, csrno, wr_mask, new_val);
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
166
}
158
167
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateen(CPURISCVState *env, int csrno,
159
if (ret != RISCV_EXCP_NONE) {
168
static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
160
riscv_raise_exception(env, ret, GETPC());
169
target_ulong new_val)
170
{
171
- uint64_t wr_mask = SMSTATEEN_STATEEN;
172
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
173
174
return write_hstateen(env, csrno, wr_mask, new_val);
175
}
176
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
177
static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
178
target_ulong new_val)
179
{
180
- uint64_t wr_mask = SMSTATEEN_STATEEN;
181
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
182
183
return write_hstateenh(env, csrno, wr_mask, new_val);
184
}
185
@@ -XXX,XX +XXX,XX @@ static RISCVException write_sstateen(CPURISCVState *env, int csrno,
186
static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
187
target_ulong new_val)
188
{
189
- uint64_t wr_mask = SMSTATEEN_STATEEN;
190
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
191
192
return write_sstateen(env, csrno, wr_mask, new_val);
193
}
161
--
194
--
162
2.45.1
195
2.38.1
diff view generated by jsdifflib
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
2
2
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
3
This patch adds a mechanism to generate a virtual instruction
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
4
instruction exception instead of an illegal instruction exception
5
agnostic policy.
5
during instruction decode when virt is enabled.
6
6
7
However, this function can't deal the big endian situation. This patch fixes
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
8
the problem by adding handling of such case.
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
10
Message-Id: <20221016124726.102129-4-mchitale@ventanamicro.com>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
12
---
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
13
target/riscv/translate.c | 8 +++++++-
18
1 file changed, 22 insertions(+)
14
1 file changed, 7 insertions(+), 1 deletion(-)
19
15
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
16
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/vector_internals.c
18
--- a/target/riscv/translate.c
23
+++ b/target/riscv/vector_internals.c
19
+++ b/target/riscv/translate.c
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
20
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
25
if (tot - cnt == 0) {
21
to reset this known value. */
26
return ;
22
int frm;
27
}
23
RISCVMXL ol;
28
+
24
+ bool virt_inst_excp;
29
+ if (HOST_BIG_ENDIAN) {
25
bool virt_enabled;
30
+ /*
26
const RISCVCPUConfig *cfg_ptr;
31
+ * Deal the situation when the elements are insdie
27
bool hlsx;
32
+ * only one uint64 block including setting the
28
@@ -XXX,XX +XXX,XX @@ static void gen_exception_illegal(DisasContext *ctx)
33
+ * masked-off element.
29
{
34
+ */
30
tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
35
+ if (((tot - 1) ^ cnt) < 8) {
31
offsetof(CPURISCVState, bins));
36
+ memset(base + H1(tot - 1), -1, tot - cnt);
32
- generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
37
+ return;
33
+ if (ctx->virt_inst_excp) {
38
+ }
34
+ generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
39
+ /*
35
+ } else {
40
+ * Otherwise, at least cross two uint64_t blocks.
36
+ generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
41
+ * Set first unaligned block.
42
+ */
43
+ if (cnt % 8 != 0) {
44
+ uint32_t j = ROUND_UP(cnt, 8);
45
+ memset(base + H1(j - 1), -1, j - cnt);
46
+ cnt = j;
47
+ }
48
+ /* Set other 64bit aligend blocks */
49
+ }
37
+ }
50
memset(base + cnt, -1, tot - cnt);
51
}
38
}
52
39
40
static void gen_exception_inst_addr_mis(DisasContext *ctx)
41
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
42
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps },
43
};
44
45
+ ctx->virt_inst_excp = false;
46
/* Check for compressed insn */
47
if (insn_len(opcode) == 2) {
48
if (!has_ext(ctx, RVC)) {
53
--
49
--
54
2.45.1
50
2.38.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
Add support for Zve32x extension and replace some checks for Zve32f with
3
When icount is not enabled, there is no API in QEMU that can get the
4
Zve32x, since Zve32f depends on Zve32x.
4
guest instruction number.
5
5
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
Translate the guest code in a way that each TB only has one instruction.
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
After executing the instruction, decrease the count by 1 until it reaches 0
8
Reviewed-by: Max Chou <max.chou@sifive.com>
8
where the itrigger fires.
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
10
Note that only when priviledge matches the itrigger configuration,
11
the count will decrease.
12
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20221013062946.7530-2-zhiwei_liu@linux.alibaba.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
17
---
13
target/riscv/cpu_cfg.h | 1 +
18
target/riscv/cpu.h | 2 +
14
target/riscv/cpu.c | 2 ++
19
target/riscv/debug.h | 12 ++++
15
target/riscv/cpu_helper.c | 2 +-
20
target/riscv/helper.h | 2 +
16
target/riscv/csr.c | 2 +-
21
target/riscv/cpu_helper.c | 6 ++
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
22
target/riscv/debug.c | 71 +++++++++++++++++++
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
23
target/riscv/translate.c | 33 ++++++++-
19
6 files changed, 15 insertions(+), 12 deletions(-)
24
.../riscv/insn_trans/trans_privileged.c.inc | 4 +-
20
25
target/riscv/insn_trans/trans_rvi.c.inc | 8 +--
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
26
target/riscv/insn_trans/trans_rvv.c.inc | 4 +-
22
index XXXXXXX..XXXXXXX 100644
27
9 files changed, 131 insertions(+), 11 deletions(-)
23
--- a/target/riscv/cpu_cfg.h
28
24
+++ b/target/riscv/cpu_cfg.h
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
30
index XXXXXXX..XXXXXXX 100644
26
bool ext_zhinx;
31
--- a/target/riscv/cpu.h
27
bool ext_zhinxmin;
32
+++ b/target/riscv/cpu.h
28
bool ext_zve32f;
33
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
29
+ bool ext_zve32x;
34
FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
30
bool ext_zve64f;
35
FIELD(TB_FLAGS, VTA, 24, 1)
31
bool ext_zve64d;
36
FIELD(TB_FLAGS, VMA, 25, 1)
32
bool ext_zvbb;
37
+/* Native debug itrigger */
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
38
+FIELD(TB_FLAGS, ITRIGGER, 26, 1)
34
index XXXXXXX..XXXXXXX 100644
39
35
--- a/target/riscv/cpu.c
40
#ifdef TARGET_RISCV32
36
+++ b/target/riscv/cpu.c
41
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
42
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
43
index XXXXXXX..XXXXXXX 100644
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
44
--- a/target/riscv/debug.h
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
45
+++ b/target/riscv/debug.h
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
46
@@ -XXX,XX +XXX,XX @@ enum {
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
47
SIZE_NUM = 16
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
48
};
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
49
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
50
+/* itrigger filed masks */
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
51
+#define ITRIGGER_ACTION 0x3f
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
52
+#define ITRIGGER_U BIT(6)
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
53
+#define ITRIGGER_S BIT(7)
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
54
+#define ITRIGGER_PENDING BIT(8)
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
55
+#define ITRIGGER_M BIT(9)
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
56
+#define ITRIGGER_COUNT (0x3fff << 10)
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
57
+#define ITRIGGER_HIT BIT(24)
58
+#define ITRIGGER_VU BIT(25)
59
+#define ITRIGGER_VS BIT(26)
60
+
61
bool tdata_available(CPURISCVState *env, int tdata_index);
62
63
target_ulong tselect_csr_read(CPURISCVState *env);
64
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
65
66
void riscv_trigger_init(CPURISCVState *env);
67
68
+bool riscv_itrigger_enabled(CPURISCVState *env);
69
#endif /* RISCV_DEBUG_H */
70
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/riscv/helper.h
73
+++ b/target/riscv/helper.h
74
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(sret, tl, env)
75
DEF_HELPER_1(mret, tl, env)
76
DEF_HELPER_1(wfi, void, env)
77
DEF_HELPER_1(tlb_flush, void, env)
78
+/* Native Debug */
79
+DEF_HELPER_1(itrigger_match, void, env)
80
#endif
81
82
/* Hypervisor functions */
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
83
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
54
index XXXXXXX..XXXXXXX 100644
84
index XXXXXXX..XXXXXXX 100644
55
--- a/target/riscv/cpu_helper.c
85
--- a/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
86
+++ b/target/riscv/cpu_helper.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
87
@@ -XXX,XX +XXX,XX @@
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
88
#include "tcg/tcg-op.h"
59
*cs_base = 0;
89
#include "trace.h"
60
90
#include "semihosting/common-semi.h"
61
- if (cpu->cfg.ext_zve32f) {
91
+#include "sysemu/cpu-timers.h"
62
+ if (cpu->cfg.ext_zve32x) {
92
#include "cpu_bits.h"
63
/*
93
+#include "debug.h"
64
* If env->vl equals to VLMAX, we can use generic vector operation
94
65
* expanders (GVEC) to accerlate the vector operations.
95
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
66
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/csr.c
69
+++ b/target/riscv/csr.c
70
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
71
72
static RISCVException vs(CPURISCVState *env, int csrno)
73
{
96
{
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
97
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
98
flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
76
#if !defined(CONFIG_USER_ONLY)
99
get_field(env->mstatus_hs, MSTATUS_VS));
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
78
return RISCV_EXCP_ILLEGAL_INST;
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
80
index XXXXXXX..XXXXXXX 100644
81
--- a/target/riscv/tcg/tcg-cpu.c
82
+++ b/target/riscv/tcg/tcg-cpu.c
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
84
return;
85
}
100
}
86
101
+ if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
102
+ flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
103
+ riscv_itrigger_enabled(env));
89
- return;
104
+ }
90
+ /* The Zve32f extension depends on the Zve32x extension */
105
#endif
91
+ if (cpu->cfg.ext_zve32f) {
106
92
+ if (!riscv_has_ext(env, RVF)) {
107
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
108
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
94
+ return;
109
index XXXXXXX..XXXXXXX 100644
95
+ }
110
--- a/target/riscv/debug.c
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
111
+++ b/target/riscv/debug.c
112
@@ -XXX,XX +XXX,XX @@
113
#include "cpu.h"
114
#include "trace.h"
115
#include "exec/exec-all.h"
116
+#include "exec/helper-proto.h"
117
118
/*
119
* The following M-mode trigger CSRs are implemented:
120
@@ -XXX,XX +XXX,XX @@ static void type6_reg_write(CPURISCVState *env, target_ulong index,
121
return;
122
}
123
124
+/* icount trigger type */
125
+static inline int
126
+itrigger_get_count(CPURISCVState *env, int index)
127
+{
128
+ return get_field(env->tdata1[index], ITRIGGER_COUNT);
129
+}
130
+
131
+static inline void
132
+itrigger_set_count(CPURISCVState *env, int index, int value)
133
+{
134
+ env->tdata1[index] = set_field(env->tdata1[index],
135
+ ITRIGGER_COUNT, value);
136
+}
137
+
138
+static bool check_itrigger_priv(CPURISCVState *env, int index)
139
+{
140
+ target_ulong tdata1 = env->tdata1[index];
141
+ if (riscv_cpu_virt_enabled(env)) {
142
+ /* check VU/VS bit against current privilege level */
143
+ return (get_field(tdata1, ITRIGGER_VS) == env->priv) ||
144
+ (get_field(tdata1, ITRIGGER_VU) == env->priv);
145
+ } else {
146
+ /* check U/S/M bit against current privilege level */
147
+ return (get_field(tdata1, ITRIGGER_M) == env->priv) ||
148
+ (get_field(tdata1, ITRIGGER_S) == env->priv) ||
149
+ (get_field(tdata1, ITRIGGER_U) == env->priv);
150
+ }
151
+}
152
+
153
+bool riscv_itrigger_enabled(CPURISCVState *env)
154
+{
155
+ int count;
156
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
157
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
158
+ continue;
159
+ }
160
+ if (check_itrigger_priv(env, i)) {
161
+ continue;
162
+ }
163
+ count = itrigger_get_count(env, i);
164
+ if (!count) {
165
+ continue;
166
+ }
167
+ return true;
168
+ }
169
+
170
+ return false;
171
+}
172
+
173
+void helper_itrigger_match(CPURISCVState *env)
174
+{
175
+ int count;
176
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
177
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
178
+ continue;
179
+ }
180
+ if (check_itrigger_priv(env, i)) {
181
+ continue;
182
+ }
183
+ count = itrigger_get_count(env, i);
184
+ if (!count) {
185
+ continue;
186
+ }
187
+ itrigger_set_count(env, i, count--);
188
+ if (!count) {
189
+ do_trigger_action(env, i);
190
+ }
191
+ }
192
+}
193
+
194
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
195
{
196
switch (tdata_index) {
197
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/target/riscv/translate.c
200
+++ b/target/riscv/translate.c
201
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
202
/* PointerMasking extension */
203
bool pm_mask_enabled;
204
bool pm_base_enabled;
205
+ /* Use icount trigger for native debug */
206
+ bool itrigger;
207
/* TCG of the current insn_start */
208
TCGOp *insn_start;
209
} DisasContext;
210
@@ -XXX,XX +XXX,XX @@ static void gen_exception_inst_addr_mis(DisasContext *ctx)
211
generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
212
}
213
214
+static void lookup_and_goto_ptr(DisasContext *ctx)
215
+{
216
+#ifndef CONFIG_USER_ONLY
217
+ if (ctx->itrigger) {
218
+ gen_helper_itrigger_match(cpu_env);
219
+ }
220
+#endif
221
+ tcg_gen_lookup_and_goto_ptr();
222
+}
223
+
224
+static void exit_tb(DisasContext *ctx)
225
+{
226
+#ifndef CONFIG_USER_ONLY
227
+ if (ctx->itrigger) {
228
+ gen_helper_itrigger_match(cpu_env);
229
+ }
230
+#endif
231
+ tcg_gen_exit_tb(NULL, 0);
232
+}
233
+
234
static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
235
{
236
- if (translator_use_goto_tb(&ctx->base, dest)) {
237
+ /*
238
+ * Under itrigger, instruction executes one by one like singlestep,
239
+ * direct block chain benefits will be small.
240
+ */
241
+ if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
242
tcg_gen_goto_tb(n);
243
gen_set_pc_imm(ctx, dest);
244
tcg_gen_exit_tb(ctx->base.tb, n);
245
} else {
246
gen_set_pc_imm(ctx, dest);
247
- tcg_gen_lookup_and_goto_ptr();
248
+ lookup_and_goto_ptr(ctx);
97
}
249
}
98
250
}
99
if (cpu->cfg.ext_zvfh) {
251
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
252
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
253
memset(ctx->ftemp, 0, sizeof(ctx->ftemp));
254
ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
255
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
256
+ ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
257
ctx->zero = tcg_constant_tl(0);
258
}
259
260
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
261
262
/* Only the first insn within a TB is allowed to cross a page boundary. */
263
if (ctx->base.is_jmp == DISAS_NEXT) {
264
- if (!is_same_page(&ctx->base, ctx->base.pc_next)) {
265
+ if (ctx->itrigger || !is_same_page(&ctx->base, ctx->base.pc_next)) {
266
ctx->base.is_jmp = DISAS_TOO_MANY;
267
} else {
268
unsigned page_ofs = ctx->base.pc_next & ~TARGET_PAGE_MASK;
269
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
270
index XXXXXXX..XXXXXXX 100644
271
--- a/target/riscv/insn_trans/trans_privileged.c.inc
272
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
273
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
274
if (has_ext(ctx, RVS)) {
275
decode_save_opc(ctx);
276
gen_helper_sret(cpu_pc, cpu_env);
277
- tcg_gen_exit_tb(NULL, 0); /* no chaining */
278
+ exit_tb(ctx); /* no chaining */
279
ctx->base.is_jmp = DISAS_NORETURN;
280
} else {
281
return false;
282
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
283
#ifndef CONFIG_USER_ONLY
284
decode_save_opc(ctx);
285
gen_helper_mret(cpu_pc, cpu_env);
286
- tcg_gen_exit_tb(NULL, 0); /* no chaining */
287
+ exit_tb(ctx); /* no chaining */
288
ctx->base.is_jmp = DISAS_NORETURN;
289
return true;
290
#else
291
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
292
index XXXXXXX..XXXXXXX 100644
293
--- a/target/riscv/insn_trans/trans_rvi.c.inc
294
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
295
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
102
}
296
}
103
297
104
- /*
298
gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
105
- * In principle Zve*x would also suffice here, were they supported
299
- tcg_gen_lookup_and_goto_ptr();
106
- * in qemu
300
+ lookup_and_goto_ptr(ctx);
107
- */
301
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
302
if (misaligned) {
109
cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
303
gen_set_label(misaligned);
110
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
304
@@ -XXX,XX +XXX,XX @@ static bool trans_pause(DisasContext *ctx, arg_pause *a)
111
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
305
* end the TB and return to main loop
112
error_setg(errp,
306
*/
113
"Vector crypto extensions require V or Zve* extensions");
307
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
114
return;
308
- tcg_gen_exit_tb(NULL, 0);
309
+ exit_tb(ctx);
310
ctx->base.is_jmp = DISAS_NORETURN;
311
312
return true;
313
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
314
* however we need to end the translation block
315
*/
316
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
317
- tcg_gen_exit_tb(NULL, 0);
318
+ exit_tb(ctx);
319
ctx->base.is_jmp = DISAS_NORETURN;
320
return true;
321
}
322
@@ -XXX,XX +XXX,XX @@ static bool do_csr_post(DisasContext *ctx)
323
decode_save_opc(ctx);
324
/* We may have changed important cpu state -- exit to main loop. */
325
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
326
- tcg_gen_exit_tb(NULL, 0);
327
+ exit_tb(ctx);
328
ctx->base.is_jmp = DISAS_NORETURN;
329
return true;
330
}
115
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
331
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
116
index XXXXXXX..XXXXXXX 100644
332
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/insn_trans/trans_rvv.c.inc
333
--- a/target/riscv/insn_trans/trans_rvv.c.inc
118
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
334
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
119
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
335
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
120
{
336
mark_vs_dirty(s);
121
TCGv s1, dst;
337
122
338
gen_set_pc_imm(s, s->pc_succ_insn);
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
339
- tcg_gen_lookup_and_goto_ptr();
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
340
+ lookup_and_goto_ptr(s);
125
return false;
341
s->base.is_jmp = DISAS_NORETURN;
126
}
342
127
343
if (rd == 0 && rs1 == 0) {
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
344
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
129
{
345
gen_set_gpr(s, rd, dst);
130
TCGv dst;
346
mark_vs_dirty(s);
131
347
gen_set_pc_imm(s, s->pc_succ_insn);
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
348
- tcg_gen_lookup_and_goto_ptr();
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
349
+ lookup_and_goto_ptr(s);
134
return false;
350
s->base.is_jmp = DISAS_NORETURN;
135
}
351
136
352
return true;
137
--
353
--
138
2.45.1
354
2.38.1
diff view generated by jsdifflib
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
In this patch, we modify the decoder to be a freely composable data
3
The max count in itrigger can be 0x3FFF, which will cause a no trivial
4
structure instead of a hardcoded one. It can be dynamically builded up
4
translation and execution overload.
5
according to the extensions.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
20
5
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
6
When icount is enabled, QEMU provides API that can fetch guest
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
7
instruction number. Thus, we can set an timer for itrigger with
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
the count as deadline.
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
10
Only when timer expires or priviledge mode changes, do lazy update
11
to count.
12
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
15
Message-Id: <20221013062946.7530-3-zhiwei_liu@linux.alibaba.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
17
---
29
target/riscv/cpu.h | 1 +
18
target/riscv/cpu.h | 2 ++
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
19
target/riscv/debug.h | 1 +
31
target/riscv/cpu.c | 1 +
20
target/riscv/cpu_helper.c | 3 ++
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
21
target/riscv/debug.c | 59 +++++++++++++++++++++++++++++++++++++++
33
target/riscv/translate.c | 31 +++++++++++++++----------------
22
4 files changed, 65 insertions(+)
34
5 files changed, 47 insertions(+), 16 deletions(-)
35
23
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
37
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu.h
26
--- a/target/riscv/cpu.h
39
+++ b/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
28
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
41
uint32_t pmu_avail_ctrs;
29
target_ulong tdata3[RV_MAX_TRIGGERS];
42
/* Mapping of events to counters */
30
struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
43
GHashTable *pmu_event_ctr_map;
31
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
44
+ const GPtrArray *decoders;
32
+ QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
45
};
33
+ int64_t last_icount;
46
34
47
/**
35
/* machine specific rdtime callback */
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
36
uint64_t (*rdtime_fn)(void *);
37
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
49
index XXXXXXX..XXXXXXX 100644
38
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/tcg/tcg-cpu.h
39
--- a/target/riscv/debug.h
51
+++ b/target/riscv/tcg/tcg-cpu.h
40
+++ b/target/riscv/debug.h
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
41
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
42
void riscv_trigger_init(CPURISCVState *env);
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
43
55
44
bool riscv_itrigger_enabled(CPURISCVState *env);
56
+struct DisasContext;
45
+void riscv_itrigger_update_priv(CPURISCVState *env);
57
+struct RISCVCPUConfig;
46
#endif /* RISCV_DEBUG_H */
58
+typedef struct RISCVDecoder {
47
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
61
+} RISCVDecoder;
62
+
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
64
+
65
+extern const size_t decoder_table_size;
66
+
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
73
index XXXXXXX..XXXXXXX 100644
48
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu.c
49
--- a/target/riscv/cpu_helper.c
75
+++ b/target/riscv/cpu.c
50
+++ b/target/riscv/cpu_helper.c
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
51
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
77
error_propagate(errp, local_err);
52
if (newpriv == PRV_H) {
78
return;
53
newpriv = PRV_U;
79
}
54
}
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
55
+ if (icount_enabled() && newpriv != env->priv) {
81
} else if (kvm_enabled()) {
56
+ riscv_itrigger_update_priv(env);
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
57
+ }
83
if (local_err != NULL) {
58
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
59
env->priv = newpriv;
60
env->xl = cpu_recompute_xl(env);
61
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
85
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
86
--- a/target/riscv/tcg/tcg-cpu.c
63
--- a/target/riscv/debug.c
87
+++ b/target/riscv/tcg/tcg-cpu.c
64
+++ b/target/riscv/debug.c
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
65
@@ -XXX,XX +XXX,XX @@
66
#include "trace.h"
67
#include "exec/exec-all.h"
68
#include "exec/helper-proto.h"
69
+#include "sysemu/cpu-timers.h"
70
71
/*
72
* The following M-mode trigger CSRs are implemented:
73
@@ -XXX,XX +XXX,XX @@ void helper_itrigger_match(CPURISCVState *env)
89
}
74
}
90
}
75
}
91
76
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
77
+static void riscv_itrigger_update_count(CPURISCVState *env)
93
+{
78
+{
94
+ GPtrArray *dynamic_decoders;
79
+ int count, executed;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
80
+ /*
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
81
+ * Record last icount, so that we can evaluate the executed instructions
97
+ if (decoder_table[i].guard_func &&
82
+ * since last priviledge mode change or timer expire.
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
83
+ */
99
+ g_ptr_array_add(dynamic_decoders,
84
+ int64_t last_icount = env->last_icount, current_icount;
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
85
+ current_icount = env->last_icount = icount_get_raw();
86
+
87
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
88
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
89
+ continue;
90
+ }
91
+ count = itrigger_get_count(env, i);
92
+ if (!count) {
93
+ continue;
94
+ }
95
+ /*
96
+ * Only when priviledge is changed or itrigger timer expires,
97
+ * the count field in itrigger tdata1 register is updated.
98
+ * And the count field in itrigger only contains remaining value.
99
+ */
100
+ if (check_itrigger_priv(env, i)) {
101
+ /*
102
+ * If itrigger enabled in this priviledge mode, the number of
103
+ * executed instructions since last priviledge change
104
+ * should be reduced from current itrigger count.
105
+ */
106
+ executed = current_icount - last_icount;
107
+ itrigger_set_count(env, i, count - executed);
108
+ if (count == executed) {
109
+ do_trigger_action(env, i);
110
+ }
111
+ } else {
112
+ /*
113
+ * If itrigger is not enabled in this priviledge mode,
114
+ * the number of executed instructions will be discard and
115
+ * the count field in itrigger will not change.
116
+ */
117
+ timer_mod(env->itrigger_timer[i],
118
+ current_icount + count);
101
+ }
119
+ }
102
+ }
120
+ }
103
+
104
+ cpu->decoders = dynamic_decoders;
105
+}
121
+}
106
+
122
+
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
123
+static void riscv_itrigger_timer_cb(void *opaque)
124
+{
125
+ riscv_itrigger_update_count((CPURISCVState *)opaque);
126
+}
127
+
128
+void riscv_itrigger_update_priv(CPURISCVState *env)
129
+{
130
+ riscv_itrigger_update_count(env);
131
+}
132
+
133
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
108
{
134
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
135
switch (tdata_index) {
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
136
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
111
index XXXXXXX..XXXXXXX 100644
137
env->tdata3[i] = 0;
112
--- a/target/riscv/translate.c
138
env->cpu_breakpoint[i] = NULL;
113
+++ b/target/riscv/translate.c
139
env->cpu_watchpoint[i] = NULL;
114
@@ -XXX,XX +XXX,XX @@
140
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
115
#include "exec/helper-info.c.inc"
141
+ riscv_itrigger_timer_cb, env);
116
#undef HELPER_H
142
}
117
118
+#include "tcg/tcg-cpu.h"
119
+
120
/* global register indices */
121
static TCGv cpu_gpr[32], cpu_gprh[32], cpu_pc, cpu_vl, cpu_vstart;
122
static TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
123
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
124
/* FRM is known to contain a valid value. */
125
bool frm_valid;
126
bool insn_start_updated;
127
+ const GPtrArray *decoders;
128
} DisasContext;
129
130
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
131
@@ -XXX,XX +XXX,XX @@ static inline int insn_len(uint16_t first_word)
132
return (first_word & 3) == 3 ? 4 : 2;
133
}
143
}
134
135
+const RISCVDecoder decoder_table[] = {
136
+ { always_true_p, decode_insn32 },
137
+ { has_xthead_p, decode_xthead},
138
+ { has_XVentanaCondOps_p, decode_XVentanaCodeOps},
139
+};
140
+
141
+const size_t decoder_table_size = ARRAY_SIZE(decoder_table);
142
+
143
static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
144
{
145
- /*
146
- * A table with predicate (i.e., guard) functions and decoder functions
147
- * that are tested in-order until a decoder matches onto the opcode.
148
- */
149
- static const struct {
150
- bool (*guard_func)(const RISCVCPUConfig *);
151
- bool (*decode_func)(DisasContext *, uint32_t);
152
- } decoders[] = {
153
- { always_true_p, decode_insn32 },
154
- { has_xthead_p, decode_xthead },
155
- { has_XVentanaCondOps_p, decode_XVentanaCodeOps },
156
- };
157
-
158
ctx->virt_inst_excp = false;
159
ctx->cur_insn_len = insn_len(opcode);
160
/* Check for compressed insn */
161
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
162
ctx->base.pc_next + 2));
163
ctx->opcode = opcode32;
164
165
- for (size_t i = 0; i < ARRAY_SIZE(decoders); ++i) {
166
- if (decoders[i].guard_func(ctx->cfg_ptr) &&
167
- decoders[i].decode_func(ctx, opcode32)) {
168
+ for (guint i = 0; i < ctx->decoders->len; ++i) {
169
+ riscv_cpu_decode_fn func = g_ptr_array_index(ctx->decoders, i);
170
+ if (func(ctx, opcode32)) {
171
return;
172
}
173
}
174
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
175
ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
176
ctx->zero = tcg_constant_tl(0);
177
ctx->virt_inst_excp = false;
178
+ ctx->decoders = cpu->decoders;
179
}
180
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
182
--
144
--
183
2.45.1
145
2.38.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
3
When QEMU is not in icount mode, execute instruction one by one. The
4
instructions will be affected by Zvfhmin extension.
4
tdata1 can be read directly.
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
6
conversions of
7
5
8
* From 1*SEW(16/32) to 2*SEW(32/64)
6
When QEMU is in icount mode, use a timer to simulate the itrigger. The
9
* From 2*SEW(32/64) to 1*SEW(16/32)
7
tdata1 may be not right because of lazy update of count in tdata1. Thus,
8
We should pack the adjusted count into tdata1 before read it back.
10
9
11
Signed-off-by: Max Chou <max.chou@sifive.com>
10
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-Id: <20221013062946.7530-4-zhiwei_liu@linux.alibaba.com>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
14
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
15
target/riscv/debug.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 18 insertions(+), 2 deletions(-)
16
1 file changed, 72 insertions(+)
19
17
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
18
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
20
--- a/target/riscv/debug.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
21
+++ b/target/riscv/debug.c
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
22
@@ -XXX,XX +XXX,XX @@ void riscv_itrigger_update_priv(CPURISCVState *env)
25
}
23
riscv_itrigger_update_count(env);
26
}
24
}
27
25
28
+static bool require_rvfmin(DisasContext *s)
26
+static target_ulong itrigger_validate(CPURISCVState *env,
27
+ target_ulong ctrl)
29
+{
28
+{
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
29
+ target_ulong val;
31
+ return false;
30
+
31
+ /* validate the generic part first */
32
+ val = tdata1_validate(env, ctrl, TRIGGER_TYPE_INST_CNT);
33
+
34
+ /* validate unimplemented (always zero) bits */
35
+ warn_always_zero_bit(ctrl, ITRIGGER_ACTION, "action");
36
+ warn_always_zero_bit(ctrl, ITRIGGER_HIT, "hit");
37
+ warn_always_zero_bit(ctrl, ITRIGGER_PENDING, "pending");
38
+
39
+ /* keep the mode and attribute bits */
40
+ val |= ctrl & (ITRIGGER_VU | ITRIGGER_VS | ITRIGGER_U | ITRIGGER_S |
41
+ ITRIGGER_M | ITRIGGER_COUNT);
42
+
43
+ return val;
44
+}
45
+
46
+static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
47
+ int tdata_index, target_ulong val)
48
+{
49
+ target_ulong new_val;
50
+
51
+ switch (tdata_index) {
52
+ case TDATA1:
53
+ /* set timer for icount */
54
+ new_val = itrigger_validate(env, val);
55
+ if (new_val != env->tdata1[index]) {
56
+ env->tdata1[index] = new_val;
57
+ if (icount_enabled()) {
58
+ env->last_icount = icount_get_raw();
59
+ /* set the count to timer */
60
+ timer_mod(env->itrigger_timer[index],
61
+ env->last_icount + itrigger_get_count(env, index));
62
+ }
63
+ }
64
+ break;
65
+ case TDATA2:
66
+ qemu_log_mask(LOG_UNIMP,
67
+ "tdata2 is not supported for icount trigger\n");
68
+ break;
69
+ case TDATA3:
70
+ qemu_log_mask(LOG_UNIMP,
71
+ "tdata3 is not supported for icount trigger\n");
72
+ break;
73
+ default:
74
+ g_assert_not_reached();
32
+ }
75
+ }
33
+
76
+
34
+ switch (s->sew) {
77
+ return;
35
+ case MO_16:
36
+ return s->cfg_ptr->ext_zvfhmin;
37
+ case MO_32:
38
+ return s->cfg_ptr->ext_zve32f;
39
+ default:
40
+ return false;
41
+ }
42
+}
78
+}
43
+
79
+
44
static bool require_scale_rvf(DisasContext *s)
80
+static int itrigger_get_adjust_count(CPURISCVState *env)
81
+{
82
+ int count = itrigger_get_count(env, env->trigger_cur), executed;
83
+ if ((count != 0) && check_itrigger_priv(env, env->trigger_cur)) {
84
+ executed = icount_get_raw() - env->last_icount;
85
+ count += executed;
86
+ }
87
+ return count;
88
+}
89
+
90
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
45
{
91
{
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
92
+ int trigger_type;
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
93
switch (tdata_index) {
48
}
94
case TDATA1:
49
95
+ trigger_type = extract_trigger_type(env, env->tdata1[env->trigger_cur]);
50
switch (s->sew) {
96
+ if ((trigger_type == TRIGGER_TYPE_INST_CNT) && icount_enabled()) {
51
- case MO_8:
97
+ return deposit64(env->tdata1[env->trigger_cur], 10, 14,
52
- return s->cfg_ptr->ext_zvfhmin;
98
+ itrigger_get_adjust_count(env));
53
case MO_16:
99
+ }
54
return s->cfg_ptr->ext_zve32f;
100
return env->tdata1[env->trigger_cur];
55
case MO_32:
101
case TDATA2:
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
102
return env->tdata2[env->trigger_cur];
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
103
@@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
58
{
104
type6_reg_write(env, env->trigger_cur, tdata_index, val);
59
return opfv_widen_check(s, a) &&
105
break;
60
+ require_rvfmin(s) &&
106
case TRIGGER_TYPE_INST_CNT:
61
require_scale_rvfmin(s) &&
107
+ itrigger_reg_write(env, env->trigger_cur, tdata_index, val);
62
(s->sew != MO_8);
108
+ break;
63
}
109
case TRIGGER_TYPE_INT:
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
110
case TRIGGER_TYPE_EXCP:
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
111
case TRIGGER_TYPE_EXT_SRC:
66
{
67
return opfv_narrow_check(s, a) &&
68
+ require_rvfmin(s) &&
69
require_scale_rvfmin(s) &&
70
(s->sew != MO_8);
71
}
72
--
112
--
73
2.45.1
113
2.38.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
2
3
We're not setting (s/m)tval when triggering breakpoints of type 2
3
Avoid calling riscv_itrigger_enabled() when calculate the tbflags.
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
4
As the itrigger enable status can only be changed when write
5
5.7.12, "Match Control Type 6":
5
tdata1, migration load or itrigger fire, update env->itrigger_enabled
6
at these places.
6
7
7
"The Privileged Spec says that breakpoint exceptions that occur on
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
instruction fetches, loads, or stores update the tval CSR with either
9
zero or the faulting virtual address. The faulting virtual address for
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
which caused that trigger to fire."
12
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
14
mcontrol.
15
16
Note that what we're doing ATM is not violating the spec, but it's
17
simple enough to set mtval/stval and it makes life easier for any
18
software that relies on this info.
19
20
Given that we always use action = 0, save the faulting address for the
21
mcontrol and mcontrol6 trigger breakpoints into env->badaddr, which is
22
used as as scratch area for traps with address information. 'tval' is
23
then set during riscv_cpu_do_interrupt().
24
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Message-Id: <20221013062946.7530-5-zhiwei_liu@linux.alibaba.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
12
---
31
target/riscv/cpu_helper.c | 1 +
13
target/riscv/cpu.h | 1 +
32
target/riscv/debug.c | 3 +++
14
target/riscv/cpu_helper.c | 3 +--
33
2 files changed, 4 insertions(+)
15
target/riscv/debug.c | 3 +++
16
target/riscv/machine.c | 15 +++++++++++++++
17
4 files changed, 20 insertions(+), 2 deletions(-)
34
18
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
24
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
25
QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
26
int64_t last_icount;
27
+ bool itrigger_enabled;
28
29
/* machine specific rdtime callback */
30
uint64_t (*rdtime_fn)(void *);
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
31
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
36
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_helper.c
33
--- a/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
34
+++ b/target/riscv/cpu_helper.c
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
35
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
40
tval = env->bins;
36
get_field(env->mstatus_hs, MSTATUS_VS));
41
break;
37
}
42
case RISCV_EXCP_BREAKPOINT:
38
if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
43
+ tval = env->badaddr;
39
- flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
44
if (cs->watchpoint_hit) {
40
- riscv_itrigger_enabled(env));
45
tval = cs->watchpoint_hit->hitaddr;
41
+ flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
46
cs->watchpoint_hit = NULL;
42
}
43
#endif
44
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
45
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
48
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/debug.c
47
--- a/target/riscv/debug.c
50
+++ b/target/riscv/debug.c
48
+++ b/target/riscv/debug.c
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
49
@@ -XXX,XX +XXX,XX @@ void helper_itrigger_match(CPURISCVState *env)
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
50
}
53
/* check U/S/M bit against current privilege level */
51
itrigger_set_count(env, i, count--);
54
if ((ctrl >> 3) & BIT(env->priv)) {
52
if (!count) {
55
+ env->badaddr = pc;
53
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
56
return true;
54
do_trigger_action(env, i);
57
}
55
}
58
}
56
}
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
57
@@ -XXX,XX +XXX,XX @@ static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
60
if (env->virt_enabled) {
58
/* set the count to timer */
61
/* check VU/VS bit against current privilege level */
59
timer_mod(env->itrigger_timer[index],
62
if ((ctrl >> 23) & BIT(env->priv)) {
60
env->last_icount + itrigger_get_count(env, index));
63
+ env->badaddr = pc;
61
+ } else {
64
return true;
62
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
65
}
63
}
66
} else {
64
}
67
/* check U/S/M bit against current privilege level */
65
break;
68
if ((ctrl >> 3) & BIT(env->priv)) {
66
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
69
+ env->badaddr = pc;
67
index XXXXXXX..XXXXXXX 100644
70
return true;
68
--- a/target/riscv/machine.c
71
}
69
+++ b/target/riscv/machine.c
72
}
70
@@ -XXX,XX +XXX,XX @@
71
#include "qemu/error-report.h"
72
#include "sysemu/kvm.h"
73
#include "migration/cpu.h"
74
+#include "sysemu/cpu-timers.h"
75
+#include "debug.h"
76
77
static bool pmp_needed(void *opaque)
78
{
79
@@ -XXX,XX +XXX,XX @@ static bool debug_needed(void *opaque)
80
return riscv_feature(env, RISCV_FEATURE_DEBUG);
81
}
82
83
+static int debug_post_load(void *opaque, int version_id)
84
+{
85
+ RISCVCPU *cpu = opaque;
86
+ CPURISCVState *env = &cpu->env;
87
+
88
+ if (icount_enabled()) {
89
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
90
+ }
91
+
92
+ return 0;
93
+}
94
+
95
static const VMStateDescription vmstate_debug = {
96
.name = "cpu/debug",
97
.version_id = 2,
98
.minimum_version_id = 2,
99
.needed = debug_needed,
100
+ .post_load = debug_post_load,
101
.fields = (VMStateField[]) {
102
VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
103
VMSTATE_UINTTL_ARRAY(env.tdata1, RISCVCPU, RV_MAX_TRIGGERS),
73
--
104
--
74
2.45.1
105
2.38.1
diff view generated by jsdifflib
1
From: Cheng Yang <yangcheng.work@foxmail.com>
1
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
2
2
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
3
Commit 40244040a7a changed the way the S irqs are numbered. This breaks when
4
to set the address of initrd in FDT to support 64-bit address.
4
using numa configuration, e.g.:
5
./qemu-system-riscv64 -nographic -machine virt,dumpdtb=numa-tree.dtb \
6
-m 2G -smp cpus=16 \
7
         -object memory-backend-ram,id=mem0,size=512M \
8
         -object memory-backend-ram,id=mem1,size=512M \
9
         -object memory-backend-ram,id=mem2,size=512M \
10
         -object memory-backend-ram,id=mem3,size=512M \
11
         -numa node,cpus=0-3,memdev=mem0,nodeid=0 \
12
         -numa node,cpus=4-7,memdev=mem1,nodeid=1 \
13
         -numa node,cpus=8-11,memdev=mem2,nodeid=2 \
14
         -numa node,cpus=12-15,memdev=mem3,nodeid=3
15
leads to:
16
Unexpected error in object_property_find_err() at ../qom/object.c:1304:
17
qemu-system-riscv64: Property 'riscv.sifive.plic.unnamed-gpio-out[8]' not
18
found
5
19
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
20
This patch makes the nubering of the S irqs identical to what it was before.
21
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
25
Message-Id: <20221114135122.1668703-1-frederic.petrot@univ-grenoble-alpes.fr>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
27
---
11
hw/riscv/boot.c | 4 ++--
28
hw/intc/sifive_plic.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
29
1 file changed, 2 insertions(+), 2 deletions(-)
13
30
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
31
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
15
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
33
--- a/hw/intc/sifive_plic.c
17
+++ b/hw/riscv/boot.c
34
+++ b/hw/intc/sifive_plic.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
35
@@ -XXX,XX +XXX,XX @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
36
CPUState *cpu = qemu_get_cpu(cpu_num);
20
if (fdt) {
37
21
end = start + size;
38
if (plic->addr_config[i].mode == PLICMode_M) {
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
39
- qdev_connect_gpio_out(dev, num_harts - plic->hartid_base + cpu_num,
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
40
+ qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts,
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
41
qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
42
}
43
if (plic->addr_config[i].mode == PLICMode_S) {
44
- qdev_connect_gpio_out(dev, cpu_num,
45
+ qdev_connect_gpio_out(dev, cpu_num - hartid_base,
46
qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
47
}
26
}
48
}
27
}
28
29
--
49
--
30
2.45.1
50
2.38.1
diff view generated by jsdifflib
1
From: Clément Léger <cleger@rivosinc.com>
1
From: Anup Patel <apatel@ventanamicro.com>
2
2
3
The current semihost exception number (16) is a reserved number (range
3
We should use "&&" instead of "&" when checking hcounteren.TM and
4
[16-17]). The upcoming double trap specification uses that number for
4
henvcfg.STCE bits.
5
the double trap exception. Since the privileged spec (Table 22) defines
6
ranges for custom uses change the semihosting exception number to 63
7
which belongs to the range [48-63] in order to avoid any future
8
collisions with reserved exception.
9
5
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
6
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
11
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
9
Message-Id: <20221108125703.1463577-2-apatel@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
11
---
16
target/riscv/cpu_bits.h | 2 +-
12
target/riscv/csr.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
14
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_bits.h
17
--- a/target/riscv/csr.c
22
+++ b/target/riscv/cpu_bits.h
18
+++ b/target/riscv/csr.c
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
19
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
20
}
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
21
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
22
if (riscv_cpu_virt_enabled(env)) {
27
- RISCV_EXCP_SEMIHOST = 0x10,
23
- if (!(get_field(env->hcounteren, COUNTEREN_TM) &
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
24
+ if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
25
get_field(env->henvcfg, HENVCFG_STCE))) {
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
26
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
27
}
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
33
} RISCVException;
34
35
#define RISCV_EXCP_INT_FLAG 0x80000000
36
--
28
--
37
2.45.1
29
2.38.1
38
39
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
The imsic DT binding[1] has changed and no longer require an ipi-id.
4
The latest IMSIC driver dynamically allocates ipi id if slow-ipi
5
is not defined.
6
7
Get rid of the unused dt property which may lead to confusion.
8
9
[1] https://lore.kernel.org/lkml/20221111044207.1478350-5-apatel@ventanamicro.com/
10
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20221122080529.1692533-1-atishp@rivosinc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
include/hw/riscv/virt.h | 1 -
17
hw/riscv/virt.c | 4 ----
18
2 files changed, 5 deletions(-)
19
20
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/virt.h
23
+++ b/include/hw/riscv/virt.h
24
@@ -XXX,XX +XXX,XX @@ enum {
25
26
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
27
28
-#define VIRT_IRQCHIP_IPI_MSI 1
29
#define VIRT_IRQCHIP_NUM_MSIS 255
30
#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
31
#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
32
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/riscv/virt.c
35
+++ b/hw/riscv/virt.c
36
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
37
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
38
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
39
VIRT_IRQCHIP_NUM_MSIS);
40
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
41
- VIRT_IRQCHIP_IPI_MSI);
42
if (riscv_socket_count(mc) > 1) {
43
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
44
imsic_num_bits(imsic_max_hart_per_socket));
45
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
46
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
47
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
48
VIRT_IRQCHIP_NUM_MSIS);
49
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
50
- VIRT_IRQCHIP_IPI_MSI);
51
if (imsic_guest_bits) {
52
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
53
imsic_guest_bits);
54
--
55
2.38.1
diff view generated by jsdifflib
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
1
From: Jim Shu <jim.shu@sifive.com>
2
2
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
3
let tlb_fill() function also increments PMU counter when it is from
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
4
two-stage translation, so QEMU could also monitor these PMU events when
5
translation part, mtval2 will be set in case of successes 2 stage translation but
5
CPU runs in VS/VU mode (like running guest OS).
6
failed pmp check.
7
6
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
9
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
10
should be zero, according to RISCV privileged spec sect. 9.4.4: When a guest
11
page-fault is taken into M-mode, mtval2 is written with either zero or guest
12
physical address that faulted, shifted by 2 bits. *For other traps, mtval2
13
is set to zero...*
14
15
Signed-off-by: Alexei Filippov <alexei.filippov@syntacore.com>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
9
Message-Id: <20221123090635.6574-1-jim.shu@sifive.com>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
11
---
22
target/riscv/cpu_helper.c | 12 ++++++------
12
target/riscv/cpu_helper.c | 2 +-
23
1 file changed, 6 insertions(+), 6 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
24
14
25
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
26
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/cpu_helper.c
17
--- a/target/riscv/cpu_helper.c
28
+++ b/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
19
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
30
__func__, pa, ret, prot_pmp, tlb_size);
20
}
31
21
}
32
prot &= prot_pmp;
22
33
- }
23
+ pmu_tlb_fill_incr_ctr(cpu, access_type);
34
-
24
if (riscv_cpu_virt_enabled(env) ||
35
- if (ret != TRANSLATE_SUCCESS) {
25
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
36
+ } else {
26
access_type != MMU_INST_FETCH)) {
37
/*
27
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
38
* Guest physical address translation failed, this is a HS
39
* level exception
40
*/
41
first_stage_error = false;
42
- env->guest_phys_fault_addr = (im_address |
43
- (address &
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
45
+ if (ret != TRANSLATE_PMP_FAIL) {
46
+ env->guest_phys_fault_addr = (im_address |
47
+ (address &
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
49
+ }
50
}
28
}
51
}
29
}
52
} else {
30
} else {
31
- pmu_tlb_fill_incr_ctr(cpu, access_type);
32
/* Single stage lookup */
33
ret = get_physical_address(env, &pa, &prot, address, NULL,
34
access_type, mmu_idx, true, false, false);
53
--
35
--
54
2.45.1
36
2.38.1
diff view generated by jsdifflib
1
From: Yangyu Chen <cyy@cyyself.name>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
This code has a typo that writes zvkb to zvkg, causing users can't
3
sstatus register dump is currently missing in riscv_cpu_dump_state().
4
enable zvkb through the config. This patch gets this fixed.
4
As sstatus is a copy of mstatus, which is described in the priv spec,
5
it seems redundant to print the same information twice.
5
6
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
7
Add some comments for this to let people know this is intentional.
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
8
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Message-Id: <20221125050354.3166023-1-bmeng@tinylab.org>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
13
---
16
target/riscv/cpu.c | 2 +-
14
target/riscv/cpu.c | 4 ++++
17
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 4 insertions(+)
18
16
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
19
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
24
/* Vector cryptography extensions */
22
CSR_MHARTID,
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
23
CSR_MSTATUS,
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
24
CSR_MSTATUSH,
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
25
+ /*
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
26
+ * CSR_SSTATUS is intentionally omitted here as its value
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
27
+ * can be figured out by looking at CSR_MSTATUS
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
28
+ */
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
29
CSR_HSTATUS,
30
CSR_VSSTATUS,
31
CSR_MIP,
32
--
32
--
33
2.45.1
33
2.38.1
34
35
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
On PolarFire SoC, some peripherals (eg the PCI root port) are clocked by
4
"Clock Conditioning Circuitry" in the FPGA. The specific clock depends
5
on the FPGA bitstream & can be locked to one particular {D,P}LL - in the
6
Icicle Kit Reference Design v2022.09 or later this is/will be the case.
7
8
Linux v6.1+ will have a driver for this peripheral and devicetrees that
9
previously relied on "fixed-frequency" clock nodes have been switched
10
over to clock-controller nodes. The IOSCB region is represented in QEMU,
11
but the specific region of it that the CCCs occupy has not so v6.1-rcN
12
kernels fail to boot in QEMU.
13
14
Add the regions as unimplemented so that the status-quo in terms of boot
15
is maintained.
16
17
Acked-by: Alistair Francis <alistair.francis@wdc.com>
18
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
19
Message-Id: <20221117225518.4102575-2-conor@kernel.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
include/hw/misc/mchp_pfsoc_ioscb.h | 1 +
23
hw/misc/mchp_pfsoc_ioscb.c | 6 ++++++
24
2 files changed, 7 insertions(+)
25
26
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
29
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
30
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
31
MemoryRegion lane23;
32
MemoryRegion ctrl;
33
MemoryRegion cfg;
34
+ MemoryRegion ccc;
35
MemoryRegion pll_mss;
36
MemoryRegion cfm_mss;
37
MemoryRegion pll_ddr;
38
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/misc/mchp_pfsoc_ioscb.c
41
+++ b/hw/misc/mchp_pfsoc_ioscb.c
42
@@ -XXX,XX +XXX,XX @@
43
*/
44
#define IOSCB_WHOLE_REG_SIZE 0x10000000
45
#define IOSCB_SUBMOD_REG_SIZE 0x1000
46
+#define IOSCB_CCC_REG_SIZE 0x2000000
47
48
/*
49
* There are many sub-modules in the IOSCB module.
50
@@ -XXX,XX +XXX,XX @@
51
#define IOSCB_LANE23_BASE 0x06510000
52
#define IOSCB_CTRL_BASE 0x07020000
53
#define IOSCB_CFG_BASE 0x07080000
54
+#define IOSCB_CCC_BASE 0x08000000
55
#define IOSCB_PLL_MSS_BASE 0x0E001000
56
#define IOSCB_CFM_MSS_BASE 0x0E002000
57
#define IOSCB_PLL_DDR_BASE 0x0E010000
58
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
59
"mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
60
memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
61
62
+ memory_region_init_io(&s->ccc, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
63
+ "mchp.pfsoc.ioscb.ccc", IOSCB_CCC_REG_SIZE);
64
+ memory_region_add_subregion(&s->container, IOSCB_CCC_BASE, &s->ccc);
65
+
66
memory_region_init_io(&s->pll_mss, OBJECT(s), &mchp_pfsoc_pll_ops, s,
67
"mchp.pfsoc.ioscb.pll_mss", IOSCB_SUBMOD_REG_SIZE);
68
memory_region_add_subregion(&s->container, IOSCB_PLL_MSS_BASE, &s->pll_mss);
69
--
70
2.38.1
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
The Fabric Interconnect Controllers provide interfaces between the FPGA
4
fabric and the core complex. There are 5 FICs on PolarFire SoC, numbered
5
0 through 4. FIC2 is an AXI4 slave interface from the FPGA fabric and
6
does not show up on the MSS memory map. FIC4 is dedicated to the User
7
Crypto Processor and does not show up on the MSS memory map either.
8
9
FIC 0, 1 & 3 do show up in the MSS memory map and neither FICs 0 or 1
10
are represented in QEMU, leading to load access violations while booting
11
Linux for Icicle if PCIe is enabled as the root port is connected via
12
either FIC 0 or 1.
13
14
Acked-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
16
Message-Id: <20221117225518.4102575-3-conor@kernel.org>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/riscv/microchip_pfsoc.h | 2 +
20
hw/riscv/microchip_pfsoc.c | 115 ++++++++++++++++-------------
21
2 files changed, 65 insertions(+), 52 deletions(-)
22
23
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/microchip_pfsoc.h
26
+++ b/include/hw/riscv/microchip_pfsoc.h
27
@@ -XXX,XX +XXX,XX @@ enum {
28
MICROCHIP_PFSOC_USB,
29
MICROCHIP_PFSOC_QSPI_XIP,
30
MICROCHIP_PFSOC_IOSCB,
31
+ MICROCHIP_PFSOC_FABRIC_FIC0,
32
+ MICROCHIP_PFSOC_FABRIC_FIC1,
33
MICROCHIP_PFSOC_FABRIC_FIC3,
34
MICROCHIP_PFSOC_DRAM_LO,
35
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
36
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/microchip_pfsoc.c
39
+++ b/hw/riscv/microchip_pfsoc.c
40
@@ -XXX,XX +XXX,XX @@
41
* describes the complete IOSCB modules memory maps
42
*/
43
static const MemMapEntry microchip_pfsoc_memmap[] = {
44
- [MICROCHIP_PFSOC_RSVD0] = { 0x0, 0x100 },
45
- [MICROCHIP_PFSOC_DEBUG] = { 0x100, 0xf00 },
46
- [MICROCHIP_PFSOC_E51_DTIM] = { 0x1000000, 0x2000 },
47
- [MICROCHIP_PFSOC_BUSERR_UNIT0] = { 0x1700000, 0x1000 },
48
- [MICROCHIP_PFSOC_BUSERR_UNIT1] = { 0x1701000, 0x1000 },
49
- [MICROCHIP_PFSOC_BUSERR_UNIT2] = { 0x1702000, 0x1000 },
50
- [MICROCHIP_PFSOC_BUSERR_UNIT3] = { 0x1703000, 0x1000 },
51
- [MICROCHIP_PFSOC_BUSERR_UNIT4] = { 0x1704000, 0x1000 },
52
- [MICROCHIP_PFSOC_CLINT] = { 0x2000000, 0x10000 },
53
- [MICROCHIP_PFSOC_L2CC] = { 0x2010000, 0x1000 },
54
- [MICROCHIP_PFSOC_DMA] = { 0x3000000, 0x100000 },
55
- [MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
56
- [MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
57
- [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
58
- [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
59
- [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
60
- [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
61
- [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
62
- [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
63
- [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
64
- [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
65
- [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
66
- [MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 },
67
- [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
68
- [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
69
- [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
70
- [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
71
- [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
72
- [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
73
- [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
74
- [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
75
- [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
76
- [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
77
- [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
78
- [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
79
- [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
80
- [MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
81
- [MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
82
- [MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
83
- [MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
84
- [MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
85
- [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
86
- [MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
87
- [MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
88
- [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
89
- [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
90
- [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
91
- [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
92
- [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
93
- [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
94
- [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
95
- [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
96
+ [MICROCHIP_PFSOC_RSVD0] = { 0x0, 0x100 },
97
+ [MICROCHIP_PFSOC_DEBUG] = { 0x100, 0xf00 },
98
+ [MICROCHIP_PFSOC_E51_DTIM] = { 0x1000000, 0x2000 },
99
+ [MICROCHIP_PFSOC_BUSERR_UNIT0] = { 0x1700000, 0x1000 },
100
+ [MICROCHIP_PFSOC_BUSERR_UNIT1] = { 0x1701000, 0x1000 },
101
+ [MICROCHIP_PFSOC_BUSERR_UNIT2] = { 0x1702000, 0x1000 },
102
+ [MICROCHIP_PFSOC_BUSERR_UNIT3] = { 0x1703000, 0x1000 },
103
+ [MICROCHIP_PFSOC_BUSERR_UNIT4] = { 0x1704000, 0x1000 },
104
+ [MICROCHIP_PFSOC_CLINT] = { 0x2000000, 0x10000 },
105
+ [MICROCHIP_PFSOC_L2CC] = { 0x2010000, 0x1000 },
106
+ [MICROCHIP_PFSOC_DMA] = { 0x3000000, 0x100000 },
107
+ [MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
108
+ [MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
109
+ [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
110
+ [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
111
+ [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
112
+ [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
113
+ [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
114
+ [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
115
+ [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
116
+ [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
117
+ [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
118
+ [MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 },
119
+ [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
120
+ [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
121
+ [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
122
+ [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
123
+ [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
124
+ [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
125
+ [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
126
+ [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
127
+ [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
128
+ [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
129
+ [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
130
+ [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
131
+ [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
132
+ [MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
133
+ [MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
134
+ [MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
135
+ [MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
136
+ [MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
137
+ [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
138
+ [MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
139
+ [MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
140
+ [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
141
+ [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
142
+ [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
143
+ [MICROCHIP_PFSOC_FABRIC_FIC0] = { 0x2000000000, 0x1000000000 },
144
+ [MICROCHIP_PFSOC_FABRIC_FIC1] = { 0x3000000000, 0x1000000000 },
145
+ [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
146
+ [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
147
+ [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
148
+ [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
149
+ [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
150
+
151
};
152
153
static void microchip_pfsoc_soc_instance_init(Object *obj)
154
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
155
create_unimplemented_device("microchip.pfsoc.fabricfic3",
156
memmap[MICROCHIP_PFSOC_FABRIC_FIC3].base,
157
memmap[MICROCHIP_PFSOC_FABRIC_FIC3].size);
158
+ /* FPGA Fabric */
159
+ create_unimplemented_device("microchip.pfsoc.fabricfic0",
160
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC0].base,
161
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC0].size);
162
+ /* FPGA Fabric */
163
+ create_unimplemented_device("microchip.pfsoc.fabricfic1",
164
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC1].base,
165
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC1].size);
166
167
/* QSPI Flash */
168
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
169
--
170
2.38.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Conor Dooley <conor.dooley@microchip.com>
2
2
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
3
The system controller on PolarFire SoC is access via a mailbox. The
4
the legacy console putchar and getchar SBI extensions.
4
control registers for this mailbox lie in the "IOSCB" region & the
5
5
interrupt is cleared via write to the "SYSREG" region. It also has a
6
The appeal of the DBCN extension is that it allows multiple bytes to be
6
QSPI controller, usually connected to a flash chip, that is used for
7
read/written in the SBI console in a single SBI call.
7
storing FPGA bitstreams and used for In-Application Programming (IAP).
8
8
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
9
Linux has an implementation of the system controller, through which the
10
module to userspace. But this will only happens if the KVM module
10
hwrng is accessed, leading to load/store access faults.
11
actually supports this SBI extension and we activate it.
11
12
12
Add the QSPI as unimplemented and a very basic (effectively
13
We'll check for DBCN support during init time, checking if get-reg-list
13
unimplemented) version of the system controller's mailbox. Rather than
14
is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
14
purely marking the regions as unimplemented, service the mailbox
15
kvm_set_one_reg() during kvm_arch_init_vcpu().
15
requests by reporting failures and raising the interrupt so a guest can
16
16
better handle the lack of support.
17
Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
17
18
SBI_EXT_DBCN, reading and writing as required.
18
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
19
19
Acked-by: Alistair Francis <alistair.francis@wdc.com>
20
A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
20
Message-Id: <20221117225518.4102575-4-conor@kernel.org>
21
host, takes around 20 seconds to boot without using DBCN. With this
22
patch we're taking around 14 seconds to boot due to the speed-up in the
23
terminal output. There's no change in boot time if the guest isn't
24
using earlycon.
25
26
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
27
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
28
Message-ID: <20240425155012.581366-1-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
22
---
31
target/riscv/sbi_ecall_interface.h | 17 +++++
23
include/hw/misc/mchp_pfsoc_ioscb.h | 3 ++
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
24
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
33
2 files changed, 128 insertions(+)
25
include/hw/riscv/microchip_pfsoc.h | 1 +
34
26
hw/misc/mchp_pfsoc_ioscb.c | 72 ++++++++++++++++++++++++++++-
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
27
hw/misc/mchp_pfsoc_sysreg.c | 18 ++++++--
36
index XXXXXXX..XXXXXXX 100644
28
hw/riscv/microchip_pfsoc.c | 6 +++
37
--- a/target/riscv/sbi_ecall_interface.h
29
6 files changed, 95 insertions(+), 6 deletions(-)
38
+++ b/target/riscv/sbi_ecall_interface.h
30
39
@@ -XXX,XX +XXX,XX @@
31
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
40
32
index XXXXXXX..XXXXXXX 100644
41
/* clang-format off */
33
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
42
34
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
43
+#define SBI_SUCCESS 0
35
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
44
+#define SBI_ERR_FAILED -1
36
MemoryRegion lane01;
45
+#define SBI_ERR_NOT_SUPPORTED -2
37
MemoryRegion lane23;
46
+#define SBI_ERR_INVALID_PARAM -3
38
MemoryRegion ctrl;
47
+#define SBI_ERR_DENIED -4
39
+ MemoryRegion qspixip;
48
+#define SBI_ERR_INVALID_ADDRESS -5
40
+ MemoryRegion mailbox;
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
41
MemoryRegion cfg;
50
+#define SBI_ERR_ALREADY_STARTED -7
42
MemoryRegion ccc;
51
+#define SBI_ERR_ALREADY_STOPPED -8
43
MemoryRegion pll_mss;
52
+#define SBI_ERR_NO_SHMEM -9
44
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
53
+
45
MemoryRegion cfm_sgmii;
54
/* SBI Extension IDs */
46
MemoryRegion bc_sgmii;
55
#define SBI_EXT_0_1_SET_TIMER 0x0
47
MemoryRegion io_calib_sgmii;
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
48
+ qemu_irq irq;
57
@@ -XXX,XX +XXX,XX @@
49
} MchpPfSoCIoscbState;
58
#define SBI_EXT_IPI 0x735049
50
59
#define SBI_EXT_RFENCE 0x52464E43
51
#define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb"
60
#define SBI_EXT_HSM 0x48534D
52
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h
61
+#define SBI_EXT_DBCN 0x4442434E
53
index XXXXXXX..XXXXXXX 100644
62
54
--- a/include/hw/misc/mchp_pfsoc_sysreg.h
63
/* SBI function IDs for BASE extension */
55
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
56
@@ -XXX,XX +XXX,XX @@
65
@@ -XXX,XX +XXX,XX @@
57
typedef struct MchpPfSoCSysregState {
66
#define SBI_EXT_HSM_HART_STOP 0x1
58
SysBusDevice parent;
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
59
MemoryRegion sysreg;
68
60
+ qemu_irq irq;
69
+/* SBI function IDs for DBCN extension */
61
} MchpPfSoCSysregState;
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
62
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
63
#define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
64
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
73
+
65
index XXXXXXX..XXXXXXX 100644
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
66
--- a/include/hw/riscv/microchip_pfsoc.h
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
67
+++ b/include/hw/riscv/microchip_pfsoc.h
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
68
@@ -XXX,XX +XXX,XX @@ enum {
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
69
MICROCHIP_PFSOC_MMUART2_IRQ = 92,
78
index XXXXXXX..XXXXXXX 100644
70
MICROCHIP_PFSOC_MMUART3_IRQ = 93,
79
--- a/target/riscv/kvm/kvm-cpu.c
71
MICROCHIP_PFSOC_MMUART4_IRQ = 94,
80
+++ b/target/riscv/kvm/kvm-cpu.c
72
+ MICROCHIP_PFSOC_MAILBOX_IRQ = 96,
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
83
};
73
};
84
74
85
+static KVMCPUConfig kvm_sbi_dbcn = {
75
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
86
+ .name = "sbi_dbcn",
76
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
77
index XXXXXXX..XXXXXXX 100644
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
78
--- a/hw/misc/mchp_pfsoc_ioscb.c
89
+};
79
+++ b/hw/misc/mchp_pfsoc_ioscb.c
90
+
80
@@ -XXX,XX +XXX,XX @@
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
81
#include "qemu/bitops.h"
92
{
82
#include "qemu/log.h"
93
CPURISCVState *env = &cpu->env;
83
#include "qapi/error.h"
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
84
+#include "hw/irq.h"
95
return 0;
85
#include "hw/sysbus.h"
96
}
86
#include "hw/misc/mchp_pfsoc_ioscb.h"
97
87
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
88
@@ -XXX,XX +XXX,XX @@
99
+ KVMScratchCPU *kvmcpu,
89
#define IOSCB_WHOLE_REG_SIZE 0x10000000
100
+ struct kvm_reg_list *reglist)
90
#define IOSCB_SUBMOD_REG_SIZE 0x1000
91
#define IOSCB_CCC_REG_SIZE 0x2000000
92
+#define IOSCB_CTRL_REG_SIZE 0x800
93
+#define IOSCB_QSPIXIP_REG_SIZE 0x200
94
+
95
96
/*
97
* There are many sub-modules in the IOSCB module.
98
@@ -XXX,XX +XXX,XX @@
99
#define IOSCB_LANE01_BASE 0x06500000
100
#define IOSCB_LANE23_BASE 0x06510000
101
#define IOSCB_CTRL_BASE 0x07020000
102
+#define IOSCB_QSPIXIP_BASE 0x07020100
103
+#define IOSCB_MAILBOX_BASE 0x07020800
104
#define IOSCB_CFG_BASE 0x07080000
105
#define IOSCB_CCC_BASE 0x08000000
106
#define IOSCB_PLL_MSS_BASE 0x0E001000
107
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps mchp_pfsoc_io_calib_ddr_ops = {
108
.endianness = DEVICE_LITTLE_ENDIAN,
109
};
110
111
+#define SERVICES_CR 0x50
112
+#define SERVICES_SR 0x54
113
+#define SERVICES_STATUS_SHIFT 16
114
+
115
+static uint64_t mchp_pfsoc_ctrl_read(void *opaque, hwaddr offset,
116
+ unsigned size)
101
+{
117
+{
102
+ struct kvm_reg_list *reg_search;
118
+ uint32_t val = 0;
103
+
119
+
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
120
+ switch (offset) {
105
+ sizeof(uint64_t), uint64_cmp);
121
+ case SERVICES_SR:
106
+
122
+ /*
107
+ if (reg_search) {
123
+ * Although some services have no error codes, most do. All services
108
+ kvm_sbi_dbcn.supported = true;
124
+ * that do implement errors, begin their error codes at 1. Treat all
125
+ * service requests as failures & return 1.
126
+ * See the "PolarFire® FPGA and PolarFire SoC FPGA System Services"
127
+ * user guide for more information on service error codes.
128
+ */
129
+ val = 1u << SERVICES_STATUS_SHIFT;
130
+ break;
131
+ default:
132
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
133
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
134
+ __func__, size, offset);
135
+ }
136
+
137
+ return val;
138
+}
139
+
140
+static void mchp_pfsoc_ctrl_write(void *opaque, hwaddr offset,
141
+ uint64_t value, unsigned size)
142
+{
143
+ MchpPfSoCIoscbState *s = opaque;
144
+
145
+ switch (offset) {
146
+ case SERVICES_CR:
147
+ qemu_irq_raise(s->irq);
148
+ break;
149
+ default:
150
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
151
+ "(size %d, value 0x%" PRIx64
152
+ ", offset 0x%" HWADDR_PRIx ")\n",
153
+ __func__, size, value, offset);
109
+ }
154
+ }
110
+}
155
+}
111
+
156
+
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
157
+static const MemoryRegionOps mchp_pfsoc_ctrl_ops = {
113
struct kvm_reg_list *reglist)
158
+ .read = mchp_pfsoc_ctrl_read,
159
+ .write = mchp_pfsoc_ctrl_write,
160
+ .endianness = DEVICE_LITTLE_ENDIAN,
161
+};
162
+
163
static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
114
{
164
{
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
165
MchpPfSoCIoscbState *s = MCHP_PFSOC_IOSCB(dev);
116
if (riscv_has_ext(&cpu->env, RVV)) {
166
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
167
"mchp.pfsoc.ioscb.lane23", IOSCB_SUBMOD_REG_SIZE);
118
}
168
memory_region_add_subregion(&s->container, IOSCB_LANE23_BASE, &s->lane23);
119
+
169
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
170
- memory_region_init_io(&s->ctrl, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
171
- "mchp.pfsoc.ioscb.ctrl", IOSCB_SUBMOD_REG_SIZE);
172
+ memory_region_init_io(&s->ctrl, OBJECT(s), &mchp_pfsoc_ctrl_ops, s,
173
+ "mchp.pfsoc.ioscb.ctrl", IOSCB_CTRL_REG_SIZE);
174
memory_region_add_subregion(&s->container, IOSCB_CTRL_BASE, &s->ctrl);
175
176
+ memory_region_init_io(&s->qspixip, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
177
+ "mchp.pfsoc.ioscb.qspixip", IOSCB_QSPIXIP_REG_SIZE);
178
+ memory_region_add_subregion(&s->container, IOSCB_QSPIXIP_BASE, &s->qspixip);
179
+
180
+ memory_region_init_io(&s->mailbox, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
181
+ "mchp.pfsoc.ioscb.mailbox", IOSCB_SUBMOD_REG_SIZE);
182
+ memory_region_add_subregion(&s->container, IOSCB_MAILBOX_BASE, &s->mailbox);
183
+
184
memory_region_init_io(&s->cfg, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
185
"mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
186
memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
187
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
188
IOSCB_SUBMOD_REG_SIZE);
189
memory_region_add_subregion(&s->container, IOSCB_IO_CALIB_SGMII_BASE,
190
&s->io_calib_sgmii);
191
+
192
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
121
}
193
}
122
194
123
static void riscv_init_kvm_registers(Object *cpu_obj)
195
static void mchp_pfsoc_ioscb_class_init(ObjectClass *klass, void *data)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
196
diff --git a/hw/misc/mchp_pfsoc_sysreg.c b/hw/misc/mchp_pfsoc_sysreg.c
125
return ret;
197
index XXXXXXX..XXXXXXX 100644
126
}
198
--- a/hw/misc/mchp_pfsoc_sysreg.c
127
199
+++ b/hw/misc/mchp_pfsoc_sysreg.c
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
200
@@ -XXX,XX +XXX,XX @@
129
+{
201
#include "qemu/bitops.h"
130
+ target_ulong reg = 1;
202
#include "qemu/log.h"
131
+
203
#include "qapi/error.h"
132
+ if (!kvm_sbi_dbcn.supported) {
204
+#include "hw/irq.h"
133
+ return 0;
205
#include "hw/sysbus.h"
134
+ }
206
#include "hw/misc/mchp_pfsoc_sysreg.h"
135
+
207
136
+ return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
208
#define ENVM_CR 0xb8
137
+}
209
+#define MESSAGE_INT 0x118c
138
+
210
139
int kvm_arch_init_vcpu(CPUState *cs)
211
static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
212
unsigned size)
213
@@ -XXX,XX +XXX,XX @@ static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
214
static void mchp_pfsoc_sysreg_write(void *opaque, hwaddr offset,
215
uint64_t value, unsigned size)
140
{
216
{
141
int ret = 0;
217
- qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
218
- "(size %d, value 0x%" PRIx64
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
219
- ", offset 0x%" HWADDR_PRIx ")\n",
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
220
- __func__, size, value, offset);
145
221
+ MchpPfSoCSysregState *s = opaque;
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
222
+ switch (offset) {
147
+
223
+ case MESSAGE_INT:
148
return ret;
224
+ qemu_irq_lower(s->irq);
149
}
150
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
152
return true;
153
}
154
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
156
+{
157
+ g_autofree uint8_t *buf = NULL;
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
159
+ target_ulong num_bytes;
160
+ uint64_t addr;
161
+ unsigned char ch;
162
+ int ret;
163
+
164
+ switch (run->riscv_sbi.function_id) {
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
167
+ num_bytes = run->riscv_sbi.args[0];
168
+
169
+ if (num_bytes == 0) {
170
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
171
+ run->riscv_sbi.ret[1] = 0;
172
+ break;
173
+ }
174
+
175
+ addr = run->riscv_sbi.args[1];
176
+
177
+ /*
178
+ * Handle the case where a 32 bit CPU is running in a
179
+ * 64 bit addressing env.
180
+ */
181
+ if (riscv_cpu_mxl(&cpu->env) == MXL_RV32) {
182
+ addr |= (uint64_t)run->riscv_sbi.args[2] << 32;
183
+ }
184
+
185
+ buf = g_malloc0(num_bytes);
186
+
187
+ if (run->riscv_sbi.function_id == SBI_EXT_DBCN_CONSOLE_READ) {
188
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, buf, num_bytes);
189
+ if (ret < 0) {
190
+ error_report("SBI_EXT_DBCN_CONSOLE_READ: error when "
191
+ "reading chardev");
192
+ exit(1);
193
+ }
194
+
195
+ cpu_physical_memory_write(addr, buf, ret);
196
+ } else {
197
+ cpu_physical_memory_read(addr, buf, num_bytes);
198
+
199
+ ret = qemu_chr_fe_write_all(serial_hd(0)->be, buf, num_bytes);
200
+ if (ret < 0) {
201
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE: error when "
202
+ "writing chardev");
203
+ exit(1);
204
+ }
205
+ }
206
+
207
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
208
+ run->riscv_sbi.ret[1] = ret;
209
+ break;
210
+ case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE:
211
+ ch = run->riscv_sbi.args[0];
212
+ ret = qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
213
+
214
+ if (ret < 0) {
215
+ error_report("SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: error when "
216
+ "writing chardev");
217
+ exit(1);
218
+ }
219
+
220
+ run->riscv_sbi.ret[0] = SBI_SUCCESS;
221
+ run->riscv_sbi.ret[1] = 0;
222
+ break;
225
+ break;
223
+ default:
226
+ default:
224
+ run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
227
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
228
+ "(size %d, value 0x%" PRIx64
229
+ ", offset 0x%" HWADDR_PRIx ")\n",
230
+ __func__, size, value, offset);
225
+ }
231
+ }
226
+}
232
}
227
+
233
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
234
static const MemoryRegionOps mchp_pfsoc_sysreg_ops = {
229
{
235
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_sysreg_realize(DeviceState *dev, Error **errp)
230
int ret = 0;
236
"mchp.pfsoc.sysreg",
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
237
MCHP_PFSOC_SYSREG_REG_SIZE);
232
}
238
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sysreg);
233
ret = 0;
239
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
234
break;
240
}
235
+ case SBI_EXT_DBCN:
241
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
242
static void mchp_pfsoc_sysreg_class_init(ObjectClass *klass, void *data)
237
+ break;
243
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
238
default:
244
index XXXXXXX..XXXXXXX 100644
239
qemu_log_mask(LOG_UNIMP,
245
--- a/hw/riscv/microchip_pfsoc.c
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
246
+++ b/hw/riscv/microchip_pfsoc.c
247
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
248
sysbus_realize(SYS_BUS_DEVICE(&s->sysreg), errp);
249
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0,
250
memmap[MICROCHIP_PFSOC_SYSREG].base);
251
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sysreg), 0,
252
+ qdev_get_gpio_in(DEVICE(s->plic),
253
+ MICROCHIP_PFSOC_MAILBOX_IRQ));
254
255
/* AXISW */
256
create_unimplemented_device("microchip.pfsoc.axisw",
257
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
258
sysbus_realize(SYS_BUS_DEVICE(&s->ioscb), errp);
259
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
260
memmap[MICROCHIP_PFSOC_IOSCB].base);
261
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ioscb), 0,
262
+ qdev_get_gpio_in(DEVICE(s->plic),
263
+ MICROCHIP_PFSOC_MAILBOX_IRQ));
264
265
/* FPGA Fabric */
266
create_unimplemented_device("microchip.pfsoc.fabricfic3",
241
--
267
--
242
2.45.1
268
2.38.1
diff view generated by jsdifflib
New patch
1
From: Jim Shu <jim.shu@sifive.com>
1
2
3
If the number of interrupt is not multiple of 32, PLIC will have
4
out-of-bound access to source_priority array. Compute the number of
5
interrupt in the last word to avoid this out-of-bound access of array.
6
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Bin Meng <bmeng@tinylab.org>
9
Message-Id: <20221127165753.30533-1-jim.shu@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/intc/sifive_plic.c | 12 +++++++++++-
13
1 file changed, 11 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/sifive_plic.c
18
+++ b/hw/intc/sifive_plic.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
20
uint32_t max_irq = 0;
21
uint32_t max_prio = plic->target_priority[addrid];
22
int i, j;
23
+ int num_irq_in_word = 32;
24
25
for (i = 0; i < plic->bitfield_words; i++) {
26
uint32_t pending_enabled_not_claimed =
27
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
28
continue;
29
}
30
31
- for (j = 0; j < 32; j++) {
32
+ if (i == (plic->bitfield_words - 1)) {
33
+ /*
34
+ * If plic->num_sources is not multiple of 32, num-of-irq in last
35
+ * word is not 32. Compute the num-of-irq of last word to avoid
36
+ * out-of-bound access of source_priority array.
37
+ */
38
+ num_irq_in_word = plic->num_sources - ((plic->bitfield_words - 1) << 5);
39
+ }
40
+
41
+ for (j = 0; j < num_irq_in_word; j++) {
42
int irq = (i << 5) + j;
43
uint32_t prio = plic->source_priority[irq];
44
int enabled = pending_enabled_not_claimed & (1 << j);
45
--
46
2.38.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
3
The priv spec v1.12 says:
4
in bytes, when in this context we want 'reg_width' as the length in
5
bits.
6
4
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
5
If no PMP entry matches an M-mode access, the access succeeds. If
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
6
no PMP entry matches an S-mode or U-mode access, but at least one
9
beforehand.
7
PMP entry is implemented, the access fails. Failed accesses generate
8
an instruction, load, or store access-fault exception.
10
9
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
10
At present the exception cause is set to 'illegal instruction' but
12
clarity about what the variable represents. 'bitsize' is also used in
11
should have been 'instruction access fault'.
13
riscv_gen_dynamic_csr_feature() with the same purpose, i.e. as an input to
14
gdb_feature_builder_append_reg().
15
12
16
Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
13
Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is configured")
17
Cc: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
18
Reported-by: Robin Dapp <rdapp.gcc@gmail.com>
15
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
19
Fixes: 33a24910ae ("target/riscv: Use GDBFeature for dynamic XML")
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Acked-by: Alex Bennée <alex.bennee@linaro.org>
23
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
17
Message-Id: <20221205065303.204095-1-bmeng@tinylab.org>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
19
---
29
target/riscv/gdbstub.c | 6 +++---
20
target/riscv/op_helper.c | 2 +-
30
1 file changed, 3 insertions(+), 3 deletions(-)
21
1 file changed, 1 insertion(+), 1 deletion(-)
31
22
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
23
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
33
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/gdbstub.c
25
--- a/target/riscv/op_helper.c
35
+++ b/target/riscv/gdbstub.c
26
+++ b/target/riscv/op_helper.c
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
27
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
28
38
{
29
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
39
RISCVCPU *cpu = RISCV_CPU(cs);
30
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
40
- int reg_width = cpu->cfg.vlenb;
31
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
41
+ int bitsize = cpu->cfg.vlenb << 3;
32
+ riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
42
GDBFeatureBuilder builder;
43
int i;
44
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
46
47
/* First define types and totals in a whole VL */
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
49
- int count = reg_width / vec_lanes[i].size;
50
+ int count = bitsize / vec_lanes[i].size;
51
gdb_feature_builder_append_tag(
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
55
/* Define vector registers */
56
for (i = 0; i < 32; i++) {
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
58
- reg_width, i, "riscv_vector", "vector");
59
+ bitsize, i, "riscv_vector", "vector");
60
}
33
}
61
34
62
gdb_feature_builder_end(&builder);
35
target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
63
--
36
--
64
2.45.1
37
2.38.1
65
66
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Failure to set pc_succ_insn may result in a TB covering zero bytes,
4
which triggers an assert within the code generator.
5
6
Cc: qemu-stable@nongnu.org
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1224
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-Id: <20221203175744.151365-1-richard.henderson@linaro.org>
12
[ Changes by AF:
13
- Add missing run-plugin-test-noc-% line
14
]
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/translate.c | 12 ++++--------
18
tests/tcg/Makefile.target | 2 ++
19
tests/tcg/riscv64/Makefile.target | 6 ++++++
20
tests/tcg/riscv64/test-noc.S | 32 +++++++++++++++++++++++++++++++
21
4 files changed, 44 insertions(+), 8 deletions(-)
22
create mode 100644 tests/tcg/riscv64/test-noc.S
23
24
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/translate.c
27
+++ b/target/riscv/translate.c
28
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
29
ctx->virt_inst_excp = false;
30
/* Check for compressed insn */
31
if (insn_len(opcode) == 2) {
32
- if (!has_ext(ctx, RVC)) {
33
- gen_exception_illegal(ctx);
34
- } else {
35
- ctx->opcode = opcode;
36
- ctx->pc_succ_insn = ctx->base.pc_next + 2;
37
- if (decode_insn16(ctx, opcode)) {
38
- return;
39
- }
40
+ ctx->opcode = opcode;
41
+ ctx->pc_succ_insn = ctx->base.pc_next + 2;
42
+ if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
43
+ return;
44
}
45
} else {
46
uint32_t opcode32 = opcode;
47
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
48
index XXXXXXX..XXXXXXX 100644
49
--- a/tests/tcg/Makefile.target
50
+++ b/tests/tcg/Makefile.target
51
@@ -XXX,XX +XXX,XX @@ endif
52
53
%: %.c
54
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
55
+%: %.S
56
+    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
57
else
58
# For softmmu targets we include a different Makefile fragement as the
59
# build options for bare programs are usually pretty different. They
60
diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
61
index XXXXXXX..XXXXXXX 100644
62
--- a/tests/tcg/riscv64/Makefile.target
63
+++ b/tests/tcg/riscv64/Makefile.target
64
@@ -XXX,XX +XXX,XX @@
65
VPATH += $(SRC_PATH)/tests/tcg/riscv64
66
TESTS += test-div
67
TESTS += noexec
68
+
69
+# Disable compressed instructions for test-noc
70
+TESTS += test-noc
71
+test-noc: LDFLAGS = -nostdlib -static
72
+run-test-noc: QEMU_OPTS += -cpu rv64,c=false
73
+run-plugin-test-noc-%: QEMU_OPTS += -cpu rv64,c=false
74
diff --git a/tests/tcg/riscv64/test-noc.S b/tests/tcg/riscv64/test-noc.S
75
new file mode 100644
76
index XXXXXXX..XXXXXXX
77
--- /dev/null
78
+++ b/tests/tcg/riscv64/test-noc.S
79
@@ -XXX,XX +XXX,XX @@
80
+#include <asm/unistd.h>
81
+
82
+    .text
83
+    .globl _start
84
+_start:
85
+    .option    norvc
86
+    li    a0, 4        /* SIGILL */
87
+    la    a1, sa
88
+    li    a2, 0
89
+    li    a3, 8
90
+    li    a7, __NR_rt_sigaction
91
+    scall
92
+
93
+    .option    rvc
94
+    li    a0, 1
95
+    j    exit
96
+    .option    norvc
97
+
98
+pass:
99
+    li    a0, 0
100
+exit:
101
+    li    a7, __NR_exit
102
+    scall
103
+
104
+    .data
105
+    /* struct kernel_sigaction sa = { .sa_handler = pass }; */
106
+    .type    sa, @object
107
+    .size    sa, 32
108
+sa:
109
+    .dword    pass
110
+    .zero    24
111
+
112
--
113
2.38.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
3
There are 2 paths in helper_sret() and the same mstatus update codes
4
enabling Zve64x enables Zve32x according to their dependency.
4
are replicated. Extract the common parts to simplify it a little bit.
5
5
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Message-Id: <20221207090037.281452-1-bmeng@tinylab.org>
9
Reviewed-by: Max Chou <max.chou@sifive.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20240328022343.6871-3-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
10
---
14
target/riscv/cpu_cfg.h | 1 +
11
target/riscv/op_helper.c | 20 ++++++--------------
15
target/riscv/cpu.c | 2 ++
12
1 file changed, 6 insertions(+), 14 deletions(-)
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
17
3 files changed, 14 insertions(+), 6 deletions(-)
18
13
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
20
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_cfg.h
16
--- a/target/riscv/op_helper.c
22
+++ b/target/riscv/cpu_cfg.h
17
+++ b/target/riscv/op_helper.c
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
24
bool ext_zve32x;
25
bool ext_zve64f;
26
bool ext_zve64d;
27
+ bool ext_zve64x;
28
bool ext_zvbb;
29
bool ext_zvbc;
30
bool ext_zvkb;
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/tcg/tcg-cpu.c
54
+++ b/target/riscv/tcg/tcg-cpu.c
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
56
57
/* The Zve64d extension depends on the Zve64f extension */
58
if (cpu->cfg.ext_zve64d) {
59
+ if (!riscv_has_ext(env, RVD)) {
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
61
+ return;
62
+ }
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
64
}
19
}
65
20
66
- /* The Zve64f extension depends on the Zve32f extension */
21
mstatus = env->mstatus;
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
22
+ prev_priv = get_field(mstatus, MSTATUS_SPP);
68
if (cpu->cfg.ext_zve64f) {
23
+ mstatus = set_field(mstatus, MSTATUS_SIE,
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
24
+ get_field(mstatus, MSTATUS_SPIE));
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
25
+ mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
26
+ mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
27
+ env->mstatus = mstatus;
28
29
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
30
/* We support Hypervisor extensions and virtulisation is disabled */
31
target_ulong hstatus = env->hstatus;
32
33
- prev_priv = get_field(mstatus, MSTATUS_SPP);
34
prev_virt = get_field(hstatus, HSTATUS_SPV);
35
36
hstatus = set_field(hstatus, HSTATUS_SPV, 0);
37
- mstatus = set_field(mstatus, MSTATUS_SPP, 0);
38
- mstatus = set_field(mstatus, SSTATUS_SIE,
39
- get_field(mstatus, SSTATUS_SPIE));
40
- mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
41
42
- env->mstatus = mstatus;
43
env->hstatus = hstatus;
44
45
if (prev_virt) {
46
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
47
}
48
49
riscv_cpu_set_virt_enabled(env, prev_virt);
50
- } else {
51
- prev_priv = get_field(mstatus, MSTATUS_SPP);
52
-
53
- mstatus = set_field(mstatus, MSTATUS_SIE,
54
- get_field(mstatus, MSTATUS_SPIE));
55
- mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
56
- mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
57
- env->mstatus = mstatus;
71
}
58
}
72
59
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
60
riscv_cpu_set_mode(env, prev_priv);
74
- error_setg(errp, "Zve64d/V extensions require D extension");
75
- return;
76
+ /* The Zve64x extension depends on the Zve32x extension */
77
+ if (cpu->cfg.ext_zve64x) {
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
79
}
80
81
/* The Zve32f extension depends on the Zve32x extension */
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
83
return;
84
}
85
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
88
error_setg(
89
errp,
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
92
return;
93
}
94
95
--
61
--
96
2.45.1
62
2.38.1
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Implementing wrs.nto to always just return is consistent with the
3
Since priv spec v1.12, MRET and SRET now clear mstatus.MPRV when
4
specification, as the instruction is permitted to terminate the
4
leaving M-mode.
5
stall for any reason, but it's not useful for virtualization, where
6
we'd like the guest to trap to the hypervisor in order to allow
7
scheduling of the lock holding VCPU. Change to always immediately
8
raise exceptions when the appropriate conditions are present,
9
otherwise continue to just return. Note, immediately raising
10
exceptions is also consistent with the specification since the
11
time limit that should expire prior to the exception is
12
implementation-specific.
13
5
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
15
Reviewed-by: Christoph Müllner <christoph.muellner@vrull.eu>
16
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
8
Message-Id: <20221207090037.281452-2-bmeng@tinylab.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
10
---
21
target/riscv/helper.h | 1 +
11
target/riscv/op_helper.c | 6 ++++++
22
target/riscv/op_helper.c | 11 ++++++++
12
1 file changed, 6 insertions(+)
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
24
3 files changed, 32 insertions(+), 9 deletions(-)
25
13
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/helper.h
29
+++ b/target/riscv/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
31
DEF_HELPER_1(sret, tl, env)
32
DEF_HELPER_1(mret, tl, env)
33
DEF_HELPER_1(wfi, void, env)
34
+DEF_HELPER_1(wrs_nto, void, env)
35
DEF_HELPER_1(tlb_flush, void, env)
36
DEF_HELPER_1(tlb_flush_all, void, env)
37
/* Native Debug */
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
39
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/op_helper.c
16
--- a/target/riscv/op_helper.c
41
+++ b/target/riscv/op_helper.c
17
+++ b/target/riscv/op_helper.c
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
43
}
19
get_field(mstatus, MSTATUS_SPIE));
44
}
20
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
45
21
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
46
+void helper_wrs_nto(CPURISCVState *env)
22
+ if (env->priv_ver >= PRIV_VERSION_1_12_0) {
47
+{
23
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
54
+ }
24
+ }
55
+}
25
env->mstatus = mstatus;
56
+
26
57
void helper_tlb_flush(CPURISCVState *env)
27
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
58
{
28
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
59
CPUState *cs = env_cpu(env);
29
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
30
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
61
index XXXXXXX..XXXXXXX 100644
31
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
32
+ if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
33
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
64
@@ -XXX,XX +XXX,XX @@
65
* this program. If not, see <http://www.gnu.org/licenses/>.
66
*/
67
68
-static bool trans_wrs(DisasContext *ctx)
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
70
{
71
if (!ctx->cfg_ptr->ext_zawrs) {
72
return false;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
74
return true;
75
}
76
77
-#define GEN_TRANS_WRS(insn) \
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
79
-{ \
80
- (void)a; \
81
- return trans_wrs(ctx); \
82
-}
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
84
+{
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
86
+ return false;
87
+ }
34
+ }
88
35
env->mstatus = mstatus;
89
-GEN_TRANS_WRS(wrs_nto)
36
riscv_cpu_set_mode(env, prev_priv);
90
-GEN_TRANS_WRS(wrs_sto)
37
91
+ /*
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
93
+ * should raise an exception when the implementation-specific bounded time
94
+ * limit has expired. Our time limit is zero, so we either return
95
+ * immediately, as does our implementation of wrs.sto, or raise an
96
+ * exception, as handled by the wrs.nto helper.
97
+ */
98
+#ifndef CONFIG_USER_ONLY
99
+ gen_helper_wrs_nto(tcg_env);
100
+#endif
101
+
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
103
+ return trans_wrs_sto(ctx, NULL);
104
+}
105
--
38
--
106
2.45.1
39
2.38.1
107
108
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
From: Christoph Muellner <christoph.muellner@vrull.eu>
2
2
3
The th.sxstatus CSR can be used to identify available custom extension
3
This patch adds support for the Zawrs ISA extension.
4
on T-Head CPUs. The CSR is documented here:
4
Given the current (incomplete) implementation of reservation sets
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
5
there seems to be no way to provide a full emulation of the WRS
6
instruction (wake on reservation set invalidation or timeout or
7
interrupt). Therefore, we just exit the TB and return to the main loop.
6
8
7
An important property of this patch is, that the th.sxstatus MAEE field
9
The specification can be found here:
8
is not set (indicating that XTheadMae is not available).
10
https://github.com/riscv/riscv-zawrs/blob/main/zawrs.adoc
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
11
in PTEs that are marked as reserved. QEMU maintainers prefer to not
12
implement XTheadMae, so we need give kernels a mechanism to identify
13
if XTheadMae is available in a system or not. And this patch introduces
14
this mechanism in QEMU in a way that's compatible with real HW
15
(i.e., probing the th.sxstatus.MAEE bit).
16
11
17
Further context can be found on the list:
12
Note, that the Zawrs extension is frozen, but not ratified yet.
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
19
13
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
14
Changes since v3:
15
* Remove "RFC" since the extension is frozen
16
* Rebase on master and fix integration issues
17
* Fix entry ordering in extension list
18
19
Changes since v2:
20
* Rebase on master and resolve conflicts
21
* Adjustments according to a specification change
22
* Inline REQUIRE_ZAWRS() since it has only one user
23
24
Changes since v1:
25
* Adding zawrs to the ISA string that is passed to the kernel
26
27
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
28
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
29
Message-Id: <20221005144948.3421504-1-christoph.muellner@vrull.eu>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
31
---
26
MAINTAINERS | 1 +
32
target/riscv/cpu.h | 1 +
27
target/riscv/cpu.h | 3 ++
33
target/riscv/insn32.decode | 4 ++
28
target/riscv/cpu.c | 1 +
34
target/riscv/cpu.c | 7 +++
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
35
target/riscv/translate.c | 1 +
30
target/riscv/meson.build | 1 +
36
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 +++++++++++++++++++++
31
5 files changed, 85 insertions(+)
37
5 files changed, 64 insertions(+)
32
create mode 100644 target/riscv/th_csr.c
38
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
33
39
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
37
+++ b/MAINTAINERS
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
39
S: Supported
40
F: target/riscv/insn_trans/trans_xthead.c.inc
41
F: target/riscv/xthead*.decode
42
+F: target/riscv/th_*
43
F: disas/riscv-xthead*
44
45
RISC-V XVentanaCondOps extension
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
40
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
47
index XXXXXXX..XXXXXXX 100644
41
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
42
--- a/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
43
+++ b/target/riscv/cpu.h
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
44
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
51
uint8_t satp_mode_max_from_map(uint32_t map);
45
bool ext_svnapot;
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
46
bool ext_svpbmt;
53
47
bool ext_zdinx;
54
+/* Implemented in th_csr.c */
48
+ bool ext_zawrs;
55
+void th_register_custom_csrs(RISCVCPU *cpu);
49
bool ext_zfh;
50
bool ext_zfhmin;
51
bool ext_zfinx;
52
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/insn32.decode
55
+++ b/target/riscv/insn32.decode
56
@@ -XXX,XX +XXX,XX @@ vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm11
57
vsetivli 11 .......... ..... 111 ..... 1010111 @r2_zimm10
58
vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
59
60
+# *** Zawrs Standard Extension ***
61
+wrs_nto 000000001101 00000 000 00000 1110011
62
+wrs_sto 000000011101 00000 000 00000 1110011
56
+
63
+
57
#endif /* RISCV_CPU_H */
64
# *** RV32 Zba Standard Extension ***
65
sh1add 0010000 .......... 010 ..... 0110011 @r
66
sh2add 0010000 .......... 100 ..... 0110011 @r
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
59
index XXXXXXX..XXXXXXX 100644
68
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu.c
69
--- a/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
70
+++ b/target/riscv/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
72
ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
64
#ifndef CONFIG_USER_ONLY
73
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
74
ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause),
66
+ th_register_custom_csrs(cpu);
75
+ ISA_EXT_DATA_ENTRY(zawrs, true, PRIV_VERSION_1_12_0, ext_zawrs),
67
#endif
76
ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
68
77
ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
69
/* inherited from parent obj via riscv_cpu_init() */
78
ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
79
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
80
return;
81
}
82
83
+ if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
84
+ error_setg(errp, "Zawrs extension requires A extension");
85
+ return;
86
+ }
87
+
88
if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
89
error_setg(errp, "Zfh/Zfhmin extensions require F extension");
90
return;
91
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
92
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
93
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
94
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
95
+ DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
96
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
97
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
98
DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
99
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/riscv/translate.c
102
+++ b/target/riscv/translate.c
103
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
104
#include "insn_trans/trans_rvh.c.inc"
105
#include "insn_trans/trans_rvv.c.inc"
106
#include "insn_trans/trans_rvb.c.inc"
107
+#include "insn_trans/trans_rvzawrs.c.inc"
108
#include "insn_trans/trans_rvzfh.c.inc"
109
#include "insn_trans/trans_rvk.c.inc"
110
#include "insn_trans/trans_privileged.c.inc"
111
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
71
new file mode 100644
112
new file mode 100644
72
index XXXXXXX..XXXXXXX
113
index XXXXXXX..XXXXXXX
73
--- /dev/null
114
--- /dev/null
74
+++ b/target/riscv/th_csr.c
115
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
75
@@ -XXX,XX +XXX,XX @@
116
@@ -XXX,XX +XXX,XX @@
76
+/*
117
+/*
77
+ * T-Head-specific CSRs.
118
+ * RISC-V translation routines for the RISC-V Zawrs Extension.
78
+ *
119
+ *
79
+ * Copyright (c) 2024 VRULL GmbH
120
+ * Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.io
80
+ *
121
+ *
81
+ * This program is free software; you can redistribute it and/or modify it
122
+ * This program is free software; you can redistribute it and/or modify it
82
+ * under the terms and conditions of the GNU General Public License,
123
+ * under the terms and conditions of the GNU General Public License,
83
+ * version 2 or later, as published by the Free Software Foundation.
124
+ * version 2 or later, as published by the Free Software Foundation.
84
+ *
125
+ *
...
...
89
+ *
130
+ *
90
+ * You should have received a copy of the GNU General Public License along with
131
+ * You should have received a copy of the GNU General Public License along with
91
+ * this program. If not, see <http://www.gnu.org/licenses/>.
132
+ * this program. If not, see <http://www.gnu.org/licenses/>.
92
+ */
133
+ */
93
+
134
+
94
+#include "qemu/osdep.h"
135
+static bool trans_wrs(DisasContext *ctx)
95
+#include "cpu.h"
96
+#include "cpu_vendorid.h"
97
+
98
+#define CSR_TH_SXSTATUS 0x5c0
99
+
100
+/* TH_SXSTATUS bits */
101
+#define TH_SXSTATUS_UCME BIT(16)
102
+#define TH_SXSTATUS_MAEE BIT(21)
103
+#define TH_SXSTATUS_THEADISAEE BIT(22)
104
+
105
+typedef struct {
106
+ int csrno;
107
+ int (*insertion_test)(RISCVCPU *cpu);
108
+ riscv_csr_operations csr_ops;
109
+} riscv_csr;
110
+
111
+static RISCVException smode(CPURISCVState *env, int csrno)
112
+{
136
+{
113
+ if (riscv_has_ext(env, RVS)) {
137
+ if (!ctx->cfg_ptr->ext_zawrs) {
114
+ return RISCV_EXCP_NONE;
138
+ return false;
115
+ }
139
+ }
116
+
140
+
117
+ return RISCV_EXCP_ILLEGAL_INST;
141
+ /*
142
+ * The specification says:
143
+ * While stalled, an implementation is permitted to occasionally
144
+ * terminate the stall and complete execution for any reason.
145
+ *
146
+ * So let's just exit TB and return to the main loop.
147
+ */
148
+
149
+ /* Clear the load reservation (if any). */
150
+ tcg_gen_movi_tl(load_res, -1);
151
+
152
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
153
+ tcg_gen_exit_tb(NULL, 0);
154
+ ctx->base.is_jmp = DISAS_NORETURN;
155
+
156
+ return true;
118
+}
157
+}
119
+
158
+
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
159
+#define GEN_TRANS_WRS(insn) \
121
+{
160
+static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
161
+{ \
123
+ return -1;
162
+ (void)a; \
124
+ }
163
+ return trans_wrs(ctx); \
125
+
126
+ return 0;
127
+}
164
+}
128
+
165
+
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
166
+GEN_TRANS_WRS(wrs_nto)
130
+ target_ulong *val)
167
+GEN_TRANS_WRS(wrs_sto)
131
+{
132
+ /* We don't set MAEE here, because QEMU does not implement MAEE. */
133
+ *val = TH_SXSTATUS_UCME | TH_SXSTATUS_THEADISAEE;
134
+ return RISCV_EXCP_NONE;
135
+}
136
+
137
+static riscv_csr th_csr_list[] = {
138
+ {
139
+ .csrno = CSR_TH_SXSTATUS,
140
+ .insertion_test = test_thead_mvendorid,
141
+ .csr_ops = { "th.sxstatus", smode, read_th_sxstatus }
142
+ }
143
+};
144
+
145
+void th_register_custom_csrs(RISCVCPU *cpu)
146
+{
147
+ for (size_t i = 0; i < ARRAY_SIZE(th_csr_list); i++) {
148
+ int csrno = th_csr_list[i].csrno;
149
+ riscv_csr_operations *csr_ops = &th_csr_list[i].csr_ops;
150
+ if (!th_csr_list[i].insertion_test(cpu)) {
151
+ riscv_set_csr_ops(csrno, csr_ops);
152
+ }
153
+ }
154
+}
155
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/riscv/meson.build
158
+++ b/target/riscv/meson.build
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
160
'monitor.c',
161
'machine.c',
162
'pmu.c',
163
+ 'th_csr.c',
164
'time_helper.c',
165
'riscv-qmp-cmds.c',
166
))
167
--
168
--
168
2.45.1
169
2.38.1
169
170
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
4
controllers regardless of how MSI is implemented. msi_nonbroken is
5
initialized to true in sifive_plic_realize().
6
7
Let SIFIVE_PLIC select MSI_NONBROKEN and drop the selection from
8
RISC-V machines.
9
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
14
Message-Id: <20221211030829.802437-1-bmeng@tinylab.org>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
hw/intc/Kconfig | 1 +
18
hw/riscv/Kconfig | 5 -----
19
2 files changed, 1 insertion(+), 5 deletions(-)
20
21
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/intc/Kconfig
24
+++ b/hw/intc/Kconfig
25
@@ -XXX,XX +XXX,XX @@ config RISCV_IMSIC
26
27
config SIFIVE_PLIC
28
bool
29
+ select MSI_NONBROKEN
30
31
config GOLDFISH_PIC
32
bool
33
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/riscv/Kconfig
36
+++ b/hw/riscv/Kconfig
37
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
38
select MCHP_PFSOC_IOSCB
39
select MCHP_PFSOC_MMUART
40
select MCHP_PFSOC_SYSREG
41
- select MSI_NONBROKEN
42
select RISCV_ACLINT
43
select SIFIVE_PDMA
44
select SIFIVE_PLIC
45
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
46
imply TPM_TIS_SYSBUS
47
select RISCV_NUMA
48
select GOLDFISH_RTC
49
- select MSI_NONBROKEN
50
select PCI
51
select PCI_EXPRESS_GENERIC_BRIDGE
52
select PFLASH_CFI01
53
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
54
55
config SIFIVE_E
56
bool
57
- select MSI_NONBROKEN
58
select RISCV_ACLINT
59
select SIFIVE_GPIO
60
select SIFIVE_PLIC
61
@@ -XXX,XX +XXX,XX @@ config SIFIVE_E
62
config SIFIVE_U
63
bool
64
select CADENCE
65
- select MSI_NONBROKEN
66
select RISCV_ACLINT
67
select SIFIVE_GPIO
68
select SIFIVE_PDMA
69
@@ -XXX,XX +XXX,XX @@ config SPIKE
70
bool
71
select RISCV_NUMA
72
select HTIF
73
- select MSI_NONBROKEN
74
select RISCV_ACLINT
75
select SIFIVE_PLIC
76
--
77
2.38.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Privileged spec section 4.1.9 mentions:
3
hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
4
controllers regardless of how MSI is implemented. msi_nonbroken is
5
initialized to true in both riscv_aplic_realize() and
6
riscv_imsic_realize().
4
7
5
"When a trap is taken into S-mode, stval is written with
8
Select MSI_NONBROKEN in RISCV_APLIC and RISCV_IMSIC.
6
exception-specific information to assist software in handling the trap.
7
(...)
8
9
9
If stval is written with a nonzero value when a breakpoint,
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
address-misaligned, access-fault, or page-fault exception occurs on an
11
instruction fetch, load, or store, then stval will contain the faulting
12
virtual address."
13
14
A similar text is found for mtval in section 3.1.16.
15
16
Setting mtval/stval in this scenario is optional, but some softwares read
17
these regs when handling ebreaks.
18
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
20
'tval' during riscv_do_cpu_interrrupt().
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-Id: <20221211030829.802437-2-bmeng@tinylab.org>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
15
---
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
16
hw/intc/Kconfig | 2 ++
30
1 file changed, 2 insertions(+)
17
1 file changed, 2 insertions(+)
31
18
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
19
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
33
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
21
--- a/hw/intc/Kconfig
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
22
+++ b/hw/intc/Kconfig
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
23
@@ -XXX,XX +XXX,XX @@ config RISCV_ACLINT
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
24
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
25
config RISCV_APLIC
39
} else {
26
bool
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
27
+ select MSI_NONBROKEN
41
+ offsetof(CPURISCVState, badaddr));
28
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
29
config RISCV_IMSIC
43
}
30
bool
44
return true;
31
+ select MSI_NONBROKEN
32
33
config SIFIVE_PLIC
34
bool
45
--
35
--
46
2.45.1
36
2.38.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
The opfv_narrow_check needs to check the single width float operator by
3
Since commit ef6310064820 ("hw/riscv: opentitan: Update to the latest build")
4
require_rvf.
4
the IBEX PLIC model was replaced with the SiFive PLIC model in the
5
'opentitan' machine but we forgot the add the dependency there.
5
6
6
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
8
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
10
Message-Id: <20221211030829.802437-3-bmeng@tinylab.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
13
hw/riscv/Kconfig | 1 +
13
1 file changed, 1 insertion(+)
14
1 file changed, 1 insertion(+)
14
15
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
--- a/hw/riscv/Kconfig
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/hw/riscv/Kconfig
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
20
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
21
config OPENTITAN
21
{
22
bool
22
return opfv_narrow_check(s, a) &&
23
select IBEX
23
+ require_rvf(s) &&
24
+ select SIFIVE_PLIC
24
require_scale_rvf(s) &&
25
select UNIMP
25
(s->sew != MO_8);
26
26
}
27
config SHAKTI_C
27
--
28
--
28
2.45.1
29
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
SHAKTI_C machine Kconfig option was inserted in disorder. Fix it.
4
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Message-Id: <20221211030829.802437-4-bmeng@tinylab.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/riscv/Kconfig | 16 +++++++++-------
13
1 file changed, 9 insertions(+), 7 deletions(-)
14
15
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/Kconfig
18
+++ b/hw/riscv/Kconfig
19
@@ -XXX,XX +XXX,XX @@ config RISCV_NUMA
20
config IBEX
21
bool
22
23
+# RISC-V machines in alphabetical order
24
+
25
config MICROCHIP_PFSOC
26
bool
27
select CADENCE_SDHCI
28
@@ -XXX,XX +XXX,XX @@ config OPENTITAN
29
select SIFIVE_PLIC
30
select UNIMP
31
32
-config SHAKTI_C
33
- bool
34
- select UNIMP
35
- select SHAKTI_UART
36
- select RISCV_ACLINT
37
- select SIFIVE_PLIC
38
-
39
config RISCV_VIRT
40
bool
41
imply PCI_DEVICES
42
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
43
select FW_CFG_DMA
44
select PLATFORM_BUS
45
46
+config SHAKTI_C
47
+ bool
48
+ select RISCV_ACLINT
49
+ select SHAKTI_UART
50
+ select SIFIVE_PLIC
51
+ select UNIMP
52
+
53
config SIFIVE_E
54
bool
55
select RISCV_ACLINT
56
--
57
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
PLIC is not included in the 'spike' machine.
4
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221211030829.802437-5-bmeng@tinylab.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
hw/riscv/spike.c | 1 -
12
1 file changed, 1 deletion(-)
13
14
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/spike.c
17
+++ b/hw/riscv/spike.c
18
@@ -XXX,XX +XXX,XX @@
19
*
20
* 0) HTIF Console and Poweroff
21
* 1) CLINT (Timer and IPI)
22
- * 2) PLIC (Platform Level Interrupt Controller)
23
*
24
* This program is free software; you can redistribute it and/or modify it
25
* under the terms and conditions of the GNU General Public License,
26
--
27
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
H-mode has been removed since priv spec 1.10. Drop it.
4
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221211030829.802437-6-bmeng@tinylab.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/hw/intc/sifive_plic.h | 1 -
12
hw/intc/sifive_plic.c | 1 -
13
2 files changed, 2 deletions(-)
14
15
diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/sifive_plic.h
18
+++ b/include/hw/intc/sifive_plic.h
19
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(SiFivePLICState, SIFIVE_PLIC,
20
typedef enum PLICMode {
21
PLICMode_U,
22
PLICMode_S,
23
- PLICMode_H,
24
PLICMode_M
25
} PLICMode;
26
27
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/sifive_plic.c
30
+++ b/hw/intc/sifive_plic.c
31
@@ -XXX,XX +XXX,XX @@ static PLICMode char_to_mode(char c)
32
switch (c) {
33
case 'U': return PLICMode_U;
34
case 'S': return PLICMode_S;
35
- case 'H': return PLICMode_H;
36
case 'M': return PLICMode_M;
37
default:
38
error_report("plic: invalid mode '%c'", c);
39
--
40
2.38.1
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
3
At present the PLIC config parser can only handle legal config string
4
enabled, will fail with a kernel oops SIGILL right at the start. The
4
like "MS,MS". However if a config string like ",MS,MS,,MS,MS,," is
5
reason is that we can't expose zkr without implementing the SEED CSR.
5
given the parser won't get the correct configuration.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
8
6
9
In hindsight this is too strict. If we keep proceeding, despite not
7
This commit improves the config parser to make it more robust.
10
disabling the extension in the KVM vcpu, we'll not add the extension in
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
14
8
15
Change our current logic to not error out if we fail to disable an
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
17
is important to throw a warning because we must make the user aware that
11
Message-Id: <20221211030829.802437-7-bmeng@tinylab.org>
18
the extension is still available in the vcpu, meaning that an
19
ill-behaved guest can ignore the riscv,isa settings and use the
20
extension.
21
22
The case we're handling happens with an EINVAL error code. If we fail to
23
disable the extension in KVM for any other reason, error out.
24
25
We'll also keep erroring out when we fail to enable an extension in KVM,
26
since adding the extension in riscv,isa at this point will cause a guest
27
malfunction because the extension isn't enabled in the vcpu.
28
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
13
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
14
hw/intc/sifive_plic.c | 24 ++++++++++++++++--------
37
1 file changed, 8 insertions(+), 4 deletions(-)
15
1 file changed, 16 insertions(+), 8 deletions(-)
38
16
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
40
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
19
--- a/hw/intc/sifive_plic.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
20
+++ b/hw/intc/sifive_plic.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
21
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_reset(DeviceState *dev)
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
22
*/
45
ret = kvm_set_one_reg(cs, id, &reg);
23
static void parse_hart_config(SiFivePLICState *plic)
46
if (ret != 0) {
24
{
47
- error_report("Unable to %s extension %s in KVM, error %d",
25
- int addrid, hartid, modes;
48
- reg ? "enable" : "disable",
26
+ int addrid, hartid, modes, m;
49
- multi_ext_cfg->name, ret);
27
const char *p;
50
- exit(EXIT_FAILURE);
28
char c;
51
+ if (!reg && ret == -EINVAL) {
29
52
+ warn_report("KVM cannot disable extension %s",
30
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
53
+ multi_ext_cfg->name);
31
p = plic->hart_config;
54
+ } else {
32
while ((c = *p++)) {
55
+ error_report("Unable to enable extension %s in KVM, error %d",
33
if (c == ',') {
56
+ multi_ext_cfg->name, ret);
34
- addrid += ctpop8(modes);
57
+ exit(EXIT_FAILURE);
35
- modes = 0;
36
- hartid++;
37
+ if (modes) {
38
+ addrid += ctpop8(modes);
39
+ hartid++;
40
+ modes = 0;
58
+ }
41
+ }
42
} else {
43
- int m = 1 << char_to_mode(c);
44
+ m = 1 << char_to_mode(c);
45
if (modes == (modes | m)) {
46
error_report("plic: duplicate mode '%c' in config: %s",
47
c, plic->hart_config);
48
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
49
}
50
if (modes) {
51
addrid += ctpop8(modes);
52
+ hartid++;
53
+ modes = 0;
54
}
55
- hartid++;
56
57
plic->num_addrs = addrid;
58
plic->num_harts = hartid;
59
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
60
p = plic->hart_config;
61
while ((c = *p++)) {
62
if (c == ',') {
63
- hartid++;
64
+ if (modes) {
65
+ hartid++;
66
+ modes = 0;
67
+ }
68
} else {
69
+ m = char_to_mode(c);
70
plic->addr_config[addrid].addrid = addrid;
71
plic->addr_config[addrid].hartid = hartid;
72
- plic->addr_config[addrid].mode = char_to_mode(c);
73
+ plic->addr_config[addrid].mode = m;
74
+ modes |= (1 << m);
75
addrid++;
59
}
76
}
60
}
77
}
61
}
62
--
78
--
63
2.45.1
79
2.38.1
diff view generated by jsdifflib
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
In AIA spec, each hart (or each hart within a group) has a unique hart
3
The realize() callback has an errp for us to propagate the error up.
4
number to locate the memory pages of interrupt files in the address
4
While we are here, correct the wrong multi-line comment format.
5
space. The number of bits required to represent any hart number is equal
6
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
7
groups.
8
5
9
However, if the largest hart number among groups is a power of 2, QEMU
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
9
Message-Id: <20221211030829.802437-8-bmeng@tinylab.org>
13
updated to ensure accurate hart-index-bit settings.
14
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
17
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
19
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
11
---
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
12
hw/intc/sifive_plic.c | 7 ++++---
27
1 file changed, 8 insertions(+), 1 deletion(-)
13
1 file changed, 4 insertions(+), 3 deletions(-)
28
14
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
30
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/kvm/kvm-cpu.c
17
--- a/hw/intc/sifive_plic.c
32
+++ b/target/riscv/kvm/kvm-cpu.c
18
+++ b/hw/intc/sifive_plic.c
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
19
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
20
s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
21
qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
22
23
- /* We can't allow the supervisor to control SEIP as this would allow the
24
+ /*
25
+ * We can't allow the supervisor to control SEIP as this would allow the
26
* supervisor to clear a pending external interrupt which will result in
27
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
28
* hardware controlled when a PLIC is attached.
29
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
30
for (i = 0; i < s->num_harts; i++) {
31
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
32
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
33
- error_report("SEIP already claimed");
34
- exit(1);
35
+ error_setg(errp, "SEIP already claimed");
36
+ return;
34
}
37
}
35
}
38
}
36
39
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
38
+
39
+ if (max_hart_per_socket > 1) {
40
+ max_hart_per_socket--;
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
42
+ } else {
43
+ hart_bits = 0;
44
+ }
45
+
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
48
&hart_bits, true, NULL);
49
--
40
--
50
2.45.1
41
2.38.1
diff view generated by jsdifflib
1
From: "yang.zhang" <yang.zhang@hexintek.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
3
At present the default value of "num-sources" property is zero,
4
be initialized first.
4
which does not make a lot of sense, as in sifive_plic_realize()
5
we see s->bitfield_words is calculated by:
5
6
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
7
s->bitfield_words = (s->num_sources + 31) >> 5;
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
9
if the we don't configure "num-sources" property its default value
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
zero makes s->bitfield_words zero too, which isn't true because
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
11
interrupt source 0 still occupies one word.
12
13
Let's change the default value to 1 meaning that only interrupt
14
source 0 is supported by default and a sanity check in realize().
15
16
While we are here, add a comment to describe the exact meaning of
17
this property that the number should include interrupt source 0.
18
19
Signed-off-by: Bin Meng <bmeng@tinylab.org>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20221211030829.802437-9-bmeng@tinylab.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
23
---
13
hw/intc/riscv_aplic.c | 8 ++++----
24
hw/intc/sifive_plic.c | 8 +++++++-
14
1 file changed, 4 insertions(+), 4 deletions(-)
25
1 file changed, 7 insertions(+), 1 deletion(-)
15
26
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
27
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
17
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/riscv_aplic.c
29
--- a/hw/intc/sifive_plic.c
19
+++ b/hw/intc/riscv_aplic.c
30
+++ b/hw/intc/sifive_plic.c
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
21
qdev_prop_set_bit(dev, "msimode", msimode);
32
22
qdev_prop_set_bit(dev, "mmode", mmode);
33
parse_hart_config(s);
23
34
24
+ if (parent) {
35
+ if (!s->num_sources) {
25
+ riscv_aplic_add_child(parent, dev);
36
+ error_setg(errp, "plic: invalid number of interrupt sources");
37
+ return;
26
+ }
38
+ }
27
+
39
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
40
s->bitfield_words = (s->num_sources + 31) >> 5;
29
41
s->num_enables = s->bitfield_words * s->num_addrs;
30
if (!is_kvm_aia(msimode)) {
42
s->source_priority = g_new0(uint32_t, s->num_sources);
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
43
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_plic = {
32
}
44
static Property sifive_plic_properties[] = {
33
45
DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
34
- if (parent) {
46
DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
35
- riscv_aplic_add_child(parent, dev);
47
- DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
36
- }
48
+ /* number of interrupt sources including interrupt source 0 */
37
-
49
+ DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
38
if (!msimode) {
50
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
39
for (i = 0; i < num_harts; i++) {
51
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
52
DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
41
--
53
--
42
2.45.1
54
2.38.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
In current implementation, the gdbstub allows reading vector registers
3
Per chapter 6.5.2 in [1], the number of interupt sources including
4
only if V extension is supported. However, all vector extensions and
4
interrupt source 0 should be 187.
5
vector crypto extensions have the vector registers and they all depend
6
on Zve32x. The gdbstub should check for Zve32x instead.
7
5
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
[1] PolarFire SoC MSS TRM:
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/ReferenceManuals/PolarFire_SoC_FPGA_MSS_Technical_Reference_Manual_VC.pdf
10
Reviewed-by: Max Chou <max.chou@sifive.com>
8
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
9
Fixes: 56f6e31e7b7e ("hw/riscv: Initial support for Microchip PolarFire SoC Icicle Kit board")
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
14
Message-Id: <20221211030829.802437-10-bmeng@tinylab.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
16
---
14
target/riscv/gdbstub.c | 2 +-
17
include/hw/riscv/microchip_pfsoc.h | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
18
1 file changed, 1 insertion(+), 1 deletion(-)
16
19
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
20
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
22
--- a/include/hw/riscv/microchip_pfsoc.h
20
+++ b/target/riscv/gdbstub.c
23
+++ b/include/hw/riscv/microchip_pfsoc.h
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
24
@@ -XXX,XX +XXX,XX @@ enum {
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
25
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
23
0);
26
#define MICROCHIP_PFSOC_COMPUTE_CPU_COUNT 4
24
}
27
25
- if (env->misa_ext & RVV) {
28
-#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 185
26
+ if (cpu->cfg.ext_zve32x) {
29
+#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
30
#define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
28
riscv_gdb_set_vector,
31
#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
32
#define MICROCHIP_PFSOC_PLIC_PENDING_BASE 0x1000
30
--
33
--
31
2.45.1
34
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
Per chapter 10 in Freedom E310 manuals [1][2][3], E310 G002 and G003
4
supports 52 interrupt sources while G000 supports 51 interrupt sources.
5
6
We use the value of G002 and G003, so it is 53 (including source 0).
7
8
[1] G000 manual:
9
https://sifive.cdn.prismic.io/sifive/4faf3e34-4a42-4c2f-be9e-c77baa4928c7_fe310-g000-manual-v3p2.pdf
10
11
[2] G002 manual:
12
https://sifive.cdn.prismic.io/sifive/034760b5-ac6a-4b1c-911c-f4148bb2c4a5_fe310-g002-v1p5.pdf
13
14
[3] G003 manual:
15
https://sifive.cdn.prismic.io/sifive/3af39c59-6498-471e-9dab-5355a0d539eb_fe310-g003-manual.pdf
16
17
Fixes: eb637edb1241 ("SiFive Freedom E Series RISC-V Machine")
18
Signed-off-by: Bin Meng <bmeng@tinylab.org>
19
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20221211030829.802437-11-bmeng@tinylab.org>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
include/hw/riscv/sifive_e.h | 7 ++++++-
25
1 file changed, 6 insertions(+), 1 deletion(-)
26
27
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/riscv/sifive_e.h
30
+++ b/include/hw/riscv/sifive_e.h
31
@@ -XXX,XX +XXX,XX @@ enum {
32
};
33
34
#define SIFIVE_E_PLIC_HART_CONFIG "M"
35
-#define SIFIVE_E_PLIC_NUM_SOURCES 127
36
+/*
37
+ * Freedom E310 G002 and G003 supports 52 interrupt sources while
38
+ * Freedom E310 G000 supports 51 interrupt sources. We use the value
39
+ * of G002 and G003, so it is 53 (including interrupt source 0).
40
+ */
41
+#define SIFIVE_E_PLIC_NUM_SOURCES 53
42
#define SIFIVE_E_PLIC_NUM_PRIORITIES 7
43
#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
44
#define SIFIVE_E_PLIC_PENDING_BASE 0x1000
45
--
46
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
At present magic number is used to create "riscv,ndev" property
4
in the dtb. Let's use the macro SIFIVE_U_PLIC_NUM_SOURCES that
5
is used to instantiate the PLIC model instead.
6
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221211030829.802437-12-bmeng@tinylab.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/riscv/sifive_u.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
19
+++ b/hw/riscv/sifive_u.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
21
qemu_fdt_setprop_cells(fdt, nodename, "reg",
22
0x0, memmap[SIFIVE_U_DEV_PLIC].base,
23
0x0, memmap[SIFIVE_U_DEV_PLIC].size);
24
- qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
25
+ qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
26
+ SIFIVE_U_PLIC_NUM_SOURCES - 1);
27
qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
28
plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
29
g_free(cells);
30
--
31
2.38.1
diff view generated by jsdifflib
1
From: Rob Bradford <rbradford@rivosinc.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
This extension has now been ratified:
3
Commit 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
4
changed the value of VIRT_IRQCHIP_NUM_SOURCES from 127 to 53, which
5
removed.
5
is VIRTIO_NDEV and also used as the value of "riscv,ndev" property
6
in the dtb. Unfortunately this is wrong as VIRT_IRQCHIP_NUM_SOURCES
7
should include interrupt source 0 but "riscv,ndev" does not.
6
8
7
Since this is now a ratified extension add it to the list of extensions
9
While we are here, we also fix the comments of platform bus irq range
8
included in the "max" CPU variant.
10
which is now "64 to 96", but should be "64 to 95", introduced since
11
commit 1832b7cb3f64 ("hw/riscv: virt: Create a platform bus").
9
12
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
13
Fixes: 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
Message-Id: <20221211030829.802437-13-bmeng@tinylab.org>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
---
18
target/riscv/cpu.c | 2 +-
19
include/hw/riscv/virt.h | 5 ++---
19
target/riscv/tcg/tcg-cpu.c | 2 +-
20
hw/riscv/virt.c | 3 ++-
20
2 files changed, 2 insertions(+), 2 deletions(-)
21
2 files changed, 4 insertions(+), 4 deletions(-)
21
22
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
23
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.c
25
--- a/include/hw/riscv/virt.h
25
+++ b/target/riscv/cpu.c
26
+++ b/include/hw/riscv/virt.h
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
27
@@ -XXX,XX +XXX,XX @@ enum {
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
28
VIRTIO_IRQ = 1, /* 1 to 8 */
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
29
VIRTIO_COUNT = 8,
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
30
PCIE_IRQ = 0x20, /* 32 to 35 */
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
31
- VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
32
- VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */
33
+ VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
32
};
34
};
33
35
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
36
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
37
38
#define VIRT_IRQCHIP_NUM_MSIS 255
39
-#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
40
+#define VIRT_IRQCHIP_NUM_SOURCES 96
41
#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
42
#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
43
#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
44
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
36
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/tcg/tcg-cpu.c
46
--- a/hw/riscv/virt.c
38
+++ b/target/riscv/tcg/tcg-cpu.c
47
+++ b/hw/riscv/virt.c
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
40
const RISCVCPUMultiExtConfig *prop;
49
plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
41
50
qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
42
/* Enable RVG, RVJ and RVV that are disabled by default */
51
0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
52
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev", VIRTIO_NDEV);
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
53
+ qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
45
54
+ VIRT_IRQCHIP_NUM_SOURCES - 1);
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
55
riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
47
isa_ext_update_enabled(cpu, prop->offset, true);
56
qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
57
plic_phandles[socket]);
48
--
58
--
49
2.45.1
59
2.38.1
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
3
At present the SiFive PLIC model "priority-base" expects interrupt
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
4
priority register base starting from source 1 instead source 0,
5
CSRs are part of the disassembly.
5
that's why on most platforms "priority-base" is set to 0x04 except
6
'opentitan' machine. 'opentitan' should have set "priority-base"
7
to 0x04 too.
6
8
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
9
Note the irq number calculation in sifive_plic_{read,write} is
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
correct as the codes make up for the irq number by adding 1.
9
Fixes: ea10325917 ("RISC-V Disassembler")
11
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Let's simply update "priority-base" to start from interrupt source
11
Cc: qemu-stable <qemu-stable@nongnu.org>
13
0 and add a comment to make it crystal clear.
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
14
15
Signed-off-by: Bin Meng <bmeng@tinylab.org>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
18
Message-Id: <20221211030829.802437-14-bmeng@tinylab.org>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
20
---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
21
include/hw/riscv/microchip_pfsoc.h | 2 +-
16
1 file changed, 64 insertions(+), 1 deletion(-)
22
include/hw/riscv/shakti_c.h | 2 +-
23
include/hw/riscv/sifive_e.h | 2 +-
24
include/hw/riscv/sifive_u.h | 2 +-
25
include/hw/riscv/virt.h | 2 +-
26
hw/intc/sifive_plic.c | 5 +++--
27
6 files changed, 8 insertions(+), 7 deletions(-)
17
28
18
diff --git a/disas/riscv.c b/disas/riscv.c
29
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
19
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.c
31
--- a/include/hw/riscv/microchip_pfsoc.h
21
+++ b/disas/riscv.c
32
+++ b/include/hw/riscv/microchip_pfsoc.h
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
33
@@ -XXX,XX +XXX,XX @@ enum {
23
case 0x0383: return "mibound";
34
24
case 0x0384: return "mdbase";
35
#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
25
case 0x0385: return "mdbound";
36
#define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
26
- case 0x03a0: return "pmpcfg3";
37
-#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04
27
+ case 0x03a0: return "pmpcfg0";
38
+#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x00
28
+ case 0x03a1: return "pmpcfg1";
39
#define MICROCHIP_PFSOC_PLIC_PENDING_BASE 0x1000
29
+ case 0x03a2: return "pmpcfg2";
40
#define MICROCHIP_PFSOC_PLIC_ENABLE_BASE 0x2000
30
+ case 0x03a3: return "pmpcfg3";
41
#define MICROCHIP_PFSOC_PLIC_ENABLE_STRIDE 0x80
31
+ case 0x03a4: return "pmpcfg4";
42
diff --git a/include/hw/riscv/shakti_c.h b/include/hw/riscv/shakti_c.h
32
+ case 0x03a5: return "pmpcfg5";
43
index XXXXXXX..XXXXXXX 100644
33
+ case 0x03a6: return "pmpcfg6";
44
--- a/include/hw/riscv/shakti_c.h
34
+ case 0x03a7: return "pmpcfg7";
45
+++ b/include/hw/riscv/shakti_c.h
35
+ case 0x03a8: return "pmpcfg8";
46
@@ -XXX,XX +XXX,XX @@ enum {
36
+ case 0x03a9: return "pmpcfg9";
47
#define SHAKTI_C_PLIC_NUM_SOURCES 28
37
+ case 0x03aa: return "pmpcfg10";
48
/* Excluding Priority 0 */
38
+ case 0x03ab: return "pmpcfg11";
49
#define SHAKTI_C_PLIC_NUM_PRIORITIES 2
39
+ case 0x03ac: return "pmpcfg12";
50
-#define SHAKTI_C_PLIC_PRIORITY_BASE 0x04
40
+ case 0x03ad: return "pmpcfg13";
51
+#define SHAKTI_C_PLIC_PRIORITY_BASE 0x00
41
+ case 0x03ae: return "pmpcfg14";
52
#define SHAKTI_C_PLIC_PENDING_BASE 0x1000
42
+ case 0x03af: return "pmpcfg15";
53
#define SHAKTI_C_PLIC_ENABLE_BASE 0x2000
43
case 0x03b0: return "pmpaddr0";
54
#define SHAKTI_C_PLIC_ENABLE_STRIDE 0x80
44
case 0x03b1: return "pmpaddr1";
55
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
45
case 0x03b2: return "pmpaddr2";
56
index XXXXXXX..XXXXXXX 100644
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
57
--- a/include/hw/riscv/sifive_e.h
47
case 0x03bd: return "pmpaddr13";
58
+++ b/include/hw/riscv/sifive_e.h
48
case 0x03be: return "pmpaddr14";
59
@@ -XXX,XX +XXX,XX @@ enum {
49
case 0x03bf: return "pmpaddr15";
60
*/
50
+ case 0x03c0: return "pmpaddr16";
61
#define SIFIVE_E_PLIC_NUM_SOURCES 53
51
+ case 0x03c1: return "pmpaddr17";
62
#define SIFIVE_E_PLIC_NUM_PRIORITIES 7
52
+ case 0x03c2: return "pmpaddr18";
63
-#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
53
+ case 0x03c3: return "pmpaddr19";
64
+#define SIFIVE_E_PLIC_PRIORITY_BASE 0x00
54
+ case 0x03c4: return "pmpaddr20";
65
#define SIFIVE_E_PLIC_PENDING_BASE 0x1000
55
+ case 0x03c5: return "pmpaddr21";
66
#define SIFIVE_E_PLIC_ENABLE_BASE 0x2000
56
+ case 0x03c6: return "pmpaddr22";
67
#define SIFIVE_E_PLIC_ENABLE_STRIDE 0x80
57
+ case 0x03c7: return "pmpaddr23";
68
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
58
+ case 0x03c8: return "pmpaddr24";
69
index XXXXXXX..XXXXXXX 100644
59
+ case 0x03c9: return "pmpaddr25";
70
--- a/include/hw/riscv/sifive_u.h
60
+ case 0x03ca: return "pmpaddr26";
71
+++ b/include/hw/riscv/sifive_u.h
61
+ case 0x03cb: return "pmpaddr27";
72
@@ -XXX,XX +XXX,XX @@ enum {
62
+ case 0x03cc: return "pmpaddr28";
73
63
+ case 0x03cd: return "pmpaddr29";
74
#define SIFIVE_U_PLIC_NUM_SOURCES 54
64
+ case 0x03ce: return "pmpaddr30";
75
#define SIFIVE_U_PLIC_NUM_PRIORITIES 7
65
+ case 0x03cf: return "pmpaddr31";
76
-#define SIFIVE_U_PLIC_PRIORITY_BASE 0x04
66
+ case 0x03d0: return "pmpaddr32";
77
+#define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
67
+ case 0x03d1: return "pmpaddr33";
78
#define SIFIVE_U_PLIC_PENDING_BASE 0x1000
68
+ case 0x03d2: return "pmpaddr34";
79
#define SIFIVE_U_PLIC_ENABLE_BASE 0x2000
69
+ case 0x03d3: return "pmpaddr35";
80
#define SIFIVE_U_PLIC_ENABLE_STRIDE 0x80
70
+ case 0x03d4: return "pmpaddr36";
81
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
71
+ case 0x03d5: return "pmpaddr37";
82
index XXXXXXX..XXXXXXX 100644
72
+ case 0x03d6: return "pmpaddr38";
83
--- a/include/hw/riscv/virt.h
73
+ case 0x03d7: return "pmpaddr39";
84
+++ b/include/hw/riscv/virt.h
74
+ case 0x03d8: return "pmpaddr40";
85
@@ -XXX,XX +XXX,XX @@ enum {
75
+ case 0x03d9: return "pmpaddr41";
86
#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
76
+ case 0x03da: return "pmpaddr42";
87
#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
77
+ case 0x03db: return "pmpaddr43";
88
78
+ case 0x03dc: return "pmpaddr44";
89
-#define VIRT_PLIC_PRIORITY_BASE 0x04
79
+ case 0x03dd: return "pmpaddr45";
90
+#define VIRT_PLIC_PRIORITY_BASE 0x00
80
+ case 0x03de: return "pmpaddr46";
91
#define VIRT_PLIC_PENDING_BASE 0x1000
81
+ case 0x03df: return "pmpaddr47";
92
#define VIRT_PLIC_ENABLE_BASE 0x2000
82
+ case 0x03e0: return "pmpaddr48";
93
#define VIRT_PLIC_ENABLE_STRIDE 0x80
83
+ case 0x03e1: return "pmpaddr49";
94
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
84
+ case 0x03e2: return "pmpaddr50";
95
index XXXXXXX..XXXXXXX 100644
85
+ case 0x03e3: return "pmpaddr51";
96
--- a/hw/intc/sifive_plic.c
86
+ case 0x03e4: return "pmpaddr52";
97
+++ b/hw/intc/sifive_plic.c
87
+ case 0x03e5: return "pmpaddr53";
98
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
88
+ case 0x03e6: return "pmpaddr54";
99
SiFivePLICState *plic = opaque;
89
+ case 0x03e7: return "pmpaddr55";
100
90
+ case 0x03e8: return "pmpaddr56";
101
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
91
+ case 0x03e9: return "pmpaddr57";
102
- uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
92
+ case 0x03ea: return "pmpaddr58";
103
+ uint32_t irq = (addr - plic->priority_base) >> 2;
93
+ case 0x03eb: return "pmpaddr59";
104
94
+ case 0x03ec: return "pmpaddr60";
105
return plic->source_priority[irq];
95
+ case 0x03ed: return "pmpaddr61";
106
} else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
96
+ case 0x03ee: return "pmpaddr62";
107
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
97
+ case 0x03ef: return "pmpaddr63";
108
SiFivePLICState *plic = opaque;
98
case 0x0780: return "mtohost";
109
99
case 0x0781: return "mfromhost";
110
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
100
case 0x0782: return "mreset";
111
- uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
112
+ uint32_t irq = (addr - plic->priority_base) >> 2;
113
114
if (((plic->num_priorities + 1) & plic->num_priorities) == 0) {
115
/*
116
@@ -XXX,XX +XXX,XX @@ static Property sifive_plic_properties[] = {
117
/* number of interrupt sources including interrupt source 0 */
118
DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
119
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
120
+ /* interrupt priority register base starting from source 0 */
121
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
122
DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
123
DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
101
--
124
--
102
2.45.1
125
2.38.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
If the checking functions check both the single and double width
3
"hartid-base" and "priority-base" are zero by default. There is no
4
operators at the same time, then the single width operator checking
4
need to initialize them to zero again.
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
5
7
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
9
Message-Id: <20221211030829.802437-15-bmeng@tinylab.org>
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/insn_trans/trans_rvv.c.inc | 16 ++++------------
12
hw/riscv/opentitan.c | 2 --
14
1 file changed, 4 insertions(+), 12 deletions(-)
13
1 file changed, 2 deletions(-)
15
14
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
--- a/hw/riscv/opentitan.c
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/hw/riscv/opentitan.c
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
19
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
21
return require_rvv(s) &&
20
22
require_rvf(s) &&
21
/* PLIC */
23
require_scale_rvf(s) &&
22
qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
24
- (s->sew != MO_8) &&
23
- qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
25
vext_check_isa_ill(s) &&
24
qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
25
qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
27
}
26
- qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
27
qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
29
return require_rvv(s) &&
28
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
30
require_rvf(s) &&
29
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 32);
31
require_scale_rvf(s) &&
32
- (s->sew != MO_8) &&
33
vext_check_isa_ill(s) &&
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
37
return require_rvv(s) &&
38
require_rvf(s) &&
39
require_scale_rvf(s) &&
40
- (s->sew != MO_8) &&
41
vext_check_isa_ill(s) &&
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
45
return require_rvv(s) &&
46
require_rvf(s) &&
47
require_scale_rvf(s) &&
48
- (s->sew != MO_8) &&
49
vext_check_isa_ill(s) &&
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
53
{
54
return opfv_widen_check(s, a) &&
55
require_rvfmin(s) &&
56
- require_scale_rvfmin(s) &&
57
- (s->sew != MO_8);
58
+ require_scale_rvfmin(s);
59
}
60
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
63
{
64
return opfv_narrow_check(s, a) &&
65
require_rvfmin(s) &&
66
- require_scale_rvfmin(s) &&
67
- (s->sew != MO_8);
68
+ require_scale_rvfmin(s);
69
}
70
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
72
{
73
return opfv_narrow_check(s, a) &&
74
require_rvf(s) &&
75
- require_scale_rvf(s) &&
76
- (s->sew != MO_8);
77
+ require_scale_rvf(s);
78
}
79
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
82
{
83
return reduction_widen_check(s, a) &&
84
require_rvf(s) &&
85
- require_scale_rvf(s) &&
86
- (s->sew != MO_8);
87
+ require_scale_rvf(s);
88
}
89
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
91
--
30
--
92
2.45.1
31
2.38.1
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bmeng@tinylab.org>
2
2
3
The require_scale_rvf function only checks the double width operator for
3
The pending register upper limit is currently set to
4
the vector floating point widen instructions, so most of the widen
4
plic->num_sources >> 3, which is wrong, e.g.: considering
5
checking functions need to add require_rvf for single width operator.
5
plic->num_sources is 7, the upper limit becomes 0 which fails
6
the range check if reading the pending register at pending_base.
6
7
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
8
Fixes: 1e24429e40df ("SiFive RISC-V PLIC Block")
8
integer to double width float, so the opfxv_widen_check function doesn’t
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
9
need require_rvf for the single width operator(integer).
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
11
Message-Id: <20221211030829.802437-16-bmeng@tinylab.org>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
13
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
14
hw/intc/sifive_plic.c | 5 +++--
18
1 file changed, 5 insertions(+)
15
1 file changed, 3 insertions(+), 2 deletions(-)
19
16
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
--- a/hw/intc/sifive_plic.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
+++ b/hw/intc/sifive_plic.c
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
21
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
22
uint32_t irq = (addr - plic->priority_base) >> 2;
26
{
23
27
return require_rvv(s) &&
24
return plic->source_priority[irq];
28
+ require_rvf(s) &&
25
- } else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
29
require_scale_rvf(s) &&
26
+ } else if (addr_between(addr, plic->pending_base,
30
(s->sew != MO_8) &&
27
+ (plic->num_sources + 31) >> 3)) {
31
vext_check_isa_ill(s) &&
28
uint32_t word = (addr - plic->pending_base) >> 2;
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
29
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
30
return plic->pending[word];
34
{
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
35
return require_rvv(s) &&
32
sifive_plic_update(plic);
36
+ require_rvf(s) &&
33
}
37
require_scale_rvf(s) &&
34
} else if (addr_between(addr, plic->pending_base,
38
(s->sew != MO_8) &&
35
- plic->num_sources >> 3)) {
39
vext_check_isa_ill(s) &&
36
+ (plic->num_sources + 31) >> 3)) {
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
37
qemu_log_mask(LOG_GUEST_ERROR,
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
38
"%s: invalid pending write: 0x%" HWADDR_PRIx "",
42
{
39
__func__, addr);
43
return require_rvv(s) &&
44
+ require_rvf(s) &&
45
require_scale_rvf(s) &&
46
(s->sew != MO_8) &&
47
vext_check_isa_ill(s) &&
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
50
{
51
return require_rvv(s) &&
52
+ require_rvf(s) &&
53
require_scale_rvf(s) &&
54
(s->sew != MO_8) &&
55
vext_check_isa_ill(s) &&
56
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
57
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
58
{
59
return reduction_widen_check(s, a) &&
60
+ require_rvf(s) &&
61
require_scale_rvf(s) &&
62
(s->sew != MO_8);
63
}
64
--
40
--
65
2.45.1
41
2.38.1
66
67
diff view generated by jsdifflib