1
The following changes since commit 20c1df5476e1e9b5d3f5b94f9f3ce01d21f14c46:
1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20200713-pull-request' into staging (2020-07-13 16:58:44 +0100)
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20200713
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
8
8
9
for you to fetch changes up to cfad709bceb629a4ebeb5d8a3acd1871b9a6436b:
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
10
10
11
target/riscv: Fix pmp NA4 implementation (2020-07-13 17:25:37 -0700)
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
This is a colection of bug fixes and small imrprovements for RISC-V.
14
RISC-V PR for 9.1
15
15
16
This includes some vector extensions fixes, a PMP bug fix, OpenTitan
16
* APLICs add child earlier than realize
17
UART bug fix and support for OpenSBI dynamic firmware.
17
* Fix exposure of Zkr
18
* Raise exceptions on wrs.nto
19
* Implement SBI debug console (DBCN) calls for KVM
20
* Support 64-bit addresses for initrd
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
22
* Tolerate KVM disable ext errors
23
* Set tval in breakpoints
24
* Add support for Zve32x extension
25
* Add support for Zve64x extension
26
* Relax vector register check in RISCV gdbstub
27
* Fix the element agnostic Vector function problem
28
* Fix Zvkb extension config
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
18
43
19
----------------------------------------------------------------
44
----------------------------------------------------------------
20
Alexandre Mergnat (1):
45
Alexei Filippov (1):
21
target/riscv: Fix pmp NA4 implementation
46
target/riscv: do not set mtval2 for non guest-page faults
22
47
23
Alistair Francis (2):
48
Alistair Francis (2):
24
hw/char: Convert the Ibex UART to use the qdev Clock model
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
25
hw/char: Convert the Ibex UART to use the registerfields API
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
26
51
27
Atish Patra (4):
52
Andrew Jones (2):
28
riscv: Unify Qemu's reset vector code path
53
target/riscv/kvm: Fix exposure of Zkr
29
RISC-V: Copy the fdt in dram instead of ROM
54
target/riscv: Raise exceptions on wrs.nto
30
riscv: Add opensbi firmware dynamic support
31
RISC-V: Support 64 bit start address
32
55
33
Bin Meng (3):
56
Cheng Yang (1):
34
MAINTAINERS: Add an entry for OpenSBI firmware
57
hw/riscv/boot.c: Support 64-bit address for initrd
35
hw/riscv: virt: Sort the SoC memmap table entries
36
hw/riscv: Modify MROM size to end at 0x10000
37
58
38
Frank Chang (4):
59
Christoph Müllner (1):
39
target/riscv: fix rsub gvec tcg_assert_listed_vecop assertion
60
riscv: thead: Add th.sxstatus CSR emulation
40
target/riscv: correct the gvec IR called in gen_vec_rsub16_i64()
41
target/riscv: fix return value of do_opivx_widen()
42
target/riscv: fix vill bit index in vtype register
43
61
44
Liao Pingfang (1):
62
Clément Léger (1):
45
tcg/riscv: Remove superfluous breaks
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
46
64
47
include/hw/char/ibex_uart.h | 79 ++++++++--------
65
Daniel Henrique Barboza (6):
48
include/hw/riscv/boot.h | 7 ++
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
49
include/hw/riscv/boot_opensbi.h | 58 ++++++++++++
67
target/riscv/kvm: tolerate KVM disable ext errors
50
target/riscv/cpu.h | 2 +-
68
target/riscv/debug: set tval=pc in breakpoint exceptions
51
hw/char/ibex_uart.c | 158 ++++++++++++++++++--------------
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
52
hw/riscv/boot.c | 107 +++++++++++++++++++++
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
53
hw/riscv/sifive_u.c | 53 ++++++-----
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
54
hw/riscv/spike.c | 59 ++++--------
55
hw/riscv/virt.c | 63 ++++---------
56
target/riscv/insn_trans/trans_rvv.inc.c | 9 +-
57
target/riscv/pmp.c | 2 +-
58
tcg/riscv/tcg-target.inc.c | 2 -
59
MAINTAINERS | 7 ++
60
13 files changed, 387 insertions(+), 219 deletions(-)
61
create mode 100644 include/hw/riscv/boot_opensbi.h
62
72
73
Huang Tao (2):
74
target/riscv: Fix the element agnostic function problem
75
target/riscv: Implement dynamic establishment of custom decoder
76
77
Jason Chien (3):
78
target/riscv: Add support for Zve32x extension
79
target/riscv: Add support for Zve64x extension
80
target/riscv: Relax vector register check in RISCV gdbstub
81
82
Max Chou (4):
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
87
88
Rob Bradford (1):
89
target/riscv: Remove experimental prefix from "B" extension
90
91
Yangyu Chen (1):
92
target/riscv/cpu.c: fix Zvkb extension config
93
94
Yong-Xuan Wang (1):
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
96
97
Yu-Ming Chang (1):
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
99
100
yang.zhang (1):
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
102
103
MAINTAINERS | 1 +
104
target/riscv/cpu.h | 11 ++
105
target/riscv/cpu_bits.h | 2 +-
106
target/riscv/cpu_cfg.h | 2 +
107
target/riscv/helper.h | 1 +
108
target/riscv/sbi_ecall_interface.h | 17 +++
109
target/riscv/tcg/tcg-cpu.h | 15 +++
110
disas/riscv.c | 65 +++++++++-
111
hw/intc/riscv_aplic.c | 8 +-
112
hw/riscv/boot.c | 4 +-
113
target/riscv/cpu.c | 10 +-
114
target/riscv/cpu_helper.c | 37 +++---
115
target/riscv/csr.c | 71 +++++++++--
116
target/riscv/debug.c | 3 +
117
target/riscv/gdbstub.c | 8 +-
118
target/riscv/kvm/kvm-cpu.c | 157 ++++++++++++++++++++++++-
119
target/riscv/op_helper.c | 17 ++-
120
target/riscv/tcg/tcg-cpu.c | 50 +++++---
121
target/riscv/th_csr.c | 79 +++++++++++++
122
target/riscv/translate.c | 31 +++--
123
target/riscv/vector_internals.c | 22 ++++
124
target/riscv/insn_trans/trans_privileged.c.inc | 2 +
125
target/riscv/insn_trans/trans_rvv.c.inc | 46 +++++---
126
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 +++--
127
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++-
128
target/riscv/meson.build | 1 +
129
26 files changed, 596 insertions(+), 109 deletions(-)
130
create mode 100644 target/riscv/th_csr.c
131
diff view generated by jsdifflib
New patch
1
From: "yang.zhang" <yang.zhang@hexintek.com>
1
2
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
4
be initialized first.
5
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/intc/riscv_aplic.c | 8 ++++----
14
1 file changed, 4 insertions(+), 4 deletions(-)
15
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/riscv_aplic.c
19
+++ b/hw/intc/riscv_aplic.c
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
21
qdev_prop_set_bit(dev, "msimode", msimode);
22
qdev_prop_set_bit(dev, "mmode", mmode);
23
24
+ if (parent) {
25
+ riscv_aplic_add_child(parent, dev);
26
+ }
27
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
29
30
if (!is_kvm_aia(msimode)) {
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
32
}
33
34
- if (parent) {
35
- riscv_aplic_add_child(parent, dev);
36
- }
37
-
38
if (!msimode) {
39
for (i = 0; i < num_harts; i++) {
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
41
--
42
2.45.1
diff view generated by jsdifflib
New patch
1
From: Andrew Jones <ajones@ventanamicro.com>
1
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
4
implements the SEED CSR. Use the same implementation as TCG.
5
6
Without this patch, running with a KVM which does not forward the
7
SEED CSR access to QEMU will result in an ILL exception being
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
12
Fixes: 3108e2f1c69d ("target/riscv/kvm: update KVM exts to Linux 6.8")
13
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Cc: qemu-stable <qemu-stable@nongnu.org>
16
Message-ID: <20240422134605.534207-2-ajones@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
target/riscv/cpu.h | 3 +++
20
target/riscv/csr.c | 18 ++++++++++++++----
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
22
3 files changed, 42 insertions(+), 4 deletions(-)
23
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
29
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
31
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
33
+ target_ulong write_mask);
34
+
35
uint8_t satp_mode_max_from_map(uint32_t map);
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
37
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/csr.c
41
+++ b/target/riscv/csr.c
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
43
#endif
44
45
/* Crypto Extension */
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
47
- target_ulong *ret_value,
48
- target_ulong new_value,
49
- target_ulong write_mask)
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
51
+ target_ulong write_mask)
52
{
53
uint16_t random_v;
54
Error *random_e = NULL;
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
56
rval = random_v | SEED_OPST_ES16;
57
}
58
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
--
118
2.45.1
diff view generated by jsdifflib
1
Conver the Ibex UART to use the recently added qdev-clock functions.
1
From: Andrew Jones <ajones@ventanamicro.com>
2
2
3
Implementing wrs.nto to always just return is consistent with the
4
specification, as the instruction is permitted to terminate the
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
14
Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
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>
18
Message-ID: <20240424142808.62936-2-ajones@ventanamicro.com>
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: b0136fad870a29049959ec161c1217b967d7e19d.1594332223.git.alistair.francis@wdc.com
6
Message-Id: <b0136fad870a29049959ec161c1217b967d7e19d.1594332223.git.alistair.francis@wdc.com>
7
---
20
---
8
include/hw/char/ibex_uart.h | 3 +++
21
target/riscv/helper.h | 1 +
9
hw/char/ibex_uart.c | 30 +++++++++++++++++++++++++++---
22
target/riscv/op_helper.c | 11 ++++++++
10
2 files changed, 30 insertions(+), 3 deletions(-)
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
24
3 files changed, 32 insertions(+), 9 deletions(-)
11
25
12
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
13
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/char/ibex_uart.h
28
--- a/target/riscv/helper.h
15
+++ b/include/hw/char/ibex_uart.h
29
+++ b/target/riscv/helper.h
16
@@ -XXX,XX +XXX,XX @@
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
17
#define IBEX_UART_TIMEOUT_CTRL 0x2c
31
DEF_HELPER_1(sret, tl, env)
18
32
DEF_HELPER_1(mret, tl, env)
19
#define IBEX_UART_TX_FIFO_SIZE 16
33
DEF_HELPER_1(wfi, void, env)
20
+#define IBEX_UART_CLOCK 50000000 /* 50MHz clock */
34
+DEF_HELPER_1(wrs_nto, void, env)
21
35
DEF_HELPER_1(tlb_flush, void, env)
22
#define TYPE_IBEX_UART "ibex-uart"
36
DEF_HELPER_1(tlb_flush_all, void, env)
23
#define IBEX_UART(obj) \
37
/* Native Debug */
24
@@ -XXX,XX +XXX,XX @@ typedef struct {
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
25
uint32_t uart_val;
26
uint32_t uart_timeout_ctrl;
27
28
+ Clock *f_clk;
29
+
30
CharBackend chr;
31
qemu_irq tx_watermark;
32
qemu_irq rx_watermark;
33
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
34
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/char/ibex_uart.c
40
--- a/target/riscv/op_helper.c
36
+++ b/hw/char/ibex_uart.c
41
+++ b/target/riscv/op_helper.c
37
@@ -XXX,XX +XXX,XX @@
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
38
#include "qemu/osdep.h"
43
}
39
#include "hw/char/ibex_uart.h"
40
#include "hw/irq.h"
41
+#include "hw/qdev-clock.h"
42
#include "hw/qdev-properties.h"
43
#include "migration/vmstate.h"
44
#include "qemu/log.h"
45
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
46
ibex_uart_update_irqs(s);
47
}
44
}
48
45
49
+static uint64_t ibex_uart_get_baud(IbexUartState *s)
46
+void helper_wrs_nto(CPURISCVState *env)
50
+{
47
+{
51
+ uint64_t baud;
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
52
+
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
53
+ baud = ((s->uart_ctrl & UART_CTRL_NCO) >> 16);
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
54
+ baud *= clock_get_hz(s->f_clk);
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
55
+ baud >>= 20;
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
56
+
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
57
+ return baud;
54
+ }
58
+}
55
+}
59
+
56
+
60
static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
57
void helper_tlb_flush(CPURISCVState *env)
61
unsigned int size)
62
{
58
{
63
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
59
CPUState *cs = env_cpu(env);
64
"%s: UART_CTRL_RXBLVL is not supported\n", __func__);
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
65
}
61
index XXXXXXX..XXXXXXX 100644
66
if (value & UART_CTRL_NCO) {
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
67
- uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
68
- baud *= 1000;
64
@@ -XXX,XX +XXX,XX @@
69
- baud >>= 20;
65
* this program. If not, see <http://www.gnu.org/licenses/>.
70
+ uint64_t baud = ibex_uart_get_baud(s);
66
*/
71
67
72
s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
68
-static bool trans_wrs(DisasContext *ctx)
73
}
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
74
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
70
{
75
}
71
if (!ctx->cfg_ptr->ext_zawrs) {
72
return false;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
74
return true;
76
}
75
}
77
76
78
+static void ibex_uart_clk_update(void *opaque)
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)
79
+{
84
+{
80
+ IbexUartState *s = opaque;
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
86
+ return false;
87
+ }
88
89
-GEN_TRANS_WRS(wrs_nto)
90
-GEN_TRANS_WRS(wrs_sto)
91
+ /*
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
93
+ * should raise an exception when the implementation-specific bounded time
94
+ * limit has expired. Our time limit is zero, so we either return
95
+ * immediately, as does our implementation of wrs.sto, or raise an
96
+ * exception, as handled by the wrs.nto helper.
97
+ */
98
+#ifndef CONFIG_USER_ONLY
99
+ gen_helper_wrs_nto(tcg_env);
100
+#endif
81
+
101
+
82
+ /* recompute uart's speed on clock change */
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
83
+ uint64_t baud = ibex_uart_get_baud(s);
103
+ return trans_wrs_sto(ctx, NULL);
84
+
85
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
86
+}
104
+}
87
+
88
static void fifo_trigger_update(void *opaque)
89
{
90
IbexUartState *s = opaque;
91
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_init(Object *obj)
92
{
93
IbexUartState *s = IBEX_UART(obj);
94
95
+ s->f_clk = qdev_init_clock_in(DEVICE(obj), "f_clock",
96
+ ibex_uart_clk_update, s);
97
+ clock_set_hz(s->f_clk, IBEX_UART_CLOCK);
98
+
99
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
100
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_watermark);
101
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_empty);
102
--
105
--
103
2.27.0
106
2.45.1
104
107
105
108
diff view generated by jsdifflib
New patch
1
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
4
the legacy console putchar and getchar SBI extensions.
5
6
The appeal of the DBCN extension is that it allows multiple bytes to be
7
read/written in the SBI console in a single SBI call.
8
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
10
module to userspace. But this will only happens if the KVM module
11
actually supports this SBI extension and we activate it.
12
13
We'll check for DBCN support during init time, checking if get-reg-list
14
is advertising KVM_RISCV_SBI_EXT_DBCN. In that case, we'll enable it via
15
kvm_set_one_reg() during kvm_arch_init_vcpu().
16
17
Finally, change kvm_riscv_handle_sbi() to handle the incoming calls for
18
SBI_EXT_DBCN, reading and writing as required.
19
20
A simple KVM guest with 'earlycon=sbi', running in an emulated RISC-V
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>
30
---
31
target/riscv/sbi_ecall_interface.h | 17 +++++
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
33
2 files changed, 128 insertions(+)
34
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/sbi_ecall_interface.h
38
+++ b/target/riscv/sbi_ecall_interface.h
39
@@ -XXX,XX +XXX,XX @@
40
41
/* clang-format off */
42
43
+#define SBI_SUCCESS 0
44
+#define SBI_ERR_FAILED -1
45
+#define SBI_ERR_NOT_SUPPORTED -2
46
+#define SBI_ERR_INVALID_PARAM -3
47
+#define SBI_ERR_DENIED -4
48
+#define SBI_ERR_INVALID_ADDRESS -5
49
+#define SBI_ERR_ALREADY_AVAILABLE -6
50
+#define SBI_ERR_ALREADY_STARTED -7
51
+#define SBI_ERR_ALREADY_STOPPED -8
52
+#define SBI_ERR_NO_SHMEM -9
53
+
54
/* SBI Extension IDs */
55
#define SBI_EXT_0_1_SET_TIMER 0x0
56
#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
57
@@ -XXX,XX +XXX,XX @@
58
#define SBI_EXT_IPI 0x735049
59
#define SBI_EXT_RFENCE 0x52464E43
60
#define SBI_EXT_HSM 0x48534D
61
+#define SBI_EXT_DBCN 0x4442434E
62
63
/* SBI function IDs for BASE extension */
64
#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
65
@@ -XXX,XX +XXX,XX @@
66
#define SBI_EXT_HSM_HART_STOP 0x1
67
#define SBI_EXT_HSM_HART_GET_STATUS 0x2
68
69
+/* SBI function IDs for DBCN extension */
70
+#define SBI_EXT_DBCN_CONSOLE_WRITE 0x0
71
+#define SBI_EXT_DBCN_CONSOLE_READ 0x1
72
+#define SBI_EXT_DBCN_CONSOLE_WRITE_BYTE 0x2
73
+
74
#define SBI_HSM_HART_STATUS_STARTED 0x0
75
#define SBI_HSM_HART_STATUS_STOPPED 0x1
76
#define SBI_HSM_HART_STATUS_START_PENDING 0x2
77
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/target/riscv/kvm/kvm-cpu.c
80
+++ b/target/riscv/kvm/kvm-cpu.c
81
@@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_v_vlenb = {
82
KVM_REG_RISCV_VECTOR_CSR_REG(vlenb)
83
};
84
85
+static KVMCPUConfig kvm_sbi_dbcn = {
86
+ .name = "sbi_dbcn",
87
+ .kvm_reg_id = KVM_REG_RISCV | KVM_REG_SIZE_U64 |
88
+ KVM_REG_RISCV_SBI_EXT | KVM_RISCV_SBI_EXT_DBCN
89
+};
90
+
91
static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
92
{
93
CPURISCVState *env = &cpu->env;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
95
return 0;
96
}
97
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
99
+ KVMScratchCPU *kvmcpu,
100
+ struct kvm_reg_list *reglist)
101
+{
102
+ struct kvm_reg_list *reg_search;
103
+
104
+ reg_search = bsearch(&kvm_sbi_dbcn.kvm_reg_id, reglist->reg, reglist->n,
105
+ sizeof(uint64_t), uint64_cmp);
106
+
107
+ if (reg_search) {
108
+ kvm_sbi_dbcn.supported = true;
109
+ }
110
+}
111
+
112
static void kvm_riscv_read_vlenb(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
113
struct kvm_reg_list *reglist)
114
{
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
116
if (riscv_has_ext(&cpu->env, RVV)) {
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
118
}
119
+
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
121
}
122
123
static void riscv_init_kvm_registers(Object *cpu_obj)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
125
return ret;
126
}
127
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
129
+{
130
+ target_ulong reg = 1;
131
+
132
+ if (!kvm_sbi_dbcn.supported) {
133
+ return 0;
134
+ }
135
+
136
+ return kvm_set_one_reg(cs, kvm_sbi_dbcn.kvm_reg_id, &reg);
137
+}
138
+
139
int kvm_arch_init_vcpu(CPUState *cs)
140
{
141
int ret = 0;
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
145
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
147
+
148
return ret;
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;
223
+ default:
224
+ run->riscv_sbi.ret[0] = SBI_ERR_NOT_SUPPORTED;
225
+ }
226
+}
227
+
228
static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
229
{
230
int ret = 0;
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
232
}
233
ret = 0;
234
break;
235
+ case SBI_EXT_DBCN:
236
+ kvm_riscv_handle_sbi_dbcn(cs, run);
237
+ break;
238
default:
239
qemu_log_mask(LOG_UNIMP,
240
"%s: un-handled SBI EXIT, specific reasons is %lu\n",
241
--
242
2.45.1
diff view generated by jsdifflib
1
From: Atish Patra <atish.patra@wdc.com>
1
From: Cheng Yang <yangcheng.work@foxmail.com>
2
2
3
Even though the start address in ROM code is declared as a 64 bit address
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
4
for RV64, it can't be used as upper bits are set to zero in ROM code.
4
to set the address of initrd in FDT to support 64-bit address.
5
5
6
Update the ROM code correctly to reflect the 64bit value.
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
7
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Atish Patra <atish.patra@wdc.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
9
Reviewed-by: Bin Meng <bin.meng@windriver.com>
10
Tested-by: Bin Meng <bin.meng@windriver.com>
11
Message-Id: <20200701183949.398134-5-atish.patra@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
10
---
14
hw/riscv/boot.c | 6 +++++-
11
hw/riscv/boot.c | 4 ++--
15
hw/riscv/sifive_u.c | 6 +++++-
12
1 file changed, 2 insertions(+), 2 deletions(-)
16
2 files changed, 10 insertions(+), 2 deletions(-)
17
13
18
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
19
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/riscv/boot.c
16
--- a/hw/riscv/boot.c
21
+++ b/hw/riscv/boot.c
17
+++ b/hw/riscv/boot.c
22
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
23
uint32_t fdt_load_addr, void *fdt)
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
24
{
20
if (fdt) {
25
int i;
21
end = start + size;
26
+ uint32_t start_addr_hi32 = 0x00000000;
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
27
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
28
+ #if defined(TARGET_RISCV64)
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
29
+ start_addr_hi32 = start_addr >> 32;
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
30
+ #endif
26
}
31
/* reset vector */
27
}
32
uint32_t reset_vec[10] = {
28
33
0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
34
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
35
#endif
36
0x00028067, /* jr t0 */
37
start_addr, /* start: .dword */
38
- 0x00000000,
39
+ start_addr_hi32,
40
fdt_load_addr, /* fdt_laddr: .dword */
41
0x00000000,
42
/* fw_dyn: */
43
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/riscv/sifive_u.c
46
+++ b/hw/riscv/sifive_u.c
47
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
48
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
49
MemoryRegion *flash0 = g_new(MemoryRegion, 1);
50
target_ulong start_addr = memmap[SIFIVE_U_DRAM].base;
51
+ uint32_t start_addr_hi32 = 0x00000000;
52
int i;
53
uint32_t fdt_load_addr;
54
uint64_t kernel_entry;
55
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
56
/* Compute the fdt load address in dram */
57
fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DRAM].base,
58
machine->ram_size, s->fdt);
59
+ #if defined(TARGET_RISCV64)
60
+ start_addr_hi32 = start_addr >> 32;
61
+ #endif
62
63
/* reset vector */
64
uint32_t reset_vec[11] = {
65
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
66
#endif
67
0x00028067, /* jr t0 */
68
start_addr, /* start: .dword */
69
- 0x00000000,
70
+ start_addr_hi32,
71
fdt_load_addr, /* fdt_laddr: .dword */
72
0x00000000,
73
/* fw_dyn: */
74
--
29
--
75
2.27.0
30
2.45.1
76
77
diff view generated by jsdifflib
1
From: Alexandre Mergnat <amergnat@baylibre.com>
1
From: Clément Léger <cleger@rivosinc.com>
2
2
3
The end address calculation for NA4 mode is wrong because the address
3
The current semihost exception number (16) is a reserved number (range
4
used isn't shifted.
4
[16-17]). The upcoming double trap specification uses that number for
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.
5
9
6
It doesn't watch 4 bytes but a huge range because the end address
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
7
calculation is wrong.
8
11
9
The solution is to use the shifted address calculated for start address
10
variable.
11
12
Modifications are tested on Zephyr OS userspace test suite which works
13
for other RISC-V boards (E31 and E34 core).
14
15
Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-id: 20200706084550.24117-1-amergnat@baylibre.com
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
18
Message-Id: <20200706084550.24117-1-amergnat@baylibre.com>
19
[ Changes by AF:
20
- Improve the commit title and message
21
]
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
15
---
24
target/riscv/pmp.c | 2 +-
16
target/riscv/cpu_bits.h | 2 +-
25
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
26
18
27
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
28
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
29
--- a/target/riscv/pmp.c
21
--- a/target/riscv/cpu_bits.h
30
+++ b/target/riscv/pmp.c
22
+++ b/target/riscv/cpu_bits.h
31
@@ -XXX,XX +XXX,XX @@ static void pmp_update_rule(CPURISCVState *env, uint32_t pmp_index)
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
32
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
33
case PMP_AMATCH_NA4:
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
34
sa = this_addr << 2; /* shift up from [xx:0] to [xx+2:2] */
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
35
- ea = (this_addr + 4u) - 1u;
27
- RISCV_EXCP_SEMIHOST = 0x10,
36
+ ea = (sa + 4u) - 1u;
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
37
break;
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
38
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
39
case PMP_AMATCH_NAPOT:
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
33
} RISCVException;
34
35
#define RISCV_EXCP_INT_FLAG 0x80000000
40
--
36
--
41
2.27.0
37
2.45.1
42
38
43
39
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
4
enabled, will fail with a kernel oops SIGILL right at the start. The
5
reason is that we can't expose zkr without implementing the SEED CSR.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
8
9
In hindsight this is too strict. If we keep proceeding, despite not
10
disabling the extension in the KVM vcpu, we'll not add the extension in
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
14
15
Change our current logic to not error out if we fail to disable an
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
17
is important to throw a warning because we must make the user aware that
18
the extension is still available in the vcpu, meaning that an
19
ill-behaved guest can ignore the riscv,isa settings and use the
20
extension.
21
22
The case we're handling happens with an EINVAL error code. If we fail to
23
disable the extension in KVM for any other reason, error out.
24
25
We'll also keep erroring out when we fail to enable an extension in KVM,
26
since adding the extension in riscv,isa at this point will cause a guest
27
malfunction because the extension isn't enabled in the vcpu.
28
29
Suggested-by: Andrew Jones <ajones@ventanamicro.com>
30
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
31
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Message-ID: <20240422171425.333037-2-dbarboza@ventanamicro.com>
34
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
37
1 file changed, 8 insertions(+), 4 deletions(-)
38
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
42
+++ b/target/riscv/kvm/kvm-cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
45
ret = kvm_set_one_reg(cs, id, &reg);
46
if (ret != 0) {
47
- error_report("Unable to %s extension %s in KVM, error %d",
48
- reg ? "enable" : "disable",
49
- multi_ext_cfg->name, ret);
50
- exit(EXIT_FAILURE);
51
+ if (!reg && ret == -EINVAL) {
52
+ warn_report("KVM cannot disable extension %s",
53
+ multi_ext_cfg->name);
54
+ } else {
55
+ error_report("Unable to enable extension %s in KVM, error %d",
56
+ multi_ext_cfg->name, ret);
57
+ exit(EXIT_FAILURE);
58
+ }
59
}
60
}
61
}
62
--
63
2.45.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
We're not setting (s/m)tval when triggering breakpoints of type 2
4
(mcontrol) and 6 (mcontrol6). According to the debug spec section
5
5.7.12, "Match Control Type 6":
6
7
"The Privileged Spec says that breakpoint exceptions that occur on
8
instruction fetches, loads, or stores update the tval CSR with either
9
zero or the faulting virtual address. The faulting virtual address for
10
an mcontrol6 trigger with action = 0 is the address being accessed and
11
which caused that trigger to fire."
12
13
A similar text is also found in the Debug spec section 5.7.11 w.r.t.
14
mcontrol.
15
16
Note that what we're doing ATM is not violating the spec, but it's
17
simple enough to set mtval/stval and it makes life easier for any
18
software that relies on this info.
19
20
Given that we always use action = 0, save the faulting address for the
21
mcontrol and mcontrol6 trigger breakpoints into env->badaddr, which is
22
used as as scratch area for traps with address information. 'tval' is
23
then set during riscv_cpu_do_interrupt().
24
25
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
26
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
27
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
28
Message-ID: <20240416230437.1869024-2-dbarboza@ventanamicro.com>
29
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
31
target/riscv/cpu_helper.c | 1 +
32
target/riscv/debug.c | 3 +++
33
2 files changed, 4 insertions(+)
34
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
40
tval = env->bins;
41
break;
42
case RISCV_EXCP_BREAKPOINT:
43
+ tval = env->badaddr;
44
if (cs->watchpoint_hit) {
45
tval = cs->watchpoint_hit->hitaddr;
46
cs->watchpoint_hit = NULL;
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/debug.c
50
+++ b/target/riscv/debug.c
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
53
/* check U/S/M bit against current privilege level */
54
if ((ctrl >> 3) & BIT(env->priv)) {
55
+ env->badaddr = pc;
56
return true;
57
}
58
}
59
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
60
if (env->virt_enabled) {
61
/* check VU/VS bit against current privilege level */
62
if ((ctrl >> 23) & BIT(env->priv)) {
63
+ env->badaddr = pc;
64
return true;
65
}
66
} else {
67
/* check U/S/M bit against current privilege level */
68
if ((ctrl >> 3) & BIT(env->priv)) {
69
+ env->badaddr = pc;
70
return true;
71
}
72
}
73
--
74
2.45.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Privileged spec section 4.1.9 mentions:
4
5
"When a trap is taken into S-mode, stval is written with
6
exception-specific information to assist software in handling the trap.
7
(...)
8
9
If stval is written with a nonzero value when a breakpoint,
10
address-misaligned, access-fault, or page-fault exception occurs on an
11
instruction fetch, load, or store, then stval will contain the faulting
12
virtual address."
13
14
A similar text is found for mtval in section 3.1.16.
15
16
Setting mtval/stval in this scenario is optional, but some softwares read
17
these regs when handling ebreaks.
18
19
Write 'badaddr' in all ebreak breakpoints to write the appropriate
20
'tval' during riscv_do_cpu_interrrupt().
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
30
1 file changed, 2 insertions(+)
31
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
39
} else {
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
41
+ offsetof(CPURISCVState, badaddr));
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
43
}
44
return true;
45
--
46
2.45.1
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
Add support for Zve32x extension and replace some checks for Zve32f with
4
Zve32x, since Zve32f depends on Zve32x.
5
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Max Chou <max.chou@sifive.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20240328022343.6871-2-jason.chien@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu_cfg.h | 1 +
14
target/riscv/cpu.c | 2 ++
15
target/riscv/cpu_helper.c | 2 +-
16
target/riscv/csr.c | 2 +-
17
target/riscv/tcg/tcg-cpu.c | 16 ++++++++--------
18
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
19
6 files changed, 15 insertions(+), 12 deletions(-)
20
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_cfg.h
24
+++ b/target/riscv/cpu_cfg.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_zhinx;
27
bool ext_zhinxmin;
28
bool ext_zve32f;
29
+ bool ext_zve32x;
30
bool ext_zve64f;
31
bool ext_zve64d;
32
bool ext_zvbb;
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
45
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
46
MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false),
47
MULTI_EXT_CFG_BOOL("zfhmin", ext_zfhmin, false),
48
MULTI_EXT_CFG_BOOL("zve32f", ext_zve32f, false),
49
+ MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
50
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
51
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
52
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
53
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/riscv/cpu_helper.c
56
+++ b/target/riscv/cpu_helper.c
57
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
58
*pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
59
*cs_base = 0;
60
61
- if (cpu->cfg.ext_zve32f) {
62
+ if (cpu->cfg.ext_zve32x) {
63
/*
64
* If env->vl equals to VLMAX, we can use generic vector operation
65
* expanders (GVEC) to accerlate the vector operations.
66
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
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
{
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
76
#if !defined(CONFIG_USER_ONLY)
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
}
86
87
- if (cpu->cfg.ext_zve32f && !riscv_has_ext(env, RVF)) {
88
- error_setg(errp, "Zve32f/Zve64f extensions require F extension");
89
- return;
90
+ /* The Zve32f extension depends on the Zve32x extension */
91
+ if (cpu->cfg.ext_zve32f) {
92
+ if (!riscv_has_ext(env, RVF)) {
93
+ error_setg(errp, "Zve32f/Zve64f extensions require F extension");
94
+ return;
95
+ }
96
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
97
}
98
99
if (cpu->cfg.ext_zvfh) {
100
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
101
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zvbc), true);
102
}
103
104
- /*
105
- * In principle Zve*x would also suffice here, were they supported
106
- * in qemu
107
- */
108
if ((cpu->cfg.ext_zvbb || cpu->cfg.ext_zvkb || cpu->cfg.ext_zvkg ||
109
cpu->cfg.ext_zvkned || cpu->cfg.ext_zvknha || cpu->cfg.ext_zvksed ||
110
- cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32f) {
111
+ cpu->cfg.ext_zvksh) && !cpu->cfg.ext_zve32x) {
112
error_setg(errp,
113
"Vector crypto extensions require V or Zve* extensions");
114
return;
115
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
116
index XXXXXXX..XXXXXXX 100644
117
--- a/target/riscv/insn_trans/trans_rvv.c.inc
118
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
119
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
120
{
121
TCGv s1, dst;
122
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
125
return false;
126
}
127
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
129
{
130
TCGv dst;
131
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
134
return false;
135
}
136
137
--
138
2.45.1
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
2
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
4
enabling Zve64x enables Zve32x according to their dependency.
5
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Message-id: 06372c9cdeec715077899e71c858d9f0a2a3395b.1594332223.git.alistair.francis@wdc.com
3
Message-Id: <06372c9cdeec715077899e71c858d9f0a2a3395b.1594332223.git.alistair.francis@wdc.com>
4
---
13
---
5
include/hw/char/ibex_uart.h | 76 ++++++++++-----------
14
target/riscv/cpu_cfg.h | 1 +
6
hw/char/ibex_uart.c | 130 ++++++++++++++++++------------------
15
target/riscv/cpu.c | 2 ++
7
2 files changed, 100 insertions(+), 106 deletions(-)
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
17
3 files changed, 14 insertions(+), 6 deletions(-)
8
18
9
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
10
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/char/ibex_uart.h
21
--- a/target/riscv/cpu_cfg.h
12
+++ b/include/hw/char/ibex_uart.h
22
+++ b/target/riscv/cpu_cfg.h
13
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
14
#define HW_IBEX_UART_H
24
bool ext_zve32x;
15
25
bool ext_zve64f;
16
#include "hw/sysbus.h"
26
bool ext_zve64d;
17
+#include "hw/registerfields.h"
27
+ bool ext_zve64x;
18
#include "chardev/char-fe.h"
28
bool ext_zvbb;
19
#include "qemu/timer.h"
29
bool ext_zvbc;
20
30
bool ext_zvkb;
21
-#define IBEX_UART_INTR_STATE 0x00
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
22
- #define INTR_STATE_TX_WATERMARK (1 << 0)
23
- #define INTR_STATE_RX_WATERMARK (1 << 1)
24
- #define INTR_STATE_TX_EMPTY (1 << 2)
25
- #define INTR_STATE_RX_OVERFLOW (1 << 3)
26
-#define IBEX_UART_INTR_ENABLE 0x04
27
-#define IBEX_UART_INTR_TEST 0x08
28
-
29
-#define IBEX_UART_CTRL 0x0c
30
- #define UART_CTRL_TX_ENABLE (1 << 0)
31
- #define UART_CTRL_RX_ENABLE (1 << 1)
32
- #define UART_CTRL_NF (1 << 2)
33
- #define UART_CTRL_SLPBK (1 << 4)
34
- #define UART_CTRL_LLPBK (1 << 5)
35
- #define UART_CTRL_PARITY_EN (1 << 6)
36
- #define UART_CTRL_PARITY_ODD (1 << 7)
37
- #define UART_CTRL_RXBLVL (3 << 8)
38
- #define UART_CTRL_NCO (0xFFFF << 16)
39
-
40
-#define IBEX_UART_STATUS 0x10
41
- #define UART_STATUS_TXFULL (1 << 0)
42
- #define UART_STATUS_RXFULL (1 << 1)
43
- #define UART_STATUS_TXEMPTY (1 << 2)
44
- #define UART_STATUS_RXIDLE (1 << 4)
45
- #define UART_STATUS_RXEMPTY (1 << 5)
46
-
47
-#define IBEX_UART_RDATA 0x14
48
-#define IBEX_UART_WDATA 0x18
49
-
50
-#define IBEX_UART_FIFO_CTRL 0x1c
51
- #define FIFO_CTRL_RXRST (1 << 0)
52
- #define FIFO_CTRL_TXRST (1 << 1)
53
- #define FIFO_CTRL_RXILVL (7 << 2)
54
- #define FIFO_CTRL_RXILVL_SHIFT (2)
55
- #define FIFO_CTRL_TXILVL (3 << 5)
56
- #define FIFO_CTRL_TXILVL_SHIFT (5)
57
-
58
-#define IBEX_UART_FIFO_STATUS 0x20
59
-#define IBEX_UART_OVRD 0x24
60
-#define IBEX_UART_VAL 0x28
61
-#define IBEX_UART_TIMEOUT_CTRL 0x2c
62
+REG32(INTR_STATE, 0x00)
63
+ FIELD(INTR_STATE, TX_WATERMARK, 0, 1)
64
+ FIELD(INTR_STATE, RX_WATERMARK, 1, 1)
65
+ FIELD(INTR_STATE, TX_EMPTY, 2, 1)
66
+ FIELD(INTR_STATE, RX_OVERFLOW, 3, 1)
67
+REG32(INTR_ENABLE, 0x04)
68
+REG32(INTR_TEST, 0x08)
69
+REG32(CTRL, 0x0C)
70
+ FIELD(CTRL, TX_ENABLE, 0, 1)
71
+ FIELD(CTRL, RX_ENABLE, 1, 1)
72
+ FIELD(CTRL, NF, 2, 1)
73
+ FIELD(CTRL, SLPBK, 4, 1)
74
+ FIELD(CTRL, LLPBK, 5, 1)
75
+ FIELD(CTRL, PARITY_EN, 6, 1)
76
+ FIELD(CTRL, PARITY_ODD, 7, 1)
77
+ FIELD(CTRL, RXBLVL, 8, 2)
78
+ FIELD(CTRL, NCO, 16, 16)
79
+REG32(STATUS, 0x10)
80
+ FIELD(STATUS, TXFULL, 0, 1)
81
+ FIELD(STATUS, RXFULL, 1, 1)
82
+ FIELD(STATUS, TXEMPTY, 2, 1)
83
+ FIELD(STATUS, RXIDLE, 4, 1)
84
+ FIELD(STATUS, RXEMPTY, 5, 1)
85
+REG32(RDATA, 0x14)
86
+REG32(WDATA, 0x18)
87
+REG32(FIFO_CTRL, 0x1c)
88
+ FIELD(FIFO_CTRL, RXRST, 0, 1)
89
+ FIELD(FIFO_CTRL, TXRST, 1, 1)
90
+ FIELD(FIFO_CTRL, RXILVL, 2, 3)
91
+ FIELD(FIFO_CTRL, TXILVL, 5, 2)
92
+REG32(FIFO_STATUS, 0x20)
93
+REG32(OVRD, 0x24)
94
+REG32(VAL, 0x28)
95
+REG32(TIMEOUT_CTRL, 0x2c)
96
97
#define IBEX_UART_TX_FIFO_SIZE 16
98
#define IBEX_UART_CLOCK 50000000 /* 50MHz clock */
99
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
100
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/char/ibex_uart.c
33
--- a/target/riscv/cpu.c
102
+++ b/hw/char/ibex_uart.c
34
+++ b/target/riscv/cpu.c
103
@@ -XXX,XX +XXX,XX @@
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
104
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
105
static void ibex_uart_update_irqs(IbexUartState *s)
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
106
{
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
107
- if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_WATERMARK) {
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
108
+ if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_TX_WATERMARK_MASK) {
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
109
qemu_set_irq(s->tx_watermark, 1);
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
110
} else {
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
111
qemu_set_irq(s->tx_watermark, 0);
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);
112
}
64
}
113
65
114
- if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_WATERMARK) {
66
- /* The Zve64f extension depends on the Zve32f extension */
115
+ if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_RX_WATERMARK_MASK) {
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
116
qemu_set_irq(s->rx_watermark, 1);
68
if (cpu->cfg.ext_zve64f) {
117
} else {
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
118
qemu_set_irq(s->rx_watermark, 0);
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
119
}
71
}
120
72
121
- if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_EMPTY) {
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
122
+ if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_TX_EMPTY_MASK) {
74
- error_setg(errp, "Zve64d/V extensions require D extension");
123
qemu_set_irq(s->tx_empty, 1);
75
- return;
124
} else {
76
+ /* The Zve64x extension depends on the Zve32x extension */
125
qemu_set_irq(s->tx_empty, 0);
77
+ if (cpu->cfg.ext_zve64x) {
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
126
}
79
}
127
80
128
- if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_OVERFLOW) {
81
/* The Zve32f extension depends on the Zve32x extension */
129
+ if (s->uart_intr_state & s->uart_intr_enable & R_INTR_STATE_RX_OVERFLOW_MASK) {
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
130
qemu_set_irq(s->rx_overflow, 1);
83
return;
131
} else {
132
qemu_set_irq(s->rx_overflow, 0);
133
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
134
{
135
IbexUartState *s = opaque;
136
137
- if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
138
+ if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
139
return 1;
140
}
84
}
141
85
142
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
143
static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
144
{
88
error_setg(
145
IbexUartState *s = opaque;
89
errp,
146
- uint8_t rx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_RXILVL)
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
147
- >> FIFO_CTRL_RXILVL_SHIFT;
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
148
+ uint8_t rx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_RXILVL_MASK)
92
return;
149
+ >> R_FIFO_CTRL_RXILVL_SHIFT;
150
151
s->uart_rdata = *buf;
152
153
- s->uart_status &= ~UART_STATUS_RXIDLE;
154
- s->uart_status &= ~UART_STATUS_RXEMPTY;
155
+ s->uart_status &= ~R_STATUS_RXIDLE_MASK;
156
+ s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
157
158
if (size > rx_fifo_level) {
159
- s->uart_intr_state |= INTR_STATE_RX_WATERMARK;
160
+ s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
161
}
93
}
162
94
163
ibex_uart_update_irqs(s);
164
@@ -XXX,XX +XXX,XX @@ static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond,
165
void *opaque)
166
{
167
IbexUartState *s = opaque;
168
- uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
169
- >> FIFO_CTRL_TXILVL_SHIFT;
170
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_TXILVL_MASK)
171
+ >> R_FIFO_CTRL_TXILVL_SHIFT;
172
int ret;
173
174
/* instant drain the fifo when there's no back-end */
175
@@ -XXX,XX +XXX,XX @@ static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond,
176
}
177
178
if (!s->tx_level) {
179
- s->uart_status &= ~UART_STATUS_TXFULL;
180
- s->uart_status |= UART_STATUS_TXEMPTY;
181
- s->uart_intr_state |= INTR_STATE_TX_EMPTY;
182
- s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
183
+ s->uart_status &= ~R_STATUS_TXFULL_MASK;
184
+ s->uart_status |= R_STATUS_TXEMPTY_MASK;
185
+ s->uart_intr_state |= R_INTR_STATE_TX_EMPTY_MASK;
186
+ s->uart_intr_state &= ~R_INTR_STATE_TX_WATERMARK_MASK;
187
ibex_uart_update_irqs(s);
188
return FALSE;
189
}
190
@@ -XXX,XX +XXX,XX @@ static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond,
191
192
/* Clear the TX Full bit */
193
if (s->tx_level != IBEX_UART_TX_FIFO_SIZE) {
194
- s->uart_status &= ~UART_STATUS_TXFULL;
195
+ s->uart_status &= ~R_STATUS_TXFULL_MASK;
196
}
197
198
/* Disable the TX_WATERMARK IRQ */
199
if (s->tx_level < tx_fifo_level) {
200
- s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
201
+ s->uart_intr_state &= ~R_INTR_STATE_TX_WATERMARK_MASK;
202
}
203
204
/* Set TX empty */
205
if (s->tx_level == 0) {
206
- s->uart_status |= UART_STATUS_TXEMPTY;
207
- s->uart_intr_state |= INTR_STATE_TX_EMPTY;
208
+ s->uart_status |= R_STATUS_TXEMPTY_MASK;
209
+ s->uart_intr_state |= R_INTR_STATE_TX_EMPTY_MASK;
210
}
211
212
ibex_uart_update_irqs(s);
213
@@ -XXX,XX +XXX,XX @@ static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
214
int size)
215
{
216
uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
217
- uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
218
- >> FIFO_CTRL_TXILVL_SHIFT;
219
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & R_FIFO_CTRL_TXILVL_MASK)
220
+ >> R_FIFO_CTRL_TXILVL_SHIFT;
221
222
if (size > IBEX_UART_TX_FIFO_SIZE - s->tx_level) {
223
size = IBEX_UART_TX_FIFO_SIZE - s->tx_level;
224
@@ -XXX,XX +XXX,XX @@ static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
225
s->tx_level += size;
226
227
if (s->tx_level > 0) {
228
- s->uart_status &= ~UART_STATUS_TXEMPTY;
229
+ s->uart_status &= ~R_STATUS_TXEMPTY_MASK;
230
}
231
232
if (s->tx_level >= tx_fifo_level) {
233
- s->uart_intr_state |= INTR_STATE_TX_WATERMARK;
234
+ s->uart_intr_state |= R_INTR_STATE_TX_WATERMARK_MASK;
235
ibex_uart_update_irqs(s);
236
}
237
238
if (s->tx_level == IBEX_UART_TX_FIFO_SIZE) {
239
- s->uart_status |= UART_STATUS_TXFULL;
240
+ s->uart_status |= R_STATUS_TXFULL_MASK;
241
}
242
243
timer_mod(s->fifo_trigger_handle, current_time +
244
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_get_baud(IbexUartState *s)
245
{
246
uint64_t baud;
247
248
- baud = ((s->uart_ctrl & UART_CTRL_NCO) >> 16);
249
+ baud = ((s->uart_ctrl & R_CTRL_NCO_MASK) >> 16);
250
baud *= clock_get_hz(s->f_clk);
251
baud >>= 20;
252
253
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
254
IbexUartState *s = opaque;
255
uint64_t retvalue = 0;
256
257
- switch (addr) {
258
- case IBEX_UART_INTR_STATE:
259
+ switch (addr >> 2) {
260
+ case R_INTR_STATE:
261
retvalue = s->uart_intr_state;
262
break;
263
- case IBEX_UART_INTR_ENABLE:
264
+ case R_INTR_ENABLE:
265
retvalue = s->uart_intr_enable;
266
break;
267
- case IBEX_UART_INTR_TEST:
268
+ case R_INTR_TEST:
269
qemu_log_mask(LOG_GUEST_ERROR,
270
"%s: wdata is write only\n", __func__);
271
break;
272
273
- case IBEX_UART_CTRL:
274
+ case R_CTRL:
275
retvalue = s->uart_ctrl;
276
break;
277
- case IBEX_UART_STATUS:
278
+ case R_STATUS:
279
retvalue = s->uart_status;
280
break;
281
282
- case IBEX_UART_RDATA:
283
+ case R_RDATA:
284
retvalue = s->uart_rdata;
285
- if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
286
+ if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
287
qemu_chr_fe_accept_input(&s->chr);
288
289
- s->uart_status |= UART_STATUS_RXIDLE;
290
- s->uart_status |= UART_STATUS_RXEMPTY;
291
+ s->uart_status |= R_STATUS_RXIDLE_MASK;
292
+ s->uart_status |= R_STATUS_RXEMPTY_MASK;
293
}
294
break;
295
- case IBEX_UART_WDATA:
296
+ case R_WDATA:
297
qemu_log_mask(LOG_GUEST_ERROR,
298
"%s: wdata is write only\n", __func__);
299
break;
300
301
- case IBEX_UART_FIFO_CTRL:
302
+ case R_FIFO_CTRL:
303
retvalue = s->uart_fifo_ctrl;
304
break;
305
- case IBEX_UART_FIFO_STATUS:
306
+ case R_FIFO_STATUS:
307
retvalue = s->uart_fifo_status;
308
309
retvalue |= s->tx_level & 0x1F;
310
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
311
"%s: RX fifos are not supported\n", __func__);
312
break;
313
314
- case IBEX_UART_OVRD:
315
+ case R_OVRD:
316
retvalue = s->uart_ovrd;
317
qemu_log_mask(LOG_UNIMP,
318
"%s: ovrd is not supported\n", __func__);
319
break;
320
- case IBEX_UART_VAL:
321
+ case R_VAL:
322
retvalue = s->uart_val;
323
qemu_log_mask(LOG_UNIMP,
324
"%s: val is not supported\n", __func__);
325
break;
326
- case IBEX_UART_TIMEOUT_CTRL:
327
+ case R_TIMEOUT_CTRL:
328
retvalue = s->uart_timeout_ctrl;
329
qemu_log_mask(LOG_UNIMP,
330
"%s: timeout_ctrl is not supported\n", __func__);
331
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
332
IbexUartState *s = opaque;
333
uint32_t value = val64;
334
335
- switch (addr) {
336
- case IBEX_UART_INTR_STATE:
337
+ switch (addr >> 2) {
338
+ case R_INTR_STATE:
339
/* Write 1 clear */
340
s->uart_intr_state &= ~value;
341
ibex_uart_update_irqs(s);
342
break;
343
- case IBEX_UART_INTR_ENABLE:
344
+ case R_INTR_ENABLE:
345
s->uart_intr_enable = value;
346
ibex_uart_update_irqs(s);
347
break;
348
- case IBEX_UART_INTR_TEST:
349
+ case R_INTR_TEST:
350
s->uart_intr_state |= value;
351
ibex_uart_update_irqs(s);
352
break;
353
354
- case IBEX_UART_CTRL:
355
+ case R_CTRL:
356
s->uart_ctrl = value;
357
358
- if (value & UART_CTRL_NF) {
359
+ if (value & R_CTRL_NF_MASK) {
360
qemu_log_mask(LOG_UNIMP,
361
"%s: UART_CTRL_NF is not supported\n", __func__);
362
}
363
- if (value & UART_CTRL_SLPBK) {
364
+ if (value & R_CTRL_SLPBK_MASK) {
365
qemu_log_mask(LOG_UNIMP,
366
"%s: UART_CTRL_SLPBK is not supported\n", __func__);
367
}
368
- if (value & UART_CTRL_LLPBK) {
369
+ if (value & R_CTRL_LLPBK_MASK) {
370
qemu_log_mask(LOG_UNIMP,
371
"%s: UART_CTRL_LLPBK is not supported\n", __func__);
372
}
373
- if (value & UART_CTRL_PARITY_EN) {
374
+ if (value & R_CTRL_PARITY_EN_MASK) {
375
qemu_log_mask(LOG_UNIMP,
376
"%s: UART_CTRL_PARITY_EN is not supported\n",
377
__func__);
378
}
379
- if (value & UART_CTRL_PARITY_ODD) {
380
+ if (value & R_CTRL_PARITY_ODD_MASK) {
381
qemu_log_mask(LOG_UNIMP,
382
"%s: UART_CTRL_PARITY_ODD is not supported\n",
383
__func__);
384
}
385
- if (value & UART_CTRL_RXBLVL) {
386
+ if (value & R_CTRL_RXBLVL_MASK) {
387
qemu_log_mask(LOG_UNIMP,
388
"%s: UART_CTRL_RXBLVL is not supported\n", __func__);
389
}
390
- if (value & UART_CTRL_NCO) {
391
+ if (value & R_CTRL_NCO_MASK) {
392
uint64_t baud = ibex_uart_get_baud(s);
393
394
s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
395
}
396
break;
397
- case IBEX_UART_STATUS:
398
+ case R_STATUS:
399
qemu_log_mask(LOG_GUEST_ERROR,
400
"%s: status is read only\n", __func__);
401
break;
402
403
- case IBEX_UART_RDATA:
404
+ case R_RDATA:
405
qemu_log_mask(LOG_GUEST_ERROR,
406
"%s: rdata is read only\n", __func__);
407
break;
408
- case IBEX_UART_WDATA:
409
+ case R_WDATA:
410
uart_write_tx_fifo(s, (uint8_t *) &value, 1);
411
break;
412
413
- case IBEX_UART_FIFO_CTRL:
414
+ case R_FIFO_CTRL:
415
s->uart_fifo_ctrl = value;
416
417
- if (value & FIFO_CTRL_RXRST) {
418
+ if (value & R_FIFO_CTRL_RXRST_MASK) {
419
qemu_log_mask(LOG_UNIMP,
420
"%s: RX fifos are not supported\n", __func__);
421
}
422
- if (value & FIFO_CTRL_TXRST) {
423
+ if (value & R_FIFO_CTRL_TXRST_MASK) {
424
s->tx_level = 0;
425
}
426
break;
427
- case IBEX_UART_FIFO_STATUS:
428
+ case R_FIFO_STATUS:
429
qemu_log_mask(LOG_GUEST_ERROR,
430
"%s: fifo_status is read only\n", __func__);
431
break;
432
433
- case IBEX_UART_OVRD:
434
+ case R_OVRD:
435
s->uart_ovrd = value;
436
qemu_log_mask(LOG_UNIMP,
437
"%s: ovrd is not supported\n", __func__);
438
break;
439
- case IBEX_UART_VAL:
440
+ case R_VAL:
441
qemu_log_mask(LOG_GUEST_ERROR,
442
"%s: val is read only\n", __func__);
443
break;
444
- case IBEX_UART_TIMEOUT_CTRL:
445
+ case R_TIMEOUT_CTRL:
446
s->uart_timeout_ctrl = value;
447
qemu_log_mask(LOG_UNIMP,
448
"%s: timeout_ctrl is not supported\n", __func__);
449
@@ -XXX,XX +XXX,XX @@ static void fifo_trigger_update(void *opaque)
450
{
451
IbexUartState *s = opaque;
452
453
- if (s->uart_ctrl & UART_CTRL_TX_ENABLE) {
454
+ if (s->uart_ctrl & R_CTRL_TX_ENABLE_MASK) {
455
ibex_uart_xmit(NULL, G_IO_OUT, s);
456
}
457
}
458
--
95
--
459
2.27.0
96
2.45.1
460
461
diff view generated by jsdifflib
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
In current implementation, the gdbstub allows reading vector registers
4
only if V extension is supported. However, all vector extensions and
5
vector crypto extensions have the vector registers and they all depend
6
on Zve32x. The gdbstub should check for Zve32x instead.
7
8
Signed-off-by: Jason Chien <jason.chien@sifive.com>
9
Reviewed-by: Frank Chang <frank.chang@sifive.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Message-ID: <20240328022343.6871-4-jason.chien@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/gdbstub.c | 2 +-
15
1 file changed, 1 insertion(+), 1 deletion(-)
16
17
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/gdbstub.c
20
+++ b/target/riscv/gdbstub.c
21
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
22
gdb_find_static_feature("riscv-32bit-fpu.xml"),
23
0);
24
}
25
- if (env->misa_ext & RVV) {
26
+ if (cpu->cfg.ext_zve32x) {
27
gdb_register_coprocessor(cs, riscv_gdb_get_vector,
28
riscv_gdb_set_vector,
29
ricsv_gen_dynamic_vector_feature(cs, cs->gdb_num_regs),
30
--
31
2.45.1
diff view generated by jsdifflib
New patch
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
2
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
5
agnostic policy.
6
7
However, this function can't deal the big endian situation. This patch fixes
8
the problem by adding handling of such case.
9
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
18
1 file changed, 22 insertions(+)
19
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/vector_internals.c
23
+++ b/target/riscv/vector_internals.c
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
25
if (tot - cnt == 0) {
26
return ;
27
}
28
+
29
+ if (HOST_BIG_ENDIAN) {
30
+ /*
31
+ * Deal the situation when the elements are insdie
32
+ * only one uint64 block including setting the
33
+ * masked-off element.
34
+ */
35
+ if (((tot - 1) ^ cnt) < 8) {
36
+ memset(base + H1(tot - 1), -1, tot - cnt);
37
+ return;
38
+ }
39
+ /*
40
+ * Otherwise, at least cross two uint64_t blocks.
41
+ * Set first unaligned block.
42
+ */
43
+ if (cnt % 8 != 0) {
44
+ uint32_t j = ROUND_UP(cnt, 8);
45
+ memset(base + H1(j - 1), -1, j - cnt);
46
+ cnt = j;
47
+ }
48
+ /* Set other 64bit aligend blocks */
49
+ }
50
memset(base + cnt, -1, tot - cnt);
51
}
52
53
--
54
2.45.1
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Yangyu Chen <cyy@cyyself.name>
2
2
3
Signed-off-by: Frank Chang <frank.chang@sifive.com>
3
This code has a typo that writes zvkb to zvkg, causing users can't
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
enable zvkb through the config. This patch gets this fixed.
5
Message-Id: <20200710104920.13550-3-frank.chang@sifive.com>
5
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
7
Fixes: ea61ef7097d0 ("target/riscv: Move vector crypto extensions to riscv_cpu_extensions")
8
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
15
---
8
target/riscv/insn_trans/trans_rvv.inc.c | 2 +-
16
target/riscv/cpu.c | 2 +-
9
1 file changed, 1 insertion(+), 1 deletion(-)
17
1 file changed, 1 insertion(+), 1 deletion(-)
10
18
11
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
12
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/insn_trans/trans_rvv.inc.c
21
--- a/target/riscv/cpu.c
14
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
22
+++ b/target/riscv/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static void gen_vec_rsub8_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
16
24
/* Vector cryptography extensions */
17
static void gen_vec_rsub16_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
18
{
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
19
- tcg_gen_vec_sub8_i64(d, b, a);
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
20
+ tcg_gen_vec_sub16_i64(d, b, a);
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
21
}
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
22
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
23
static void gen_rsub_i32(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
24
--
32
--
25
2.27.0
33
2.45.1
26
34
27
35
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Huang Tao <eric.huang@linux.alibaba.com>
2
2
3
vill bit is at vtype[XLEN-1].
3
In this patch, we modify the decoder to be a freely composable data
4
structure instead of a hardcoded one. It can be dynamically builded up
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.
4
20
5
Signed-off-by: Frank Chang <frank.chang@sifive.com>
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-Id: <20200710104920.13550-5-frank.chang@sifive.com>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
28
---
10
target/riscv/cpu.h | 2 +-
29
target/riscv/cpu.h | 1 +
11
1 file changed, 1 insertion(+), 1 deletion(-)
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
31
target/riscv/cpu.c | 1 +
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
12
35
13
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
14
index XXXXXXX..XXXXXXX 100644
37
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.h
38
--- a/target/riscv/cpu.h
16
+++ b/target/riscv/cpu.h
39
+++ b/target/riscv/cpu.h
17
@@ -XXX,XX +XXX,XX @@ FIELD(VTYPE, VLMUL, 0, 2)
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
18
FIELD(VTYPE, VSEW, 2, 3)
41
uint32_t pmu_avail_ctrs;
19
FIELD(VTYPE, VEDIV, 5, 2)
42
/* Mapping of events to counters */
20
FIELD(VTYPE, RESERVED, 7, sizeof(target_ulong) * 8 - 9)
43
GHashTable *pmu_event_ctr_map;
21
-FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 2, 1)
44
+ const GPtrArray *decoders;
22
+FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
45
};
23
46
24
struct CPURISCVState {
47
/**
25
target_ulong gpr[32];
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
49
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/tcg/tcg-cpu.h
51
+++ b/target/riscv/tcg/tcg-cpu.h
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
55
56
+struct DisasContext;
57
+struct RISCVCPUConfig;
58
+typedef struct RISCVDecoder {
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
61
+} RISCVDecoder;
62
+
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
64
+
65
+extern const size_t decoder_table_size;
66
+
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
77
error_propagate(errp, local_err);
78
return;
79
}
80
+ riscv_tcg_cpu_finalize_dynamic_decoder(cpu);
81
} else if (kvm_enabled()) {
82
riscv_kvm_cpu_finalize_features(cpu, &local_err);
83
if (local_err != NULL) {
84
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/riscv/tcg/tcg-cpu.c
87
+++ b/target/riscv/tcg/tcg-cpu.c
88
@@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
89
}
90
}
91
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
93
+{
94
+ GPtrArray *dynamic_decoders;
95
+ dynamic_decoders = g_ptr_array_sized_new(decoder_table_size);
96
+ for (size_t i = 0; i < decoder_table_size; ++i) {
97
+ if (decoder_table[i].guard_func &&
98
+ decoder_table[i].guard_func(&cpu->cfg)) {
99
+ g_ptr_array_add(dynamic_decoders,
100
+ (gpointer)decoder_table[i].riscv_cpu_decode_fn);
101
+ }
102
+ }
103
+
104
+ cpu->decoders = dynamic_decoders;
105
+}
106
+
107
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu)
108
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/target/riscv/translate.c
113
+++ b/target/riscv/translate.c
114
@@ -XXX,XX +XXX,XX @@
115
#include "exec/helper-info.c.inc"
116
#undef HELPER_H
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
}
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)
26
--
182
--
27
2.27.0
183
2.45.1
28
29
diff view generated by jsdifflib
1
From: Bin Meng <bmeng.cn@gmail.com>
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
2
2
3
List me as the maintainer for OpenSBI firmware related files.
3
The th.sxstatus CSR can be used to identify available custom extension
4
on T-Head CPUs. The CSR is documented here:
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
4
6
5
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
7
An important property of this patch is, that the th.sxstatus MAEE field
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
8
is not set (indicating that XTheadMae is not available).
7
Message-Id: <1593177220-28143-1-git-send-email-bmeng.cn@gmail.com>
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
17
Further context can be found on the list:
18
https://lists.gnu.org/archive/html/qemu-devel/2024-02/msg00775.html
19
20
Reviewed-by: LIU Zhiwei <zhiwe_liu@linux.alibaba.com>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
23
Message-ID: <20240429073656.2486732-1-christoph.muellner@vrull.eu>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
25
---
10
MAINTAINERS | 7 +++++++
26
MAINTAINERS | 1 +
11
1 file changed, 7 insertions(+)
27
target/riscv/cpu.h | 3 ++
28
target/riscv/cpu.c | 1 +
29
target/riscv/th_csr.c | 79 ++++++++++++++++++++++++++++++++++++++++
30
target/riscv/meson.build | 1 +
31
5 files changed, 85 insertions(+)
32
create mode 100644 target/riscv/th_csr.c
12
33
13
diff --git a/MAINTAINERS b/MAINTAINERS
34
diff --git a/MAINTAINERS b/MAINTAINERS
14
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
15
--- a/MAINTAINERS
36
--- a/MAINTAINERS
16
+++ b/MAINTAINERS
37
+++ b/MAINTAINERS
17
@@ -XXX,XX +XXX,XX @@ F: hw/i386/intel_iommu.c
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
18
F: hw/i386/intel_iommu_internal.h
39
S: Supported
19
F: include/hw/i386/intel_iommu.h
40
F: target/riscv/insn_trans/trans_xthead.c.inc
20
41
F: target/riscv/xthead*.decode
21
+OpenSBI Firmware
42
+F: target/riscv/th_*
22
+M: Bin Meng <bmeng.cn@gmail.com>
43
F: disas/riscv-xthead*
23
+S: Supported
44
24
+F: pc-bios/opensbi-*
45
RISC-V XVentanaCondOps extension
25
+F: .gitlab-ci.d/opensbi.yml
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
26
+F: .gitlab-ci.d/opensbi/
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
49
+++ b/target/riscv/cpu.h
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
51
uint8_t satp_mode_max_from_map(uint32_t map);
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
53
54
+/* Implemented in th_csr.c */
55
+void th_register_custom_csrs(RISCVCPU *cpu);
27
+
56
+
28
Usermode Emulation
57
#endif /* RISCV_CPU_H */
29
------------------
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
Overall usermode emulation
59
index XXXXXXX..XXXXXXX 100644
60
--- a/target/riscv/cpu.c
61
+++ b/target/riscv/cpu.c
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
64
#ifndef CONFIG_USER_ONLY
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
66
+ th_register_custom_csrs(cpu);
67
#endif
68
69
/* inherited from parent obj via riscv_cpu_init() */
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
71
new file mode 100644
72
index XXXXXXX..XXXXXXX
73
--- /dev/null
74
+++ b/target/riscv/th_csr.c
75
@@ -XXX,XX +XXX,XX @@
76
+/*
77
+ * T-Head-specific CSRs.
78
+ *
79
+ * Copyright (c) 2024 VRULL GmbH
80
+ *
81
+ * 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,
83
+ * version 2 or later, as published by the Free Software Foundation.
84
+ *
85
+ * This program is distributed in the hope it will be useful, but WITHOUT
86
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
87
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
88
+ * more details.
89
+ *
90
+ * 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/>.
92
+ */
93
+
94
+#include "qemu/osdep.h"
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
+{
113
+ if (riscv_has_ext(env, RVS)) {
114
+ return RISCV_EXCP_NONE;
115
+ }
116
+
117
+ return RISCV_EXCP_ILLEGAL_INST;
118
+}
119
+
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
121
+{
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
123
+ return -1;
124
+ }
125
+
126
+ return 0;
127
+}
128
+
129
+static RISCVException read_th_sxstatus(CPURISCVState *env, int csrno,
130
+ target_ulong *val)
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
))
31
--
167
--
32
2.27.0
168
2.45.1
33
169
34
170
diff view generated by jsdifflib
1
From: Atish Patra <atish.patra@wdc.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
OpenSBI is the default firmware in Qemu and has various firmware loading
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
4
options. Currently, qemu loader uses fw_jump which has a compile time
4
instructions will be affected by Zvfhmin extension.
5
pre-defined address where fdt & kernel image must reside. This puts a
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
6
constraint on image size of the Linux kernel depending on the fdt location
6
conversions of
7
and available memory. However, fw_dynamic allows the loader to specify
8
the next stage location (i.e. Linux kernel/U-Boot) in memory and other
9
configurable boot options available in OpenSBI.
10
7
11
Add support for OpenSBI dynamic firmware loading support. This doesn't
8
* From 1*SEW(16/32) to 2*SEW(32/64)
12
break existing setup and fw_jump will continue to work as it is. Any
9
* From 2*SEW(32/64) to 1*SEW(16/32)
13
other firmware will continue to work without any issues as long as it
14
doesn't expect anything specific from loader in "a2" register.
15
10
16
Signed-off-by: Atish Patra <atish.patra@wdc.com>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
18
Reviewed-by: Bin Meng <bin.meng@windriver.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
19
Tested-by: Bin Meng <bin.meng@windriver.com>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
20
Message-Id: <20200701183949.398134-4-atish.patra@wdc.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
16
---
23
include/hw/riscv/boot.h | 5 ++-
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
24
include/hw/riscv/boot_opensbi.h | 58 +++++++++++++++++++++++++++++++++
18
1 file changed, 18 insertions(+), 2 deletions(-)
25
hw/riscv/boot.c | 42 +++++++++++++++++++++---
26
hw/riscv/sifive_u.c | 20 +++++++++---
27
hw/riscv/spike.c | 13 ++++++--
28
hw/riscv/virt.c | 12 +++++--
29
6 files changed, 134 insertions(+), 16 deletions(-)
30
create mode 100644 include/hw/riscv/boot_opensbi.h
31
19
32
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
33
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
34
--- a/include/hw/riscv/boot.h
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
35
+++ b/include/hw/riscv/boot.h
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
36
@@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
37
uint64_t kernel_entry, hwaddr *start);
25
}
38
uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
39
void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base,
40
- hwaddr rom_size,
41
+ hwaddr rom_size, uint64_t kernel_entry,
42
uint32_t fdt_load_addr, void *fdt);
43
+void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
44
+ uint32_t reset_vec_size,
45
+ uint64_t kernel_entry);
46
47
#endif /* RISCV_BOOT_H */
48
diff --git a/include/hw/riscv/boot_opensbi.h b/include/hw/riscv/boot_opensbi.h
49
new file mode 100644
50
index XXXXXXX..XXXXXXX
51
--- /dev/null
52
+++ b/include/hw/riscv/boot_opensbi.h
53
@@ -XXX,XX +XXX,XX @@
54
+/* SPDX-License-Identifier: BSD-2-Clause */
55
+/*
56
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
57
+ *
58
+ * Based on include/sbi/{fw_dynamic.h,sbi_scratch.h} from the OpenSBI project.
59
+ */
60
+#ifndef OPENSBI_H
61
+#define OPENSBI_H
62
+
63
+/** Expected value of info magic ('OSBI' ascii string in hex) */
64
+#define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f
65
+
66
+/** Maximum supported info version */
67
+#define FW_DYNAMIC_INFO_VERSION 0x2
68
+
69
+/** Possible next mode values */
70
+#define FW_DYNAMIC_INFO_NEXT_MODE_U 0x0
71
+#define FW_DYNAMIC_INFO_NEXT_MODE_S 0x1
72
+#define FW_DYNAMIC_INFO_NEXT_MODE_M 0x3
73
+
74
+enum sbi_scratch_options {
75
+ /** Disable prints during boot */
76
+ SBI_SCRATCH_NO_BOOT_PRINTS = (1 << 0),
77
+ /** Enable runtime debug prints */
78
+ SBI_SCRATCH_DEBUG_PRINTS = (1 << 1),
79
+};
80
+
81
+/** Representation dynamic info passed by previous booting stage */
82
+struct fw_dynamic_info {
83
+ /** Info magic */
84
+ target_long magic;
85
+ /** Info version */
86
+ target_long version;
87
+ /** Next booting stage address */
88
+ target_long next_addr;
89
+ /** Next booting stage mode */
90
+ target_long next_mode;
91
+ /** Options for OpenSBI library */
92
+ target_long options;
93
+ /**
94
+ * Preferred boot HART id
95
+ *
96
+ * It is possible that the previous booting stage uses same link
97
+ * address as the FW_DYNAMIC firmware. In this case, the relocation
98
+ * lottery mechanism can potentially overwrite the previous booting
99
+ * stage while other HARTs are still running in the previous booting
100
+ * stage leading to boot-time crash. To avoid this boot-time crash,
101
+ * the previous booting stage can specify last HART that will jump
102
+ * to the FW_DYNAMIC firmware as the preferred boot HART.
103
+ *
104
+ * To avoid specifying a preferred boot HART, the previous booting
105
+ * stage can set it to -1UL which will force the FW_DYNAMIC firmware
106
+ * to use the relocation lottery mechanism.
107
+ */
108
+ target_long boot_hart;
109
+};
110
+
111
+#endif
112
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/hw/riscv/boot.c
115
+++ b/hw/riscv/boot.c
116
@@ -XXX,XX +XXX,XX @@
117
#include "hw/boards.h"
118
#include "hw/loader.h"
119
#include "hw/riscv/boot.h"
120
+#include "hw/riscv/boot_opensbi.h"
121
#include "elf.h"
122
#include "sysemu/device_tree.h"
123
#include "sysemu/qtest.h"
124
@@ -XXX,XX +XXX,XX @@
125
126
#if defined(TARGET_RISCV32)
127
# define KERNEL_BOOT_ADDRESS 0x80400000
128
+#define fw_dynamic_info_data(__val) cpu_to_le32(__val)
129
#else
130
# define KERNEL_BOOT_ADDRESS 0x80200000
131
+#define fw_dynamic_info_data(__val) cpu_to_le64(__val)
132
#endif
133
134
void riscv_find_and_load_firmware(MachineState *machine,
135
@@ -XXX,XX +XXX,XX @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
136
return fdt_addr;
137
}
26
}
138
27
139
+void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
28
+static bool require_rvfmin(DisasContext *s)
140
+ uint32_t reset_vec_size, uint64_t kernel_entry)
141
+{
29
+{
142
+ struct fw_dynamic_info dinfo;
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
143
+ size_t dinfo_len;
31
+ return false;
144
+
145
+ dinfo.magic = fw_dynamic_info_data(FW_DYNAMIC_INFO_MAGIC_VALUE);
146
+ dinfo.version = fw_dynamic_info_data(FW_DYNAMIC_INFO_VERSION);
147
+ dinfo.next_mode = fw_dynamic_info_data(FW_DYNAMIC_INFO_NEXT_MODE_S);
148
+ dinfo.next_addr = fw_dynamic_info_data(kernel_entry);
149
+ dinfo.options = 0;
150
+ dinfo.boot_hart = 0;
151
+ dinfo_len = sizeof(dinfo);
152
+
153
+ /**
154
+ * copy the dynamic firmware info. This information is specific to
155
+ * OpenSBI but doesn't break any other firmware as long as they don't
156
+ * expect any certain value in "a2" register.
157
+ */
158
+ if (dinfo_len > (rom_size - reset_vec_size)) {
159
+ error_report("not enough space to store dynamic firmware info");
160
+ exit(1);
161
+ }
32
+ }
162
+
33
+
163
+ rom_add_blob_fixed_as("mrom.finfo", &dinfo, dinfo_len,
34
+ switch (s->sew) {
164
+ rom_base + reset_vec_size,
35
+ case MO_16:
165
+ &address_space_memory);
36
+ return s->cfg_ptr->ext_zvfhmin;
37
+ case MO_32:
38
+ return s->cfg_ptr->ext_zve32f;
39
+ default:
40
+ return false;
41
+ }
166
+}
42
+}
167
+
43
+
168
void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
44
static bool require_scale_rvf(DisasContext *s)
169
- hwaddr rom_size,
170
+ hwaddr rom_size, uint64_t kernel_entry,
171
uint32_t fdt_load_addr, void *fdt)
172
{
45
{
173
int i;
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
174
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
175
/* reset vector */
176
uint32_t reset_vec[10] = {
177
- 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
178
+ 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
179
+ 0x02828613, /* addi a2, t0, %pcrel_lo(1b) */
180
0xf1402573, /* csrr a0, mhartid */
181
#if defined(TARGET_RISCV32)
182
0x0202a583, /* lw a1, 32(t0) */
183
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
184
0x0182b283, /* ld t0, 24(t0) */
185
#endif
186
0x00028067, /* jr t0 */
187
- 0x00000000,
188
start_addr, /* start: .dword */
189
0x00000000,
190
fdt_load_addr, /* fdt_laddr: .dword */
191
0x00000000,
192
- /* dtb: */
193
+ /* fw_dyn: */
194
};
195
196
/* copy in the reset vector in little_endian byte order */
197
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
198
}
48
}
199
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
49
200
rom_base, &address_space_memory);
50
switch (s->sew) {
201
+ riscv_rom_copy_firmware_info(rom_base, rom_size, sizeof(reset_vec),
51
- case MO_8:
202
+ kernel_entry);
52
- return s->cfg_ptr->ext_zvfhmin;
203
53
case MO_16:
204
return;
54
return s->cfg_ptr->ext_zve32f;
55
case MO_32:
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
58
{
59
return opfv_widen_check(s, a) &&
60
+ require_rvfmin(s) &&
61
require_scale_rvfmin(s) &&
62
(s->sew != MO_8);
205
}
63
}
206
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
207
index XXXXXXX..XXXXXXX 100644
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
208
--- a/hw/riscv/sifive_u.c
66
{
209
+++ b/hw/riscv/sifive_u.c
67
return opfv_narrow_check(s, a) &&
210
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
68
+ require_rvfmin(s) &&
211
target_ulong start_addr = memmap[SIFIVE_U_DRAM].base;
69
require_scale_rvfmin(s) &&
212
int i;
70
(s->sew != MO_8);
213
uint32_t fdt_load_addr;
214
+ uint64_t kernel_entry;
215
216
/* Initialize SoC */
217
object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
218
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
219
riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL);
220
221
if (machine->kernel_filename) {
222
- uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
223
- NULL);
224
+ kernel_entry = riscv_load_kernel(machine->kernel_filename, NULL);
225
226
if (machine->initrd_filename) {
227
hwaddr start;
228
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
229
qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
230
end);
231
}
232
+ } else {
233
+ /*
234
+ * If dynamic firmware is used, it doesn't know where is the next mode
235
+ * if kernel argument is not set.
236
+ */
237
+ kernel_entry = 0;
238
}
239
240
/* Compute the fdt load address in dram */
241
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
242
/* reset vector */
243
uint32_t reset_vec[11] = {
244
s->msel, /* MSEL pin state */
245
- 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
246
+ 0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
247
+ 0x02828613, /* addi a2, t0, %pcrel_lo(1b) */
248
0xf1402573, /* csrr a0, mhartid */
249
#if defined(TARGET_RISCV32)
250
0x0202a583, /* lw a1, 32(t0) */
251
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
252
0x0182b283, /* ld t0, 24(t0) */
253
#endif
254
0x00028067, /* jr t0 */
255
- 0x00000000,
256
start_addr, /* start: .dword */
257
0x00000000,
258
fdt_load_addr, /* fdt_laddr: .dword */
259
0x00000000,
260
- /* dtb: */
261
+ /* fw_dyn: */
262
};
263
264
/* copy in the reset vector in little_endian byte order */
265
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
266
}
267
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
268
memmap[SIFIVE_U_MROM].base, &address_space_memory);
269
+
270
+ riscv_rom_copy_firmware_info(memmap[SIFIVE_U_MROM].base,
271
+ memmap[SIFIVE_U_MROM].size,
272
+ sizeof(reset_vec), kernel_entry);
273
}
71
}
274
275
static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
276
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
277
index XXXXXXX..XXXXXXX 100644
278
--- a/hw/riscv/spike.c
279
+++ b/hw/riscv/spike.c
280
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
281
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
282
unsigned int smp_cpus = machine->smp.cpus;
283
uint32_t fdt_load_addr;
284
+ uint64_t kernel_entry;
285
286
/* Initialize SOC */
287
object_initialize_child(OBJECT(machine), "soc", &s->soc,
288
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
289
htif_symbol_callback);
290
291
if (machine->kernel_filename) {
292
- uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
293
- htif_symbol_callback);
294
+ kernel_entry = riscv_load_kernel(machine->kernel_filename,
295
+ htif_symbol_callback);
296
297
if (machine->initrd_filename) {
298
hwaddr start;
299
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
300
qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
301
end);
302
}
303
+ } else {
304
+ /*
305
+ * If dynamic firmware is used, it doesn't know where is the next mode
306
+ * if kernel argument is not set.
307
+ */
308
+ kernel_entry = 0;
309
}
310
311
/* Compute the fdt load address in dram */
312
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
313
machine->ram_size, s->fdt);
314
/* load the reset vector */
315
riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base,
316
- memmap[SPIKE_MROM].size,
317
+ memmap[SPIKE_MROM].size, kernel_entry,
318
fdt_load_addr, s->fdt);
319
320
/* initialize HTIF using symbols found in load_kernel */
321
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
322
index XXXXXXX..XXXXXXX 100644
323
--- a/hw/riscv/virt.c
324
+++ b/hw/riscv/virt.c
325
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
326
size_t plic_hart_config_len;
327
target_ulong start_addr = memmap[VIRT_DRAM].base;
328
uint32_t fdt_load_addr;
329
+ uint64_t kernel_entry;
330
int i;
331
unsigned int smp_cpus = machine->smp.cpus;
332
333
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
334
memmap[VIRT_DRAM].base, NULL);
335
336
if (machine->kernel_filename) {
337
- uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
338
- NULL);
339
+ kernel_entry = riscv_load_kernel(machine->kernel_filename, NULL);
340
341
if (machine->initrd_filename) {
342
hwaddr start;
343
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
344
qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
345
end);
346
}
347
+ } else {
348
+ /*
349
+ * If dynamic firmware is used, it doesn't know where is the next mode
350
+ * if kernel argument is not set.
351
+ */
352
+ kernel_entry = 0;
353
}
354
355
if (drive_get(IF_PFLASH, 0, 0)) {
356
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
357
machine->ram_size, s->fdt);
358
/* load the reset vector */
359
riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base,
360
- virt_memmap[VIRT_MROM].size,
361
+ virt_memmap[VIRT_MROM].size, kernel_entry,
362
fdt_load_addr, s->fdt);
363
364
/* create PLIC hart topology configuration string */
365
--
72
--
366
2.27.0
73
2.45.1
367
368
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Max Chou <max.chou@sifive.com>
2
2
3
gvec should provide vecop_list to avoid:
3
The require_scale_rvf function only checks the double width operator for
4
"tcg_tcg_assert_listed_vecop: code should not be reached bug" assertion.
4
the vector floating point widen instructions, so most of the widen
5
checking functions need to add require_rvf for single width operator.
5
6
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
integer to double width float, so the opfxv_widen_check function doesn’t
8
Message-Id: <20200710104920.13550-2-frank.chang@sifive.com>
9
need require_rvf for the single width operator(integer).
10
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
16
---
11
target/riscv/insn_trans/trans_rvv.inc.c | 5 +++++
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
12
1 file changed, 5 insertions(+)
18
1 file changed, 5 insertions(+)
13
19
14
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvv.inc.c
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
@@ -XXX,XX +XXX,XX @@ static void gen_rsub_vec(unsigned vece, TCGv_vec r, TCGv_vec a, TCGv_vec b)
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
19
static void tcg_gen_gvec_rsubs(unsigned vece, uint32_t dofs, uint32_t aofs,
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
20
TCGv_i64 c, uint32_t oprsz, uint32_t maxsz)
21
{
26
{
22
+ static const TCGOpcode vecop_list[] = { INDEX_op_sub_vec, 0 };
27
return require_rvv(s) &&
23
static const GVecGen2s rsub_op[4] = {
28
+ require_rvf(s) &&
24
{ .fni8 = gen_vec_rsub8_i64,
29
require_scale_rvf(s) &&
25
.fniv = gen_rsub_vec,
30
(s->sew != MO_8) &&
26
.fno = gen_helper_vec_rsubs8,
31
vext_check_isa_ill(s) &&
27
+ .opt_opc = vecop_list,
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
28
.vece = MO_8 },
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
29
{ .fni8 = gen_vec_rsub16_i64,
34
{
30
.fniv = gen_rsub_vec,
35
return require_rvv(s) &&
31
.fno = gen_helper_vec_rsubs16,
36
+ require_rvf(s) &&
32
+ .opt_opc = vecop_list,
37
require_scale_rvf(s) &&
33
.vece = MO_16 },
38
(s->sew != MO_8) &&
34
{ .fni4 = gen_rsub_i32,
39
vext_check_isa_ill(s) &&
35
.fniv = gen_rsub_vec,
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
36
.fno = gen_helper_vec_rsubs32,
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
37
+ .opt_opc = vecop_list,
42
{
38
.vece = MO_32 },
43
return require_rvv(s) &&
39
{ .fni8 = gen_rsub_i64,
44
+ require_rvf(s) &&
40
.fniv = gen_rsub_vec,
45
require_scale_rvf(s) &&
41
.fno = gen_helper_vec_rsubs64,
46
(s->sew != MO_8) &&
42
+ .opt_opc = vecop_list,
47
vext_check_isa_ill(s) &&
43
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
44
.vece = MO_64 },
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
45
};
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
}
46
--
64
--
47
2.27.0
65
2.45.1
48
66
49
67
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
The opfv_narrow_check needs to check the single width float operator by
4
require_rvf.
5
6
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
13
1 file changed, 1 insertion(+)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
21
{
22
return opfv_narrow_check(s, a) &&
23
+ require_rvf(s) &&
24
require_scale_rvf(s) &&
25
(s->sew != MO_8);
26
}
27
--
28
2.45.1
diff view generated by jsdifflib
New patch
1
From: Max Chou <max.chou@sifive.com>
1
2
3
If the checking functions check both the single and double width
4
operators at the same time, then the single width operator checking
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
7
Signed-off-by: Max Chou <max.chou@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
14
1 file changed, 4 insertions(+), 12 deletions(-)
15
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
21
return require_rvv(s) &&
22
require_rvf(s) &&
23
require_scale_rvf(s) &&
24
- (s->sew != MO_8) &&
25
vext_check_isa_ill(s) &&
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
27
}
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
29
return require_rvv(s) &&
30
require_rvf(s) &&
31
require_scale_rvf(s) &&
32
- (s->sew != MO_8) &&
33
vext_check_isa_ill(s) &&
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
35
}
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
37
return require_rvv(s) &&
38
require_rvf(s) &&
39
require_scale_rvf(s) &&
40
- (s->sew != MO_8) &&
41
vext_check_isa_ill(s) &&
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
43
}
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
45
return require_rvv(s) &&
46
require_rvf(s) &&
47
require_scale_rvf(s) &&
48
- (s->sew != MO_8) &&
49
vext_check_isa_ill(s) &&
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
51
}
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
53
{
54
return opfv_widen_check(s, a) &&
55
require_rvfmin(s) &&
56
- require_scale_rvfmin(s) &&
57
- (s->sew != MO_8);
58
+ require_scale_rvfmin(s);
59
}
60
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
63
{
64
return opfv_narrow_check(s, a) &&
65
require_rvfmin(s) &&
66
- require_scale_rvfmin(s) &&
67
- (s->sew != MO_8);
68
+ require_scale_rvfmin(s);
69
}
70
71
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
72
{
73
return opfv_narrow_check(s, a) &&
74
require_rvf(s) &&
75
- require_scale_rvf(s) &&
76
- (s->sew != MO_8);
77
+ require_scale_rvf(s);
78
}
79
80
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
81
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
82
{
83
return reduction_widen_check(s, a) &&
84
require_rvf(s) &&
85
- require_scale_rvf(s) &&
86
- (s->sew != MO_8);
87
+ require_scale_rvf(s);
88
}
89
90
GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
91
--
92
2.45.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
raise_mmu_exception(), as is today, is prioritizing guest page faults by
4
checking first if virt_enabled && !first_stage, and then considering the
5
regular inst/load/store faults.
6
7
There's no mention in the spec about guest page fault being a higher
8
priority that PMP faults. In fact, privileged spec section 3.7.1 says:
9
10
"Attempting to fetch an instruction from a PMP region that does not have
11
execute permissions raises an instruction access-fault exception.
12
Attempting to execute a load or load-reserved instruction which accesses
13
a physical address within a PMP region without read permissions raises a
14
load access-fault exception. Attempting to execute a store,
15
store-conditional, or AMO instruction which accesses a physical address
16
within a PMP region without write permissions raises a store
17
access-fault exception."
18
19
So, in fact, we're doing it wrong - PMP faults should always be thrown,
20
regardless of also being a first or second stage fault.
21
22
The way riscv_cpu_tlb_fill() and get_physical_address() work is
23
adequate: a TRANSLATE_PMP_FAIL error is immediately reported and
24
reflected in the 'pmp_violation' flag. What we need is to change
25
raise_mmu_exception() to prioritize it.
26
27
Reported-by: Joseph Chan <jchan@ventanamicro.com>
28
Fixes: 82d53adfbb ("target/riscv/cpu_helper.c: Invalid exception on MMU translation stage")
29
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-ID: <20240413105929.7030-1-alexei.filippov@syntacore.com>
32
Cc: qemu-stable <qemu-stable@nongnu.org>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
36
1 file changed, 12 insertions(+), 10 deletions(-)
37
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
43
44
switch (access_type) {
45
case MMU_INST_FETCH:
46
- if (env->virt_enabled && !first_stage) {
47
+ if (pmp_violation) {
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
49
+ } else if (env->virt_enabled && !first_stage) {
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
51
} else {
52
- cs->exception_index = pmp_violation ?
53
- RISCV_EXCP_INST_ACCESS_FAULT : RISCV_EXCP_INST_PAGE_FAULT;
54
+ cs->exception_index = RISCV_EXCP_INST_PAGE_FAULT;
55
}
56
break;
57
case MMU_DATA_LOAD:
58
- if (two_stage && !first_stage) {
59
+ if (pmp_violation) {
60
+ cs->exception_index = RISCV_EXCP_LOAD_ACCESS_FAULT;
61
+ } else if (two_stage && !first_stage) {
62
cs->exception_index = RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT;
63
} else {
64
- cs->exception_index = pmp_violation ?
65
- RISCV_EXCP_LOAD_ACCESS_FAULT : RISCV_EXCP_LOAD_PAGE_FAULT;
66
+ cs->exception_index = RISCV_EXCP_LOAD_PAGE_FAULT;
67
}
68
break;
69
case MMU_DATA_STORE:
70
- if (two_stage && !first_stage) {
71
+ if (pmp_violation) {
72
+ cs->exception_index = RISCV_EXCP_STORE_AMO_ACCESS_FAULT;
73
+ } else if (two_stage && !first_stage) {
74
cs->exception_index = RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT;
75
} else {
76
- cs->exception_index = pmp_violation ?
77
- RISCV_EXCP_STORE_AMO_ACCESS_FAULT :
78
- RISCV_EXCP_STORE_PAGE_FAULT;
79
+ cs->exception_index = RISCV_EXCP_STORE_PAGE_FAULT;
80
}
81
break;
82
default:
83
--
84
2.45.1
diff view generated by jsdifflib
New patch
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
1
2
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
5
translation part, mtval2 will be set in case of successes 2 stage translation but
6
failed pmp check.
7
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
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>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
target/riscv/cpu_helper.c | 12 ++++++------
23
1 file changed, 6 insertions(+), 6 deletions(-)
24
25
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/cpu_helper.c
28
+++ b/target/riscv/cpu_helper.c
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
30
__func__, pa, ret, prot_pmp, tlb_size);
31
32
prot &= prot_pmp;
33
- }
34
-
35
- if (ret != TRANSLATE_SUCCESS) {
36
+ } else {
37
/*
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
}
51
}
52
} else {
53
--
54
2.45.1
diff view generated by jsdifflib
1
From: Liao Pingfang <liao.pingfang@zte.com.cn>
1
From: Rob Bradford <rbradford@rivosinc.com>
2
2
3
Remove superfluous breaks, as there is a "return" before them.
3
This extension has now been ratified:
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
5
removed.
4
6
5
Signed-off-by: Liao Pingfang <liao.pingfang@zte.com.cn>
7
Since this is now a ratified extension add it to the list of extensions
6
Signed-off-by: Yi Wang <wang.yi59@zte.com.cn>
8
included in the "max" CPU variant.
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
8
Reviewed-by: Thomas Huth <thuth@redhat.com>
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <1594600421-22942-1-git-send-email-wang.yi59@zte.com.cn>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
17
---
13
tcg/riscv/tcg-target.inc.c | 2 --
18
target/riscv/cpu.c | 2 +-
14
1 file changed, 2 deletions(-)
19
target/riscv/tcg/tcg-cpu.c | 2 +-
20
2 files changed, 2 insertions(+), 2 deletions(-)
15
21
16
diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/tcg/riscv/tcg-target.inc.c
24
--- a/target/riscv/cpu.c
19
+++ b/tcg/riscv/tcg-target.inc.c
25
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static bool patch_reloc(tcg_insn_unit *code_ptr, int type,
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
21
break;
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
22
case R_RISCV_JAL:
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
23
return reloc_jimm20(code_ptr, (tcg_insn_unit *)value);
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
24
- break;
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
25
case R_RISCV_CALL:
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
26
return reloc_call(code_ptr, (tcg_insn_unit *)value);
32
};
27
- break;
33
28
default:
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
29
tcg_abort();
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
30
}
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/tcg/tcg-cpu.c
38
+++ b/target/riscv/tcg/tcg-cpu.c
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
40
const RISCVCPUMultiExtConfig *prop;
41
42
/* Enable RVG, RVJ and RVV that are disabled by default */
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
45
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
47
isa_ext_update_enabled(cpu, prop->offset, true);
31
--
48
--
32
2.27.0
49
2.45.1
33
34
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Alistair Francis <alistair23@gmail.com>
2
2
3
do_opivx_widen() should return false if check function returns false.
3
When running the instruction
4
4
5
Signed-off-by: Frank Chang <frank.chang@sifive.com>
5
```
6
cbo.flush 0(x0)
7
```
8
9
QEMU would segfault.
10
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
12
allocated.
13
14
In order to fix this let's use the existing get_address()
15
helper. This also has the benefit of performing pointer mask
16
calculations on the address specified in rs1.
17
18
The pointer masking specificiation specifically states:
19
20
"""
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-Id: <20200710104920.13550-4-frank.chang@sifive.com>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
34
---
10
target/riscv/insn_trans/trans_rvv.inc.c | 2 +-
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
11
1 file changed, 1 insertion(+), 1 deletion(-)
36
1 file changed, 12 insertions(+), 4 deletions(-)
12
37
13
diff --git a/target/riscv/insn_trans/trans_rvv.inc.c b/target/riscv/insn_trans/trans_rvv.inc.c
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
14
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/insn_trans/trans_rvv.inc.c
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
16
+++ b/target/riscv/insn_trans/trans_rvv.inc.c
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
17
@@ -XXX,XX +XXX,XX @@ static bool do_opivx_widen(DisasContext *s, arg_rmrr *a,
42
@@ -XXX,XX +XXX,XX @@
18
if (opivx_widen_check(s, a)) {
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
19
return opivx_trans(a->rd, a->rs1, a->rs2, a->vm, fn, s);
44
{
20
}
45
REQUIRE_ZICBOM(ctx);
21
- return true;
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
22
+ return false;
47
+ TCGv src = get_address(ctx, a->rs1, 0);
48
+
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
50
return true;
23
}
51
}
24
52
25
#define GEN_OPIVX_WIDEN_TRANS(NAME) \
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
54
{
55
REQUIRE_ZICBOM(ctx);
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
57
+ TCGv src = get_address(ctx, a->rs1, 0);
58
+
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
60
return true;
61
}
62
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
64
{
65
REQUIRE_ZICBOM(ctx);
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
67
+ TCGv src = get_address(ctx, a->rs1, 0);
68
+
69
+ gen_helper_cbo_inval(tcg_env, src);
70
return true;
71
}
72
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
74
{
75
REQUIRE_ZICBOZ(ctx);
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
77
+ TCGv src = get_address(ctx, a->rs1, 0);
78
+
79
+ gen_helper_cbo_zero(tcg_env, src);
80
return true;
81
}
26
--
82
--
27
2.27.0
83
2.45.1
28
29
diff view generated by jsdifflib
1
From: Atish Patra <atish.patra@wdc.com>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
Currently, all riscv machines except sifive_u have identical reset vector
3
In AIA spec, each hart (or each hart within a group) has a unique hart
4
code implementations with memory addresses being different for all machines.
4
number to locate the memory pages of interrupt files in the address
5
They can be easily combined into a single function in common code.
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.
6
8
7
Move it to common function and let all the machines use the common function.
9
However, if the largest hart number among groups is a power of 2, QEMU
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
13
updated to ensure accurate hart-index-bit settings.
8
14
9
Signed-off-by: Atish Patra <atish.patra@wdc.com>
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
11
Reviewed-by: Bin Meng <bin.meng@windriver.com>
17
12
Tested-by: Bin Meng <bin.meng@windriver.com>
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
13
Message-Id: <20200701183949.398134-2-atish.patra@wdc.com>
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>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
25
---
16
include/hw/riscv/boot.h | 2 ++
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
17
hw/riscv/boot.c | 46 +++++++++++++++++++++++++++++++++++++++++
27
1 file changed, 8 insertions(+), 1 deletion(-)
18
hw/riscv/sifive_u.c | 1 -
19
hw/riscv/spike.c | 41 +++---------------------------------
20
hw/riscv/virt.c | 40 +++--------------------------------
21
5 files changed, 54 insertions(+), 76 deletions(-)
22
28
23
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
24
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/boot.h
31
--- a/target/riscv/kvm/kvm-cpu.c
26
+++ b/include/hw/riscv/boot.h
32
+++ b/target/riscv/kvm/kvm-cpu.c
27
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename,
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
28
symbol_fn_t sym_cb);
29
hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
30
uint64_t kernel_entry, hwaddr *start);
31
+void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base,
32
+ hwaddr rom_size, void *fdt);
33
34
#endif /* RISCV_BOOT_H */
35
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/riscv/boot.c
38
+++ b/hw/riscv/boot.c
39
@@ -XXX,XX +XXX,XX @@
40
#include "hw/loader.h"
41
#include "hw/riscv/boot.h"
42
#include "elf.h"
43
+#include "sysemu/device_tree.h"
44
#include "sysemu/qtest.h"
45
46
+#include <libfdt.h>
47
+
48
#if defined(TARGET_RISCV32)
49
# define KERNEL_BOOT_ADDRESS 0x80400000
50
#else
51
@@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
52
53
return *start + size;
54
}
55
+
56
+void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
57
+ hwaddr rom_size, void *fdt)
58
+{
59
+ int i;
60
+
61
+ /* reset vector */
62
+ uint32_t reset_vec[8] = {
63
+ 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
64
+ 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
65
+ 0xf1402573, /* csrr a0, mhartid */
66
+#if defined(TARGET_RISCV32)
67
+ 0x0182a283, /* lw t0, 24(t0) */
68
+#elif defined(TARGET_RISCV64)
69
+ 0x0182b283, /* ld t0, 24(t0) */
70
+#endif
71
+ 0x00028067, /* jr t0 */
72
+ 0x00000000,
73
+ start_addr, /* start: .dword */
74
+ 0x00000000,
75
+ /* dtb: */
76
+ };
77
+
78
+ /* copy in the reset vector in little_endian byte order */
79
+ for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
80
+ reset_vec[i] = cpu_to_le32(reset_vec[i]);
81
+ }
82
+ rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
83
+ rom_base, &address_space_memory);
84
+
85
+ /* copy in the device tree */
86
+ if (fdt_pack(fdt) || fdt_totalsize(fdt) >
87
+ rom_size - sizeof(reset_vec)) {
88
+ error_report("not enough space to store device-tree");
89
+ exit(1);
90
+ }
91
+ qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
92
+ rom_add_blob_fixed_as("mrom.fdt", fdt, fdt_totalsize(fdt),
93
+ rom_base + sizeof(reset_vec),
94
+ &address_space_memory);
95
+
96
+ return;
97
+}
98
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
99
index XXXXXXX..XXXXXXX 100644
100
--- a/hw/riscv/sifive_u.c
101
+++ b/hw/riscv/sifive_u.c
102
@@ -XXX,XX +XXX,XX @@
103
#include "sysemu/device_tree.h"
104
#include "sysemu/runstate.h"
105
#include "sysemu/sysemu.h"
106
-#include "exec/address-spaces.h"
107
108
#include <libfdt.h>
109
110
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
111
index XXXXXXX..XXXXXXX 100644
112
--- a/hw/riscv/spike.c
113
+++ b/hw/riscv/spike.c
114
@@ -XXX,XX +XXX,XX @@
115
#include "sysemu/device_tree.h"
116
#include "sysemu/qtest.h"
117
#include "sysemu/sysemu.h"
118
-#include "exec/address-spaces.h"
119
-
120
-#include <libfdt.h>
121
122
#if defined(TARGET_RISCV32)
123
# define BIOS_FILENAME "opensbi-riscv32-spike-fw_jump.elf"
124
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
125
MemoryRegion *system_memory = get_system_memory();
126
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
127
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
128
- int i;
129
unsigned int smp_cpus = machine->smp.cpus;
130
131
/* Initialize SOC */
132
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
133
}
34
}
134
}
35
}
135
36
136
- /* reset vector */
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
137
- uint32_t reset_vec[8] = {
38
+
138
- 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
39
+ if (max_hart_per_socket > 1) {
139
- 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
40
+ max_hart_per_socket--;
140
- 0xf1402573, /* csrr a0, mhartid */
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
141
-#if defined(TARGET_RISCV32)
42
+ } else {
142
- 0x0182a283, /* lw t0, 24(t0) */
43
+ hart_bits = 0;
143
-#elif defined(TARGET_RISCV64)
44
+ }
144
- 0x0182b283, /* ld t0, 24(t0) */
45
+
145
-#endif
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
146
- 0x00028067, /* jr t0 */
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
147
- 0x00000000,
48
&hart_bits, true, NULL);
148
- memmap[SPIKE_DRAM].base, /* start: .dword DRAM_BASE */
149
- 0x00000000,
150
- /* dtb: */
151
- };
152
-
153
- /* copy in the reset vector in little_endian byte order */
154
- for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
155
- reset_vec[i] = cpu_to_le32(reset_vec[i]);
156
- }
157
- rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
158
- memmap[SPIKE_MROM].base, &address_space_memory);
159
-
160
- /* copy in the device tree */
161
- if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) >
162
- memmap[SPIKE_MROM].size - sizeof(reset_vec)) {
163
- error_report("not enough space to store device-tree");
164
- exit(1);
165
- }
166
- qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt));
167
- rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt),
168
- memmap[SPIKE_MROM].base + sizeof(reset_vec),
169
- &address_space_memory);
170
+ /* load the reset vector */
171
+ riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base,
172
+ memmap[SPIKE_MROM].size, s->fdt);
173
174
/* initialize HTIF using symbols found in load_kernel */
175
htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0));
176
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
177
index XXXXXXX..XXXXXXX 100644
178
--- a/hw/riscv/virt.c
179
+++ b/hw/riscv/virt.c
180
@@ -XXX,XX +XXX,XX @@
181
#include "sysemu/arch_init.h"
182
#include "sysemu/device_tree.h"
183
#include "sysemu/sysemu.h"
184
-#include "exec/address-spaces.h"
185
#include "hw/pci/pci.h"
186
#include "hw/pci-host/gpex.h"
187
188
-#include <libfdt.h>
189
-
190
#if defined(TARGET_RISCV32)
191
# define BIOS_FILENAME "opensbi-riscv32-virt-fw_jump.bin"
192
#else
193
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
194
start_addr = virt_memmap[VIRT_FLASH].base;
195
}
196
197
- /* reset vector */
198
- uint32_t reset_vec[8] = {
199
- 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
200
- 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
201
- 0xf1402573, /* csrr a0, mhartid */
202
-#if defined(TARGET_RISCV32)
203
- 0x0182a283, /* lw t0, 24(t0) */
204
-#elif defined(TARGET_RISCV64)
205
- 0x0182b283, /* ld t0, 24(t0) */
206
-#endif
207
- 0x00028067, /* jr t0 */
208
- 0x00000000,
209
- start_addr, /* start: .dword */
210
- 0x00000000,
211
- /* dtb: */
212
- };
213
-
214
- /* copy in the reset vector in little_endian byte order */
215
- for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
216
- reset_vec[i] = cpu_to_le32(reset_vec[i]);
217
- }
218
- rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
219
- memmap[VIRT_MROM].base, &address_space_memory);
220
-
221
- /* copy in the device tree */
222
- if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) >
223
- memmap[VIRT_MROM].size - sizeof(reset_vec)) {
224
- error_report("not enough space to store device-tree");
225
- exit(1);
226
- }
227
- qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt));
228
- rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt),
229
- memmap[VIRT_MROM].base + sizeof(reset_vec),
230
- &address_space_memory);
231
+ /* load the reset vector */
232
+ riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base,
233
+ virt_memmap[VIRT_MROM].size, s->fdt);
234
235
/* create PLIC hart topology configuration string */
236
plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpus;
237
--
49
--
238
2.27.0
50
2.45.1
239
240
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Adjust the PCIe memory maps to follow the order.
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
4
in bytes, when in this context we want 'reg_width' as the length in
5
bits.
4
6
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Fix 'reg_width' back to the value in bits like 7cb59921c05a
8
("target/riscv/gdbstub.c: use 'vlenb' instead of shifting 'vlen'") set
9
beforehand.
10
11
While we're at it, rename 'reg_width' to 'bitsize' to provide a bit more
12
clarity about what the variable represents. 'bitsize' is also used in
13
riscv_gen_dynamic_csr_feature() with the same purpose, i.e. as an input to
14
gdb_feature_builder_append_reg().
15
16
Cc: Akihiko Odaki <akihiko.odaki@daynix.com>
17
Cc: Alex Bennée <alex.bennee@linaro.org>
18
Reported-by: Robin Dapp <rdapp.gcc@gmail.com>
19
Fixes: 33a24910ae ("target/riscv: Use GDBFeature for dynamic XML")
20
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
21
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Acked-by: Alex Bennée <alex.bennee@linaro.org>
23
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-Id: <1593746511-19517-1-git-send-email-bmeng.cn@gmail.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
28
---
10
hw/riscv/virt.c | 6 +++---
29
target/riscv/gdbstub.c | 6 +++---
11
1 file changed, 3 insertions(+), 3 deletions(-)
30
1 file changed, 3 insertions(+), 3 deletions(-)
12
31
13
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
14
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/riscv/virt.c
34
--- a/target/riscv/gdbstub.c
16
+++ b/hw/riscv/virt.c
35
+++ b/target/riscv/gdbstub.c
17
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
18
[VIRT_TEST] = { 0x100000, 0x1000 },
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
19
[VIRT_RTC] = { 0x101000, 0x1000 },
38
{
20
[VIRT_CLINT] = { 0x2000000, 0x10000 },
39
RISCVCPU *cpu = RISCV_CPU(cs);
21
+ [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 },
40
- int reg_width = cpu->cfg.vlenb;
22
[VIRT_PLIC] = { 0xc000000, 0x4000000 },
41
+ int bitsize = cpu->cfg.vlenb << 3;
23
[VIRT_UART0] = { 0x10000000, 0x100 },
42
GDBFeatureBuilder builder;
24
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
43
int i;
25
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
44
26
- [VIRT_DRAM] = { 0x80000000, 0x0 },
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
27
- [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
46
28
- [VIRT_PCIE_PIO] = { 0x03000000, 0x00010000 },
47
/* First define types and totals in a whole VL */
29
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
30
+ [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
49
- int count = reg_width / vec_lanes[i].size;
31
+ [VIRT_DRAM] = { 0x80000000, 0x0 },
50
+ int count = bitsize / vec_lanes[i].size;
32
};
51
gdb_feature_builder_append_tag(
33
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
34
#define VIRT_FLASH_SECTOR_SIZE (256 * KiB)
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
}
61
62
gdb_feature_builder_end(&builder);
35
--
63
--
36
2.27.0
64
2.45.1
37
65
38
66
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Alistair Francis <alistair23@gmail.com>
2
2
3
At present the size of Mask ROM for sifive_u / spike / virt machines
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
4
is set to 0x11000, which ends at an unusual address. This changes the
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
5
size to 0xf000 so that it ends at 0x10000.
5
CSRs are part of the disassembly.
6
6
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <1594289144-24723-1-git-send-email-bmeng.cn@gmail.com>
9
Fixes: ea10325917 ("RISC-V Disassembler")
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
14
---
12
hw/riscv/sifive_u.c | 2 +-
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
13
hw/riscv/spike.c | 2 +-
16
1 file changed, 64 insertions(+), 1 deletion(-)
14
hw/riscv/virt.c | 2 +-
15
3 files changed, 3 insertions(+), 3 deletions(-)
16
17
17
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
18
diff --git a/disas/riscv.c b/disas/riscv.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/riscv/sifive_u.c
20
--- a/disas/riscv.c
20
+++ b/hw/riscv/sifive_u.c
21
+++ b/disas/riscv.c
21
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
22
hwaddr size;
23
case 0x0383: return "mibound";
23
} sifive_u_memmap[] = {
24
case 0x0384: return "mdbase";
24
[SIFIVE_U_DEBUG] = { 0x0, 0x100 },
25
case 0x0385: return "mdbound";
25
- [SIFIVE_U_MROM] = { 0x1000, 0x11000 },
26
- case 0x03a0: return "pmpcfg3";
26
+ [SIFIVE_U_MROM] = { 0x1000, 0xf000 },
27
+ case 0x03a0: return "pmpcfg0";
27
[SIFIVE_U_CLINT] = { 0x2000000, 0x10000 },
28
+ case 0x03a1: return "pmpcfg1";
28
[SIFIVE_U_L2LIM] = { 0x8000000, 0x2000000 },
29
+ case 0x03a2: return "pmpcfg2";
29
[SIFIVE_U_PLIC] = { 0xc000000, 0x4000000 },
30
+ case 0x03a3: return "pmpcfg3";
30
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
31
+ case 0x03a4: return "pmpcfg4";
31
index XXXXXXX..XXXXXXX 100644
32
+ case 0x03a5: return "pmpcfg5";
32
--- a/hw/riscv/spike.c
33
+ case 0x03a6: return "pmpcfg6";
33
+++ b/hw/riscv/spike.c
34
+ case 0x03a7: return "pmpcfg7";
34
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
35
+ case 0x03a8: return "pmpcfg8";
35
hwaddr base;
36
+ case 0x03a9: return "pmpcfg9";
36
hwaddr size;
37
+ case 0x03aa: return "pmpcfg10";
37
} spike_memmap[] = {
38
+ case 0x03ab: return "pmpcfg11";
38
- [SPIKE_MROM] = { 0x1000, 0x11000 },
39
+ case 0x03ac: return "pmpcfg12";
39
+ [SPIKE_MROM] = { 0x1000, 0xf000 },
40
+ case 0x03ad: return "pmpcfg13";
40
[SPIKE_CLINT] = { 0x2000000, 0x10000 },
41
+ case 0x03ae: return "pmpcfg14";
41
[SPIKE_DRAM] = { 0x80000000, 0x0 },
42
+ case 0x03af: return "pmpcfg15";
42
};
43
case 0x03b0: return "pmpaddr0";
43
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
44
case 0x03b1: return "pmpaddr1";
44
index XXXXXXX..XXXXXXX 100644
45
case 0x03b2: return "pmpaddr2";
45
--- a/hw/riscv/virt.c
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
46
+++ b/hw/riscv/virt.c
47
case 0x03bd: return "pmpaddr13";
47
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
48
case 0x03be: return "pmpaddr14";
48
hwaddr size;
49
case 0x03bf: return "pmpaddr15";
49
} virt_memmap[] = {
50
+ case 0x03c0: return "pmpaddr16";
50
[VIRT_DEBUG] = { 0x0, 0x100 },
51
+ case 0x03c1: return "pmpaddr17";
51
- [VIRT_MROM] = { 0x1000, 0x11000 },
52
+ case 0x03c2: return "pmpaddr18";
52
+ [VIRT_MROM] = { 0x1000, 0xf000 },
53
+ case 0x03c3: return "pmpaddr19";
53
[VIRT_TEST] = { 0x100000, 0x1000 },
54
+ case 0x03c4: return "pmpaddr20";
54
[VIRT_RTC] = { 0x101000, 0x1000 },
55
+ case 0x03c5: return "pmpaddr21";
55
[VIRT_CLINT] = { 0x2000000, 0x10000 },
56
+ case 0x03c6: return "pmpaddr22";
57
+ case 0x03c7: return "pmpaddr23";
58
+ case 0x03c8: return "pmpaddr24";
59
+ case 0x03c9: return "pmpaddr25";
60
+ case 0x03ca: return "pmpaddr26";
61
+ case 0x03cb: return "pmpaddr27";
62
+ case 0x03cc: return "pmpaddr28";
63
+ case 0x03cd: return "pmpaddr29";
64
+ case 0x03ce: return "pmpaddr30";
65
+ case 0x03cf: return "pmpaddr31";
66
+ case 0x03d0: return "pmpaddr32";
67
+ case 0x03d1: return "pmpaddr33";
68
+ case 0x03d2: return "pmpaddr34";
69
+ case 0x03d3: return "pmpaddr35";
70
+ case 0x03d4: return "pmpaddr36";
71
+ case 0x03d5: return "pmpaddr37";
72
+ case 0x03d6: return "pmpaddr38";
73
+ case 0x03d7: return "pmpaddr39";
74
+ case 0x03d8: return "pmpaddr40";
75
+ case 0x03d9: return "pmpaddr41";
76
+ case 0x03da: return "pmpaddr42";
77
+ case 0x03db: return "pmpaddr43";
78
+ case 0x03dc: return "pmpaddr44";
79
+ case 0x03dd: return "pmpaddr45";
80
+ case 0x03de: return "pmpaddr46";
81
+ case 0x03df: return "pmpaddr47";
82
+ case 0x03e0: return "pmpaddr48";
83
+ case 0x03e1: return "pmpaddr49";
84
+ case 0x03e2: return "pmpaddr50";
85
+ case 0x03e3: return "pmpaddr51";
86
+ case 0x03e4: return "pmpaddr52";
87
+ case 0x03e5: return "pmpaddr53";
88
+ case 0x03e6: return "pmpaddr54";
89
+ case 0x03e7: return "pmpaddr55";
90
+ case 0x03e8: return "pmpaddr56";
91
+ case 0x03e9: return "pmpaddr57";
92
+ case 0x03ea: return "pmpaddr58";
93
+ case 0x03eb: return "pmpaddr59";
94
+ case 0x03ec: return "pmpaddr60";
95
+ case 0x03ed: return "pmpaddr61";
96
+ case 0x03ee: return "pmpaddr62";
97
+ case 0x03ef: return "pmpaddr63";
98
case 0x0780: return "mtohost";
99
case 0x0781: return "mfromhost";
100
case 0x0782: return "mreset";
56
--
101
--
57
2.27.0
102
2.45.1
58
59
diff view generated by jsdifflib
1
From: Atish Patra <atish.patra@wdc.com>
1
From: Yu-Ming Chang <yumin686@andestech.com>
2
2
3
Currently, the fdt is copied to the ROM after the reset vector. The firmware
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
4
has to copy it to DRAM. Instead of this, directly copy the device tree to a
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
5
pre-computed dram address. The device tree load address should be as far as
5
holding a zero value other than x0, the instruction will still attempt to write
6
possible from kernel and initrd images. That's why it is kept at the end of
6
the unmodified value back to the CSR and will cause any attendant side effects.
7
the DRAM or 4GB whichever is lesser.
8
7
9
Signed-off-by: Atish Patra <atish.patra@wdc.com>
8
So if CSRRS or CSRRC tries to write a read-only CSR with rs1 which specifies
9
a register holding a zero value, an illegal instruction exception should be
10
raised.
11
12
Signed-off-by: Yu-Ming Chang <yumin686@andestech.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Bin Meng <bin.meng@windriver.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
12
Tested-by: Bin Meng <bin.meng@windriver.com>
13
Message-Id: <20200701183949.398134-3-atish.patra@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
---
16
include/hw/riscv/boot.h | 4 +++-
17
target/riscv/cpu.h | 4 ++++
17
hw/riscv/boot.c | 53 +++++++++++++++++++++++++++++------------
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
18
hw/riscv/sifive_u.c | 28 ++++++++++------------
19
target/riscv/op_helper.c | 6 ++---
19
hw/riscv/spike.c | 7 +++++-
20
3 files changed, 53 insertions(+), 8 deletions(-)
20
hw/riscv/virt.c | 7 +++++-
21
5 files changed, 66 insertions(+), 33 deletions(-)
22
21
23
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/boot.h
24
--- a/target/riscv/cpu.h
26
+++ b/include/hw/riscv/boot.h
25
+++ b/target/riscv/cpu.h
27
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename,
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
28
symbol_fn_t sym_cb);
27
void riscv_cpu_update_mask(CPURISCVState *env);
29
hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
30
uint64_t kernel_entry, hwaddr *start);
29
31
+uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
32
void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base,
31
+ target_ulong *ret_value);
33
- hwaddr rom_size, void *fdt);
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
34
+ hwaddr rom_size,
33
target_ulong *ret_value,
35
+ uint32_t fdt_load_addr, void *fdt);
34
target_ulong new_value, target_ulong write_mask);
36
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
37
#endif /* RISCV_BOOT_H */
36
target_ulong new_value,
38
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
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
39
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/riscv/boot.c
46
--- a/target/riscv/csr.c
41
+++ b/hw/riscv/boot.c
47
+++ b/target/riscv/csr.c
42
@@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
43
return *start + size;
49
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
51
int csrno,
52
- bool write_mask)
53
+ bool write)
54
{
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
56
bool read_only = get_field(csrno, 0xC00) == 3;
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
58
}
59
60
/* read / write check */
61
- if (write_mask && read_only) {
62
+ if (write && read_only) {
63
return RISCV_EXCP_ILLEGAL_INST;
64
}
65
66
@@ -XXX,XX +XXX,XX @@ static RISCVException riscv_csrrw_do64(CPURISCVState *env, int csrno,
67
return RISCV_EXCP_NONE;
44
}
68
}
45
69
46
+uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
71
+ target_ulong *ret_value)
47
+{
72
+{
48
+ uint32_t temp, fdt_addr;
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
49
+ hwaddr dram_end = dram_base + mem_size;
74
+ if (ret != RISCV_EXCP_NONE) {
50
+ int fdtsize = fdt_totalsize(fdt);
75
+ return ret;
76
+ }
51
+
77
+
52
+ if (fdtsize <= 0) {
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
53
+ error_report("invalid device-tree");
79
+}
54
+ exit(1);
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;
92
}
93
94
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
95
+ Int128 *ret_value)
96
+{
97
+ RISCVException ret;
98
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
100
+ if (ret != RISCV_EXCP_NONE) {
101
+ return ret;
102
+ }
103
+
104
+ if (csr_ops[csrno].read128) {
105
+ return riscv_csrrw_do128(env, csrno, ret_value,
106
+ int128_zero(), int128_zero());
55
+ }
107
+ }
56
+
108
+
57
+ /*
109
+ /*
58
+ * We should put fdt as far as possible to avoid kernel/initrd overwriting
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
59
+ * its content. But it should be addressable by 32 bit system as well.
111
+ * at all defined.
60
+ * Thus, put it at an aligned address that less than fdt size from end of
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
61
+ * dram or 4GB whichever is lesser.
113
+ * significant), for those, this fallback is correctly handling the
114
+ * accesses
62
+ */
115
+ */
63
+ temp = MIN(dram_end, 4096 * MiB);
116
+ target_ulong old_value;
64
+ fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
65
+
118
+ (target_ulong)0,
66
+ fdt_pack(fdt);
119
+ (target_ulong)0);
67
+ /* copy in the device tree */
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
68
+ qemu_fdt_dumpdtb(fdt, fdtsize);
121
+ *ret_value = int128_make64(old_value);
69
+
122
+ }
70
+ rom_add_blob_fixed_as("fdt", fdt, fdtsize, fdt_addr,
123
+ return ret;
71
+ &address_space_memory);
72
+
73
+ return fdt_addr;
74
+}
124
+}
75
+
125
+
76
void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
77
- hwaddr rom_size, void *fdt)
127
Int128 *ret_value,
78
+ hwaddr rom_size,
128
Int128 new_value, Int128 write_mask)
79
+ uint32_t fdt_load_addr, void *fdt)
80
{
129
{
81
int i;
130
RISCVException ret;
82
131
83
/* reset vector */
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
84
- uint32_t reset_vec[8] = {
133
+ ret = riscv_csrrw_check(env, csrno, true);
85
+ uint32_t reset_vec[10] = {
134
if (ret != RISCV_EXCP_NONE) {
86
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
135
return ret;
87
- 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
88
0xf1402573, /* csrr a0, mhartid */
89
#if defined(TARGET_RISCV32)
90
+ 0x0202a583, /* lw a1, 32(t0) */
91
0x0182a283, /* lw t0, 24(t0) */
92
#elif defined(TARGET_RISCV64)
93
+ 0x0202b583, /* ld a1, 32(t0) */
94
0x0182b283, /* ld t0, 24(t0) */
95
#endif
96
0x00028067, /* jr t0 */
97
0x00000000,
98
start_addr, /* start: .dword */
99
+ 0x00000000,
100
+ fdt_load_addr, /* fdt_laddr: .dword */
101
0x00000000,
102
/* dtb: */
103
};
104
105
/* copy in the reset vector in little_endian byte order */
106
- for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
107
+ for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
108
reset_vec[i] = cpu_to_le32(reset_vec[i]);
109
}
136
}
110
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
111
rom_base, &address_space_memory);
112
113
- /* copy in the device tree */
114
- if (fdt_pack(fdt) || fdt_totalsize(fdt) >
115
- rom_size - sizeof(reset_vec)) {
116
- error_report("not enough space to store device-tree");
117
- exit(1);
118
- }
119
- qemu_fdt_dumpdtb(fdt, fdt_totalsize(fdt));
120
- rom_add_blob_fixed_as("mrom.fdt", fdt, fdt_totalsize(fdt),
121
- rom_base + sizeof(reset_vec),
122
- &address_space_memory);
123
-
124
return;
125
}
126
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
127
index XXXXXXX..XXXXXXX 100644
138
index XXXXXXX..XXXXXXX 100644
128
--- a/hw/riscv/sifive_u.c
139
--- a/target/riscv/op_helper.c
129
+++ b/hw/riscv/sifive_u.c
140
+++ b/target/riscv/op_helper.c
130
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
131
MemoryRegion *flash0 = g_new(MemoryRegion, 1);
132
target_ulong start_addr = memmap[SIFIVE_U_DRAM].base;
133
int i;
134
+ uint32_t fdt_load_addr;
135
136
/* Initialize SoC */
137
object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
138
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
139
}
140
}
142
}
141
143
142
+ /* Compute the fdt load address in dram */
144
target_ulong val = 0;
143
+ fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DRAM].base,
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
144
+ machine->ram_size, s->fdt);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
145
+
147
146
/* reset vector */
148
if (ret != RISCV_EXCP_NONE) {
147
- uint32_t reset_vec[8] = {
149
riscv_raise_exception(env, ret, GETPC());
148
+ uint32_t reset_vec[11] = {
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
149
s->msel, /* MSEL pin state */
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
150
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
152
{
151
- 0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
153
Int128 rv = int128_zero();
152
0xf1402573, /* csrr a0, mhartid */
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
153
#if defined(TARGET_RISCV32)
155
- int128_zero(),
154
+ 0x0202a583, /* lw a1, 32(t0) */
156
- int128_zero());
155
0x0182a283, /* lw t0, 24(t0) */
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
156
#elif defined(TARGET_RISCV64)
158
157
- 0x0182e283, /* lwu t0, 24(t0) */
159
if (ret != RISCV_EXCP_NONE) {
158
+ 0x0202b583, /* ld a1, 32(t0) */
160
riscv_raise_exception(env, ret, GETPC());
159
+ 0x0182b283, /* ld t0, 24(t0) */
160
#endif
161
0x00028067, /* jr t0 */
162
0x00000000,
163
start_addr, /* start: .dword */
164
+ 0x00000000,
165
+ fdt_load_addr, /* fdt_laddr: .dword */
166
+ 0x00000000,
167
/* dtb: */
168
};
169
170
/* copy in the reset vector in little_endian byte order */
171
- for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
172
+ for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
173
reset_vec[i] = cpu_to_le32(reset_vec[i]);
174
}
175
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
176
memmap[SIFIVE_U_MROM].base, &address_space_memory);
177
-
178
- /* copy in the device tree */
179
- if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) >
180
- memmap[SIFIVE_U_MROM].size - sizeof(reset_vec)) {
181
- error_report("not enough space to store device-tree");
182
- exit(1);
183
- }
184
- qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt));
185
- rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt),
186
- memmap[SIFIVE_U_MROM].base + sizeof(reset_vec),
187
- &address_space_memory);
188
}
189
190
static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp)
191
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/hw/riscv/spike.c
194
+++ b/hw/riscv/spike.c
195
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
196
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
197
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
198
unsigned int smp_cpus = machine->smp.cpus;
199
+ uint32_t fdt_load_addr;
200
201
/* Initialize SOC */
202
object_initialize_child(OBJECT(machine), "soc", &s->soc,
203
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
204
}
205
}
206
207
+ /* Compute the fdt load address in dram */
208
+ fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
209
+ machine->ram_size, s->fdt);
210
/* load the reset vector */
211
riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base,
212
- memmap[SPIKE_MROM].size, s->fdt);
213
+ memmap[SPIKE_MROM].size,
214
+ fdt_load_addr, s->fdt);
215
216
/* initialize HTIF using symbols found in load_kernel */
217
htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0));
218
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
219
index XXXXXXX..XXXXXXX 100644
220
--- a/hw/riscv/virt.c
221
+++ b/hw/riscv/virt.c
222
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
223
char *plic_hart_config;
224
size_t plic_hart_config_len;
225
target_ulong start_addr = memmap[VIRT_DRAM].base;
226
+ uint32_t fdt_load_addr;
227
int i;
228
unsigned int smp_cpus = machine->smp.cpus;
229
230
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
231
start_addr = virt_memmap[VIRT_FLASH].base;
232
}
233
234
+ /* Compute the fdt load address in dram */
235
+ fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
236
+ machine->ram_size, s->fdt);
237
/* load the reset vector */
238
riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base,
239
- virt_memmap[VIRT_MROM].size, s->fdt);
240
+ virt_memmap[VIRT_MROM].size,
241
+ fdt_load_addr, s->fdt);
242
243
/* create PLIC hart topology configuration string */
244
plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpus;
245
--
161
--
246
2.27.0
162
2.45.1
247
248
diff view generated by jsdifflib