1
The following changes since commit ad10b4badc1dd5b28305f9b9f1168cf0aa3ae946:
1
The following changes since commit 4d285821c5055ed68a6f6b7693fd11a06a1aa426:
2
2
3
Merge tag 'pull-error-2024-05-27' of https://repo.or.cz/qemu/armbru into staging (2024-05-27 06:40:42 -0700)
3
Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20200618' into staging (2020-06-19 11:44:03 +0100)
4
4
5
are available in the Git repository at:
5
are available in the Git repository at:
6
6
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240528
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20200619-3
8
8
9
for you to fetch changes up to 1806da76cb81088ea026ca3441551782b850e393:
9
for you to fetch changes up to 3eaea6eb4e534f7b87c6eca808149bb671976800:
10
10
11
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR (2024-05-28 12:20:27 +1000)
11
hw/riscv: sifive_u: Add a dummy DDR memory controller device (2020-06-19 08:25:27 -0700)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
RISC-V PR for 9.1
14
This is a range of patches for RISC-V.
15
15
16
* APLICs add child earlier than realize
16
Some key points are:
17
* Fix exposure of Zkr
17
- Generalise the CPU init functions
18
* Raise exceptions on wrs.nto
18
- Support the SiFive revB machine
19
* Implement SBI debug console (DBCN) calls for KVM
19
- Improvements to the Hypervisor implementation and error checking
20
* Support 64-bit addresses for initrd
20
- Connect some OpenTitan devices
21
* Change RISCV_EXCP_SEMIHOST exception number to 63
21
- Changes to the sifive_u machine to support U-boot
22
* Tolerate KVM disable ext errors
22
23
* Set tval in breakpoints
23
v2:
24
* Add support for Zve32x extension
24
- Fix missing realise assert
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
43
25
44
----------------------------------------------------------------
26
----------------------------------------------------------------
45
Alexei Filippov (1):
27
Alistair Francis (11):
46
target/riscv: do not set mtval2 for non guest-page faults
28
sifive_e: Support the revB machine
29
target/riscv: Set access as data_load when validating stage-2 PTEs
30
target/riscv: Report errors validating 2nd-stage PTEs
31
target/riscv: Move the hfence instructions to the rvh decode
32
target/riscv: Implement checks for hfence
33
riscv/opentitan: Fix the ROM size
34
hw/char: Initial commit of Ibex UART
35
hw/intc: Initial commit of lowRISC Ibex PLIC
36
riscv/opentitan: Connect the PLIC device
37
riscv/opentitan: Connect the UART device
38
target/riscv: Use a smaller guess size for no-MMU PMP
47
39
48
Alistair Francis (2):
40
Bin Meng (20):
49
target/riscv: rvzicbo: Fixup CBO extension register calculation
41
riscv: Generalize CPU init routine for the base CPU
50
disas/riscv: Decode all of the pmpcfg and pmpaddr CSRs
42
riscv: Generalize CPU init routine for the gcsu CPU
43
riscv: Generalize CPU init routine for the imacu CPU
44
riscv: Keep the CPU init routine names consistent
45
hw/riscv: sifive_e: Remove the riscv_ prefix of the machine* and soc* functions
46
hw/riscv: opentitan: Remove the riscv_ prefix of the machine* and soc* functions
47
hw/riscv: sifive_u: Simplify the GEM IRQ connect code a little bit
48
hw/riscv: sifive_u: Generate device tree node for OTP
49
hw/riscv: sifive_gpio: Clean up the codes
50
hw/riscv: sifive_gpio: Add a new 'ngpio' property
51
hw/riscv: sifive_u: Hook a GPIO controller
52
hw/riscv: sifive_gpio: Do not blindly trigger output IRQs
53
hw/riscv: sifive_u: Add reset functionality
54
hw/riscv: sifive_u: Rename serial property get/set functions to a generic name
55
hw/riscv: sifive_u: Add a new property msel for MSEL pin state
56
target/riscv: Rename IBEX CPU init routine
57
hw/riscv: sifive: Change SiFive E/U CPU reset vector to 0x1004
58
hw/riscv: sifive_u: Support different boot source per MSEL pin state
59
hw/riscv: sifive_u: Sort the SoC memmap table entries
60
hw/riscv: sifive_u: Add a dummy DDR memory controller device
51
61
52
Andrew Jones (2):
62
Ian Jiang (1):
53
target/riscv/kvm: Fix exposure of Zkr
63
riscv: Add helper to make NaN-boxing for FP register
54
target/riscv: Raise exceptions on wrs.nto
55
64
56
Cheng Yang (1):
65
include/hw/char/ibex_uart.h | 110 ++++++
57
hw/riscv/boot.c: Support 64-bit address for initrd
66
include/hw/intc/ibex_plic.h | 63 ++++
67
include/hw/riscv/opentitan.h | 16 +
68
include/hw/riscv/sifive_e.h | 1 +
69
include/hw/riscv/sifive_gpio.h | 8 +-
70
include/hw/riscv/sifive_u.h | 27 ++
71
target/riscv/helper.h | 5 +
72
target/riscv/insn32.decode | 8 +-
73
hw/char/ibex_uart.c | 492 +++++++++++++++++++++++++
74
hw/intc/ibex_plic.c | 261 +++++++++++++
75
hw/riscv/opentitan.c | 71 +++-
76
hw/riscv/sifive_e.c | 60 ++-
77
hw/riscv/sifive_gpio.c | 45 ++-
78
hw/riscv/sifive_u.c | 157 ++++++--
79
target/riscv/cpu.c | 69 ++--
80
target/riscv/cpu_helper.c | 9 +-
81
target/riscv/insn_trans/trans_privileged.inc.c | 38 --
82
target/riscv/insn_trans/trans_rvf.inc.c | 17 +-
83
target/riscv/insn_trans/trans_rvh.inc.c | 37 ++
84
target/riscv/op_helper.c | 13 +
85
target/riscv/pmp.c | 14 +-
86
target/riscv/translate.c | 1 +
87
MAINTAINERS | 4 +
88
hw/char/Makefile.objs | 1 +
89
hw/intc/Makefile.objs | 1 +
90
hw/riscv/Kconfig | 4 +
91
26 files changed, 1350 insertions(+), 182 deletions(-)
92
create mode 100644 include/hw/char/ibex_uart.h
93
create mode 100644 include/hw/intc/ibex_plic.h
94
create mode 100644 hw/char/ibex_uart.c
95
create mode 100644 hw/intc/ibex_plic.c
96
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
58
97
59
Christoph Müllner (1):
60
riscv: thead: Add th.sxstatus CSR emulation
61
62
Clément Léger (1):
63
target/riscv: change RISCV_EXCP_SEMIHOST exception number to 63
64
65
Daniel Henrique Barboza (6):
66
target/riscv/kvm: implement SBI debug console (DBCN) calls
67
target/riscv/kvm: tolerate KVM disable ext errors
68
target/riscv/debug: set tval=pc in breakpoint exceptions
69
trans_privileged.c.inc: set (m|s)tval on ebreak breakpoint
70
target/riscv: prioritize pmp errors in raise_mmu_exception()
71
riscv, gdbstub.c: fix reg_width in ricsv_gen_dynamic_vector_feature()
72
73
Huang Tao (2):
74
target/riscv: Fix the element agnostic function problem
75
target/riscv: Implement dynamic establishment of custom decoder
76
77
Jason Chien (3):
78
target/riscv: Add support for Zve32x extension
79
target/riscv: Add support for Zve64x extension
80
target/riscv: Relax vector register check in RISCV gdbstub
81
82
Max Chou (4):
83
target/riscv: rvv: Fix Zvfhmin checking for vfwcvt.f.f.v and vfncvt.f.f.w instructions
84
target/riscv: rvv: Check single width operator for vector fp widen instructions
85
target/riscv: rvv: Check single width operator for vfncvt.rod.f.f.w
86
target/riscv: rvv: Remove redudant SEW checking for vector fp narrow/widen instructions
87
88
Rob Bradford (1):
89
target/riscv: Remove experimental prefix from "B" extension
90
91
Yangyu Chen (1):
92
target/riscv/cpu.c: fix Zvkb extension config
93
94
Yong-Xuan Wang (1):
95
target/riscv/kvm.c: Fix the hart bit setting of AIA
96
97
Yu-Ming Chang (1):
98
target/riscv: raise an exception when CSRRS/CSRRC writes a read-only CSR
99
100
yang.zhang (1):
101
hw/intc/riscv_aplic: APLICs should add child earlier than realize
102
103
MAINTAINERS | 1 +
104
target/riscv/cpu.h | 11 ++
105
target/riscv/cpu_bits.h | 2 +-
106
target/riscv/cpu_cfg.h | 2 +
107
target/riscv/helper.h | 1 +
108
target/riscv/sbi_ecall_interface.h | 17 +++
109
target/riscv/tcg/tcg-cpu.h | 15 +++
110
disas/riscv.c | 65 +++++++++-
111
hw/intc/riscv_aplic.c | 8 +-
112
hw/riscv/boot.c | 4 +-
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
1
From: Alexei Filippov <alexei.filippov@syntacore.com>
1
From: Ian Jiang <ianjiang.ict@gmail.com>
2
2
3
Previous patch fixed the PMP priority in raise_mmu_exception() but we're still
3
The function that makes NaN-boxing when a 32-bit value is assigned
4
setting mtval2 incorrectly. In riscv_cpu_tlb_fill(), after pmp check in 2 stage
4
to a 64-bit FP register is split out to a helper gen_nanbox_fpr().
5
translation part, mtval2 will be set in case of successes 2 stage translation but
5
Then it is applied in translating of the FLW instruction.
6
failed pmp check.
7
6
8
In this case we gonna set mtval2 via env->guest_phys_fault_addr in context of
7
Signed-off-by: Ian Jiang <ianjiang.ict@gmail.com>
9
riscv_cpu_tlb_fill(), as this was a guest-page-fault, but it didn't and mtval2
8
Message-Id: <20200128003707.17028-1-ianjiang.ict@gmail.com>
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>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-ID: <20240503103052.6819-1-alexei.filippov@syntacore.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Cc: qemu-stable <qemu-stable@nongnu.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
12
---
22
target/riscv/cpu_helper.c | 12 ++++++------
13
target/riscv/insn_trans/trans_rvf.inc.c | 17 +++++++++++++++--
23
1 file changed, 6 insertions(+), 6 deletions(-)
14
1 file changed, 15 insertions(+), 2 deletions(-)
24
15
25
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
diff --git a/target/riscv/insn_trans/trans_rvf.inc.c b/target/riscv/insn_trans/trans_rvf.inc.c
26
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/cpu_helper.c
18
--- a/target/riscv/insn_trans/trans_rvf.inc.c
28
+++ b/target/riscv/cpu_helper.c
19
+++ b/target/riscv/insn_trans/trans_rvf.inc.c
29
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
20
@@ -XXX,XX +XXX,XX @@
30
__func__, pa, ret, prot_pmp, tlb_size);
21
return false; \
31
22
} while (0)
32
prot &= prot_pmp;
23
33
- }
24
+/*
34
-
25
+ * RISC-V requires NaN-boxing of narrower width floating
35
- if (ret != TRANSLATE_SUCCESS) {
26
+ * point values. This applies when a 32-bit value is
36
+ } else {
27
+ * assigned to a 64-bit FP register. Thus this does not
37
/*
28
+ * apply when the RVD extension is not present.
38
* Guest physical address translation failed, this is a HS
29
+ */
39
* level exception
30
+static void gen_nanbox_fpr(DisasContext *ctx, int regno)
40
*/
31
+{
41
first_stage_error = false;
32
+ if (has_ext(ctx, RVD)) {
42
- env->guest_phys_fault_addr = (im_address |
33
+ tcg_gen_ori_i64(cpu_fpr[regno], cpu_fpr[regno],
43
- (address &
34
+ MAKE_64BIT_MASK(32, 32));
44
- (TARGET_PAGE_SIZE - 1))) >> 2;
35
+ }
45
+ if (ret != TRANSLATE_PMP_FAIL) {
36
+}
46
+ env->guest_phys_fault_addr = (im_address |
37
+
47
+ (address &
38
static bool trans_flw(DisasContext *ctx, arg_flw *a)
48
+ (TARGET_PAGE_SIZE - 1))) >> 2;
39
{
49
+ }
40
TCGv t0 = tcg_temp_new();
50
}
41
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
51
}
42
tcg_gen_addi_tl(t0, t0, a->imm);
52
} else {
43
44
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], t0, ctx->mem_idx, MO_TEUL);
45
- /* RISC-V requires NaN-boxing of narrower width floating point values */
46
- tcg_gen_ori_i64(cpu_fpr[a->rd], cpu_fpr[a->rd], 0xffffffff00000000ULL);
47
+ gen_nanbox_fpr(ctx, a->rd);
48
49
tcg_temp_free(t0);
50
mark_fs_dirty(ctx);
53
--
51
--
54
2.45.1
52
2.27.0
53
54
diff view generated by jsdifflib
1
From: Yu-Ming Chang <yumin686@andestech.com>
2
3
Both CSRRS and CSRRC always read the addressed CSR and cause any read side
4
effects regardless of rs1 and rd fields. Note that if rs1 specifies a register
5
holding a zero value other than x0, the instruction will still attempt to write
6
the unmodified value back to the CSR and will cause any attendant side effects.
7
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>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20240403070823.80897-1-yumin686@andestech.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
2
---
17
target/riscv/cpu.h | 4 ++++
3
include/hw/riscv/sifive_e.h | 1 +
18
target/riscv/csr.c | 51 ++++++++++++++++++++++++++++++++++++----
4
hw/riscv/sifive_e.c | 34 ++++++++++++++++++++++++++++++----
19
target/riscv/op_helper.c | 6 ++---
5
2 files changed, 31 insertions(+), 4 deletions(-)
20
3 files changed, 53 insertions(+), 8 deletions(-)
21
6
22
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
7
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
23
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.h
9
--- a/include/hw/riscv/sifive_e.h
25
+++ b/target/riscv/cpu.h
10
+++ b/include/hw/riscv/sifive_e.h
26
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc,
11
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveEState {
27
void riscv_cpu_update_mask(CPURISCVState *env);
12
28
bool riscv_cpu_is_32bit(RISCVCPU *cpu);
13
/*< public >*/
29
14
SiFiveESoCState soc;
30
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
15
+ bool revb;
31
+ target_ulong *ret_value);
16
} SiFiveEState;
32
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
17
33
target_ulong *ret_value,
18
#define TYPE_RISCV_E_MACHINE MACHINE_TYPE_NAME("sifive_e")
34
target_ulong new_value, target_ulong write_mask);
19
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
35
@@ -XXX,XX +XXX,XX @@ typedef RISCVException (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
36
target_ulong new_value,
37
target_ulong write_mask);
38
39
+RISCVException riscv_csrr_i128(CPURISCVState *env, int csrno,
40
+ Int128 *ret_value);
41
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
42
Int128 *ret_value,
43
Int128 new_value, Int128 write_mask);
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
45
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
46
--- a/target/riscv/csr.c
21
--- a/hw/riscv/sifive_e.c
47
+++ b/target/riscv/csr.c
22
+++ b/hw/riscv/sifive_e.c
48
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
23
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
49
24
memmap[SIFIVE_E_DTIM].base, main_mem);
50
static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
25
51
int csrno,
26
/* Mask ROM reset vector */
52
- bool write_mask)
27
- uint32_t reset_vec[2] = {
53
+ bool write)
28
- 0x204002b7, /* 0x1000: lui t0,0x20400 */
54
{
29
- 0x00028067, /* 0x1004: jr t0 */
55
/* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */
30
- };
56
bool read_only = get_field(csrno, 0xC00) == 3;
31
+ uint32_t reset_vec[2];
57
@@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
32
+
33
+ if (s->revb) {
34
+ reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
35
+ } else {
36
+ reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
37
+ }
38
+ reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
39
40
/* copy in the reset vector in little_endian byte order */
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
42
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_init(MachineState *machine)
58
}
43
}
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;
68
}
44
}
69
45
70
+RISCVException riscv_csrr(CPURISCVState *env, int csrno,
46
+static bool sifive_e_machine_get_revb(Object *obj, Error **errp)
71
+ target_ulong *ret_value)
72
+{
47
+{
73
+ RISCVException ret = riscv_csrrw_check(env, csrno, false);
48
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
74
+ if (ret != RISCV_EXCP_NONE) {
75
+ return ret;
76
+ }
77
+
49
+
78
+ return riscv_csrrw_do64(env, csrno, ret_value, 0, 0);
50
+ return s->revb;
79
+}
51
+}
80
+
52
+
81
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
53
+static void sifive_e_machine_set_revb(Object *obj, bool value, Error **errp)
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
+{
54
+{
97
+ RISCVException ret;
55
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
98
+
56
+
99
+ ret = riscv_csrrw_check(env, csrno, false);
57
+ s->revb = value;
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());
107
+ }
108
+
109
+ /*
110
+ * Fall back to 64-bit version for now, if the 128-bit alternative isn't
111
+ * at all defined.
112
+ * Note, some CSRs don't need to extend to MXLEN (64 upper bits non
113
+ * significant), for those, this fallback is correctly handling the
114
+ * accesses
115
+ */
116
+ target_ulong old_value;
117
+ ret = riscv_csrrw_do64(env, csrno, &old_value,
118
+ (target_ulong)0,
119
+ (target_ulong)0);
120
+ if (ret == RISCV_EXCP_NONE && ret_value) {
121
+ *ret_value = int128_make64(old_value);
122
+ }
123
+ return ret;
124
+}
58
+}
125
+
59
+
126
RISCVException riscv_csrrw_i128(CPURISCVState *env, int csrno,
60
static void sifive_e_machine_instance_init(Object *obj)
127
Int128 *ret_value,
128
Int128 new_value, Int128 write_mask)
129
{
61
{
130
RISCVException ret;
62
+ SiFiveEState *s = RISCV_E_MACHINE(obj);
131
63
+
132
- ret = riscv_csrrw_check(env, csrno, int128_nz(write_mask));
64
+ s->revb = false;
133
+ ret = riscv_csrrw_check(env, csrno, true);
65
+ object_property_add_bool(obj, "revb", sifive_e_machine_get_revb,
134
if (ret != RISCV_EXCP_NONE) {
66
+ sifive_e_machine_set_revb);
135
return ret;
67
+ object_property_set_description(obj, "revb",
136
}
68
+ "Set on to tell QEMU that it should model "
137
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
69
+ "the revB HiFive1 board");
138
index XXXXXXX..XXXXXXX 100644
70
}
139
--- a/target/riscv/op_helper.c
71
140
+++ b/target/riscv/op_helper.c
72
static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
141
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
142
}
143
144
target_ulong val = 0;
145
- RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0);
146
+ RISCVException ret = riscv_csrr(env, csr, &val);
147
148
if (ret != RISCV_EXCP_NONE) {
149
riscv_raise_exception(env, ret, GETPC());
150
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw(CPURISCVState *env, int csr,
151
target_ulong helper_csrr_i128(CPURISCVState *env, int csr)
152
{
153
Int128 rv = int128_zero();
154
- RISCVException ret = riscv_csrrw_i128(env, csr, &rv,
155
- int128_zero(),
156
- int128_zero());
157
+ RISCVException ret = riscv_csrr_i128(env, csr, &rv);
158
159
if (ret != RISCV_EXCP_NONE) {
160
riscv_raise_exception(env, ret, GETPC());
161
--
73
--
162
2.45.1
74
2.27.0
75
76
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Previously we only listed a single pmpcfg CSR and the first 16 pmpaddr
3
There is no need to have two functions that have exactly the same
4
CSRs. This patch fixes this to list all 16 pmpcfg and all 64 pmpaddr
4
codes for 32-bit and 64-bit base CPUs.
5
CSRs are part of the disassembly.
6
5
7
Reported-by: Eric DeVolder <eric_devolder@yahoo.com>
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Fixes: ea10325917 ("RISC-V Disassembler")
8
Message-id: 1591837729-27486-1-git-send-email-bmeng.cn@gmail.com
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <1591837729-27486-1-git-send-email-bmeng.cn@gmail.com>
11
Cc: qemu-stable <qemu-stable@nongnu.org>
12
Message-ID: <20240514051615.330979-1-alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
11
---
15
disas/riscv.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++-
12
target/riscv/cpu.c | 18 +++++-------------
16
1 file changed, 64 insertions(+), 1 deletion(-)
13
1 file changed, 5 insertions(+), 13 deletions(-)
17
14
18
diff --git a/disas/riscv.c b/disas/riscv.c
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/disas/riscv.c
17
--- a/target/riscv/cpu.c
21
+++ b/disas/riscv.c
18
+++ b/target/riscv/cpu.c
22
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
19
@@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj)
23
case 0x0383: return "mibound";
20
set_resetvec(env, DEFAULT_RSTVEC);
24
case 0x0384: return "mdbase";
21
}
25
case 0x0385: return "mdbound";
22
26
- case 0x03a0: return "pmpcfg3";
23
-#if defined(TARGET_RISCV32)
27
+ case 0x03a0: return "pmpcfg0";
24
-
28
+ case 0x03a1: return "pmpcfg1";
25
-static void riscv_base32_cpu_init(Object *obj)
29
+ case 0x03a2: return "pmpcfg2";
26
+static void riscv_base_cpu_init(Object *obj)
30
+ case 0x03a3: return "pmpcfg3";
27
{
31
+ case 0x03a4: return "pmpcfg4";
28
CPURISCVState *env = &RISCV_CPU(obj)->env;
32
+ case 0x03a5: return "pmpcfg5";
29
/* We set this in the realise function */
33
+ case 0x03a6: return "pmpcfg6";
30
@@ -XXX,XX +XXX,XX @@ static void riscv_base32_cpu_init(Object *obj)
34
+ case 0x03a7: return "pmpcfg7";
31
set_resetvec(env, DEFAULT_RSTVEC);
35
+ case 0x03a8: return "pmpcfg8";
32
}
36
+ case 0x03a9: return "pmpcfg9";
33
37
+ case 0x03aa: return "pmpcfg10";
34
+#if defined(TARGET_RISCV32)
38
+ case 0x03ab: return "pmpcfg11";
35
+
39
+ case 0x03ac: return "pmpcfg12";
36
static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
40
+ case 0x03ad: return "pmpcfg13";
37
{
41
+ case 0x03ae: return "pmpcfg14";
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
42
+ case 0x03af: return "pmpcfg15";
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
43
case 0x03b0: return "pmpaddr0";
40
44
case 0x03b1: return "pmpaddr1";
41
#elif defined(TARGET_RISCV64)
45
case 0x03b2: return "pmpaddr2";
42
46
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
43
-static void riscv_base64_cpu_init(Object *obj)
47
case 0x03bd: return "pmpaddr13";
44
-{
48
case 0x03be: return "pmpaddr14";
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
49
case 0x03bf: return "pmpaddr15";
46
- /* We set this in the realise function */
50
+ case 0x03c0: return "pmpaddr16";
47
- set_misa(env, 0);
51
+ case 0x03c1: return "pmpaddr17";
48
- set_resetvec(env, DEFAULT_RSTVEC);
52
+ case 0x03c2: return "pmpaddr18";
49
-}
53
+ case 0x03c3: return "pmpaddr19";
50
-
54
+ case 0x03c4: return "pmpaddr20";
51
static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
55
+ case 0x03c5: return "pmpaddr21";
52
{
56
+ case 0x03c6: return "pmpaddr22";
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
57
+ case 0x03c7: return "pmpaddr23";
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
58
+ case 0x03c8: return "pmpaddr24";
55
},
59
+ case 0x03c9: return "pmpaddr25";
56
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
60
+ case 0x03ca: return "pmpaddr26";
57
#if defined(TARGET_RISCV32)
61
+ case 0x03cb: return "pmpaddr27";
58
- DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init),
62
+ case 0x03cc: return "pmpaddr28";
59
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
63
+ case 0x03cd: return "pmpaddr29";
60
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
64
+ case 0x03ce: return "pmpaddr30";
61
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
65
+ case 0x03cf: return "pmpaddr31";
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
66
+ case 0x03d0: return "pmpaddr32";
63
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
67
+ case 0x03d1: return "pmpaddr33";
64
#elif defined(TARGET_RISCV64)
68
+ case 0x03d2: return "pmpaddr34";
65
- DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base64_cpu_init),
69
+ case 0x03d3: return "pmpaddr35";
66
+ DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
70
+ case 0x03d4: return "pmpaddr36";
67
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
71
+ case 0x03d5: return "pmpaddr37";
68
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
72
+ case 0x03d6: return "pmpaddr38";
69
#endif
73
+ case 0x03d7: return "pmpaddr39";
74
+ case 0x03d8: return "pmpaddr40";
75
+ case 0x03d9: return "pmpaddr41";
76
+ case 0x03da: return "pmpaddr42";
77
+ case 0x03db: return "pmpaddr43";
78
+ case 0x03dc: return "pmpaddr44";
79
+ case 0x03dd: return "pmpaddr45";
80
+ case 0x03de: return "pmpaddr46";
81
+ case 0x03df: return "pmpaddr47";
82
+ case 0x03e0: return "pmpaddr48";
83
+ case 0x03e1: return "pmpaddr49";
84
+ case 0x03e2: return "pmpaddr50";
85
+ case 0x03e3: return "pmpaddr51";
86
+ case 0x03e4: return "pmpaddr52";
87
+ case 0x03e5: return "pmpaddr53";
88
+ case 0x03e6: return "pmpaddr54";
89
+ case 0x03e7: return "pmpaddr55";
90
+ case 0x03e8: return "pmpaddr56";
91
+ case 0x03e9: return "pmpaddr57";
92
+ case 0x03ea: return "pmpaddr58";
93
+ case 0x03eb: return "pmpaddr59";
94
+ case 0x03ec: return "pmpaddr60";
95
+ case 0x03ed: return "pmpaddr61";
96
+ case 0x03ee: return "pmpaddr62";
97
+ case 0x03ef: return "pmpaddr63";
98
case 0x0780: return "mtohost";
99
case 0x0781: return "mfromhost";
100
case 0x0782: return "mreset";
101
--
70
--
102
2.45.1
71
2.27.0
72
73
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Add support for Zve64x extension. Enabling Zve64f enables Zve64x and
3
There is no need to have two functions that have almost the same
4
enabling Zve64x enables Zve32x according to their dependency.
4
codes for 32-bit and 64-bit gcsu CPUs.
5
5
6
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2107
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Jason Chien <jason.chien@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Message-Id: <1591837729-27486-2-git-send-email-bmeng.cn@gmail.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>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
10
---
14
target/riscv/cpu_cfg.h | 1 +
11
target/riscv/cpu.c | 20 ++++++--------------
15
target/riscv/cpu.c | 2 ++
12
1 file changed, 6 insertions(+), 14 deletions(-)
16
target/riscv/tcg/tcg-cpu.c | 17 +++++++++++------
17
3 files changed, 14 insertions(+), 6 deletions(-)
18
13
19
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_cfg.h
22
+++ b/target/riscv/cpu_cfg.h
23
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
24
bool ext_zve32x;
25
bool ext_zve64f;
26
bool ext_zve64d;
27
+ bool ext_zve64x;
28
bool ext_zvbb;
29
bool ext_zvbc;
30
bool ext_zvkb;
31
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu.c
16
--- a/target/riscv/cpu.c
34
+++ b/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
35
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
18
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
36
ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
19
set_resetvec(env, DEFAULT_RSTVEC);
37
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
20
}
38
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
21
39
+ ISA_EXT_DATA_ENTRY(zve64x, PRIV_VERSION_1_10_0, ext_zve64x),
22
-#if defined(TARGET_RISCV32)
40
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
23
-
41
ISA_EXT_DATA_ENTRY(zvfbfwma, PRIV_VERSION_1_12_0, ext_zvfbfwma),
24
-static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
42
ISA_EXT_DATA_ENTRY(zvfh, PRIV_VERSION_1_12_0, ext_zvfh),
25
+static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
43
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
26
{
44
MULTI_EXT_CFG_BOOL("zve32x", ext_zve32x, false),
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
45
MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
28
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
46
MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
47
+ MULTI_EXT_CFG_BOOL("zve64x", ext_zve64x, false),
30
set_priv_version(env, PRIV_VERSION_1_10_0);
48
MULTI_EXT_CFG_BOOL("zvfbfmin", ext_zvfbfmin, false),
31
set_resetvec(env, DEFAULT_RSTVEC);
49
MULTI_EXT_CFG_BOOL("zvfbfwma", ext_zvfbfwma, false),
32
}
50
MULTI_EXT_CFG_BOOL("zvfh", ext_zvfh, false),
33
51
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
34
+#if defined(TARGET_RISCV32)
52
index XXXXXXX..XXXXXXX 100644
35
+
53
--- a/target/riscv/tcg/tcg-cpu.c
36
static void rv32imcu_nommu_cpu_init(Object *obj)
54
+++ b/target/riscv/tcg/tcg-cpu.c
37
{
55
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
38
CPURISCVState *env = &RISCV_CPU(obj)->env;
56
39
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
57
/* The Zve64d extension depends on the Zve64f extension */
40
58
if (cpu->cfg.ext_zve64d) {
41
#elif defined(TARGET_RISCV64)
59
+ if (!riscv_has_ext(env, RVD)) {
42
60
+ error_setg(errp, "Zve64d/V extensions require D extension");
43
-static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
61
+ return;
44
-{
62
+ }
45
- CPURISCVState *env = &RISCV_CPU(obj)->env;
63
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64f), true);
46
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
64
}
47
- set_priv_version(env, PRIV_VERSION_1_10_0);
65
48
- set_resetvec(env, DEFAULT_RSTVEC);
66
- /* The Zve64f extension depends on the Zve32f extension */
49
-}
67
+ /* The Zve64f extension depends on the Zve64x and Zve32f extensions */
50
-
68
if (cpu->cfg.ext_zve64f) {
51
static void rv64imacu_nommu_cpu_init(Object *obj)
69
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve64x), true);
52
{
70
cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32f), true);
53
CPURISCVState *env = &RISCV_CPU(obj)->env;
71
}
54
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
72
55
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
73
- if (cpu->cfg.ext_zve64d && !riscv_has_ext(env, RVD)) {
56
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
74
- error_setg(errp, "Zve64d/V extensions require D extension");
57
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
75
- return;
58
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init),
76
+ /* The Zve64x extension depends on the Zve32x extension */
59
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
77
+ if (cpu->cfg.ext_zve64x) {
60
#elif defined(TARGET_RISCV64)
78
+ cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zve32x), true);
61
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
79
}
62
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
80
63
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64gcsu_priv1_10_0_cpu_init),
81
/* The Zve32f extension depends on the Zve32x extension */
64
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
82
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
65
#endif
83
return;
66
};
84
}
85
86
- if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64f) {
87
+ if ((cpu->cfg.ext_zvbc || cpu->cfg.ext_zvknhb) && !cpu->cfg.ext_zve64x) {
88
error_setg(
89
errp,
90
- "Zvbc and Zvknhb extensions require V or Zve64{f,d} extensions");
91
+ "Zvbc and Zvknhb extensions require V or Zve64x extensions");
92
return;
93
}
94
67
95
--
68
--
96
2.45.1
69
2.27.0
70
71
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Add support for Zve32x extension and replace some checks for Zve32f with
3
There is no need to have two functions that have almost the same
4
Zve32x, since Zve32f depends on Zve32x.
4
codes for 32-bit and 64-bit imacu CPUs.
5
5
6
Signed-off-by: Jason Chien <jason.chien@sifive.com>
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Max Chou <max.chou@sifive.com>
8
Message-Id: <1591837729-27486-3-git-send-email-bmeng.cn@gmail.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>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
10
---
13
target/riscv/cpu_cfg.h | 1 +
11
target/riscv/cpu.c | 31 ++++++++++---------------------
14
target/riscv/cpu.c | 2 ++
12
1 file changed, 10 insertions(+), 21 deletions(-)
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
13
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
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
16
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
18
@@ -XXX,XX +XXX,XX @@ static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
38
ISA_EXT_DATA_ENTRY(zvbb, PRIV_VERSION_1_12_0, ext_zvbb),
19
set_resetvec(env, DEFAULT_RSTVEC);
39
ISA_EXT_DATA_ENTRY(zvbc, PRIV_VERSION_1_12_0, ext_zvbc),
20
}
40
ISA_EXT_DATA_ENTRY(zve32f, PRIV_VERSION_1_10_0, ext_zve32f),
21
41
+ ISA_EXT_DATA_ENTRY(zve32x, PRIV_VERSION_1_10_0, ext_zve32x),
22
-#if defined(TARGET_RISCV32)
42
ISA_EXT_DATA_ENTRY(zve64f, PRIV_VERSION_1_10_0, ext_zve64f),
23
-
43
ISA_EXT_DATA_ENTRY(zve64d, PRIV_VERSION_1_10_0, ext_zve64d),
24
-static void rv32imcu_nommu_cpu_init(Object *obj)
44
ISA_EXT_DATA_ENTRY(zvfbfmin, PRIV_VERSION_1_12_0, ext_zvfbfmin),
25
+static void rvxx_imacu_nommu_cpu_init(Object *obj)
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
{
26
{
74
- if (riscv_cpu_cfg(env)->ext_zve32f) {
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
75
+ if (riscv_cpu_cfg(env)->ext_zve32x) {
28
- set_misa(env, RV32 | RVI | RVM | RVC | RVU);
76
#if !defined(CONFIG_USER_ONLY)
29
+ set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
77
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
30
set_priv_version(env, PRIV_VERSION_1_10_0);
78
return RISCV_EXCP_ILLEGAL_INST;
31
- set_resetvec(env, 0x8090);
79
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
32
+ set_resetvec(env, DEFAULT_RSTVEC);
80
index XXXXXXX..XXXXXXX 100644
33
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
81
--- a/target/riscv/tcg/tcg-cpu.c
34
}
82
+++ b/target/riscv/tcg/tcg-cpu.c
35
83
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
36
-static void rv32imacu_nommu_cpu_init(Object *obj)
84
return;
37
+#if defined(TARGET_RISCV32)
85
}
38
+
86
39
+static void rv32imcu_nommu_cpu_init(Object *obj)
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
{
40
{
121
TCGv s1, dst;
41
CPURISCVState *env = &RISCV_CPU(obj)->env;
122
42
- set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
123
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
43
+ set_misa(env, RV32 | RVI | RVM | RVC | RVU);
124
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
44
set_priv_version(env, PRIV_VERSION_1_10_0);
125
return false;
45
- set_resetvec(env, DEFAULT_RSTVEC);
126
}
46
+ set_resetvec(env, 0x8090);
127
47
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
128
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
48
}
129
{
49
130
TCGv dst;
50
@@ -XXX,XX +XXX,XX @@ static void rv32imafcu_nommu_cpu_init(Object *obj)
131
51
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
132
- if (!require_rvv(s) || !s->cfg_ptr->ext_zve32f) {
52
}
133
+ if (!require_rvv(s) || !s->cfg_ptr->ext_zve32x) {
53
134
return false;
54
-#elif defined(TARGET_RISCV64)
135
}
55
-
136
56
-static void rv64imacu_nommu_cpu_init(Object *obj)
57
-{
58
- CPURISCVState *env = &RISCV_CPU(obj)->env;
59
- set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
60
- set_priv_version(env, PRIV_VERSION_1_10_0);
61
- set_resetvec(env, DEFAULT_RSTVEC);
62
- qdev_prop_set_bit(DEVICE(obj), "mmu", false);
63
-}
64
-
65
#endif
66
67
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
68
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
69
#if defined(TARGET_RISCV32)
70
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
71
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
72
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init),
73
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
74
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
75
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
76
#elif defined(TARGET_RISCV64)
77
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
78
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64imacu_nommu_cpu_init),
79
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
80
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
81
#endif
82
};
137
--
83
--
138
2.45.1
84
2.27.0
85
86
diff view generated by jsdifflib
1
From: Yangyu Chen <cyy@cyyself.name>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
This code has a typo that writes zvkb to zvkg, causing users can't
3
Adding a _ to keep some consistency among the CPU init routines.
4
enable zvkb through the config. This patch gets this fixed.
5
4
6
Signed-off-by: Yangyu Chen <cyy@cyyself.name>
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
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>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Max Chou <max.chou@sifive.com>
7
Message-Id: <1591837729-27486-4-git-send-email-bmeng.cn@gmail.com>
11
Reviewed-by:  Weiwei Li <liwei1518@gmail.com>
12
Message-ID: <tencent_7E34EEF0F90B9A68BF38BEE09EC6D4877C0A@qq.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
9
---
16
target/riscv/cpu.c | 2 +-
10
target/riscv/cpu.c | 8 ++++----
17
1 file changed, 1 insertion(+), 1 deletion(-)
11
1 file changed, 4 insertions(+), 4 deletions(-)
18
12
19
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.c
15
--- a/target/riscv/cpu.c
22
+++ b/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
23
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
17
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
24
/* Vector cryptography extensions */
18
25
MULTI_EXT_CFG_BOOL("zvbb", ext_zvbb, false),
19
#if defined(TARGET_RISCV32)
26
MULTI_EXT_CFG_BOOL("zvbc", ext_zvbc, false),
20
27
- MULTI_EXT_CFG_BOOL("zvkb", ext_zvkg, false),
21
-static void rv32imcu_nommu_cpu_init(Object *obj)
28
+ MULTI_EXT_CFG_BOOL("zvkb", ext_zvkb, false),
22
+static void rv32_imcu_nommu_cpu_init(Object *obj)
29
MULTI_EXT_CFG_BOOL("zvkg", ext_zvkg, false),
23
{
30
MULTI_EXT_CFG_BOOL("zvkned", ext_zvkned, false),
24
CPURISCVState *env = &RISCV_CPU(obj)->env;
31
MULTI_EXT_CFG_BOOL("zvknha", ext_zvknha, false),
25
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
26
@@ -XXX,XX +XXX,XX @@ static void rv32imcu_nommu_cpu_init(Object *obj)
27
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
28
}
29
30
-static void rv32imafcu_nommu_cpu_init(Object *obj)
31
+static void rv32_imafcu_nommu_cpu_init(Object *obj)
32
{
33
CPURISCVState *env = &RISCV_CPU(obj)->env;
34
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
35
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
36
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
37
#if defined(TARGET_RISCV32)
38
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
39
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32imcu_nommu_cpu_init),
40
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
41
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
42
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init),
43
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
44
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
45
#elif defined(TARGET_RISCV64)
46
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
32
--
47
--
33
2.45.1
48
2.27.0
34
49
35
50
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
---
3
---
35
target/riscv/cpu_helper.c | 22 ++++++++++++----------
4
target/riscv/cpu_helper.c | 2 +-
36
1 file changed, 12 insertions(+), 10 deletions(-)
5
1 file changed, 1 insertion(+), 1 deletion(-)
37
6
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
9
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
10
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
11
@@ -XXX,XX +XXX,XX @@ restart:
43
12
hwaddr vbase;
44
switch (access_type) {
13
45
case MMU_INST_FETCH:
14
/* Do the second stage translation on the base PTE address. */
46
- if (env->virt_enabled && !first_stage) {
15
- get_physical_address(env, &vbase, &vbase_prot, base, access_type,
47
+ if (pmp_violation) {
16
+ get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
48
+ cs->exception_index = RISCV_EXCP_INST_ACCESS_FAULT;
17
mmu_idx, false, true);
49
+ } else if (env->virt_enabled && !first_stage) {
18
50
cs->exception_index = RISCV_EXCP_INST_GUEST_PAGE_FAULT;
19
pte_addr = vbase + idx * ptesize;
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
--
20
--
84
2.45.1
21
2.27.0
22
23
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
30
---
3
---
31
target/riscv/cpu_helper.c | 1 +
4
target/riscv/cpu_helper.c | 9 +++++++--
32
target/riscv/debug.c | 3 +++
5
1 file changed, 7 insertions(+), 2 deletions(-)
33
2 files changed, 4 insertions(+)
34
6
35
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
7
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
36
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu_helper.c
9
--- a/target/riscv/cpu_helper.c
38
+++ b/target/riscv/cpu_helper.c
10
+++ b/target/riscv/cpu_helper.c
39
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
11
@@ -XXX,XX +XXX,XX @@ restart:
40
tval = env->bins;
12
hwaddr vbase;
41
break;
13
42
case RISCV_EXCP_BREAKPOINT:
14
/* Do the second stage translation on the base PTE address. */
43
+ tval = env->badaddr;
15
- get_physical_address(env, &vbase, &vbase_prot, base, MMU_DATA_LOAD,
44
if (cs->watchpoint_hit) {
16
- mmu_idx, false, true);
45
tval = cs->watchpoint_hit->hitaddr;
17
+ int vbase_ret = get_physical_address(env, &vbase, &vbase_prot,
46
cs->watchpoint_hit = NULL;
18
+ base, MMU_DATA_LOAD,
47
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
19
+ mmu_idx, false, true);
48
index XXXXXXX..XXXXXXX 100644
20
+
49
--- a/target/riscv/debug.c
21
+ if (vbase_ret != TRANSLATE_SUCCESS) {
50
+++ b/target/riscv/debug.c
22
+ return vbase_ret;
51
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
23
+ }
52
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
24
53
/* check U/S/M bit against current privilege level */
25
pte_addr = vbase + idx * ptesize;
54
if ((ctrl >> 3) & BIT(env->priv)) {
26
} else {
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
--
27
--
74
2.45.1
28
2.27.0
29
30
diff view generated by jsdifflib
1
From: Christoph Müllner <christoph.muellner@vrull.eu>
1
Also correct the name of the VVMA instruction.
2
2
3
The th.sxstatus CSR can be used to identify available custom extension
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
on T-Head CPUs. The CSR is documented here:
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadsxstatus.adoc
5
---
6
target/riscv/insn32.decode | 8 ++-
7
.../riscv/insn_trans/trans_privileged.inc.c | 38 -------------
8
target/riscv/insn_trans/trans_rvh.inc.c | 57 +++++++++++++++++++
9
target/riscv/translate.c | 1 +
10
4 files changed, 63 insertions(+), 41 deletions(-)
11
create mode 100644 target/riscv/insn_trans/trans_rvh.inc.c
6
12
7
An important property of this patch is, that the th.sxstatus MAEE field
13
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
8
is not set (indicating that XTheadMae is not available).
9
XTheadMae is a memory attribute extension (similar to Svpbmt) which is
10
implemented in many T-Head CPUs (C906, C910, etc.) and utilizes bits
11
in PTEs that are marked as reserved. QEMU maintainers prefer to not
12
implement XTheadMae, so we need give kernels a mechanism to identify
13
if XTheadMae is available in a system or not. And this patch introduces
14
this mechanism in QEMU in a way that's compatible with real HW
15
(i.e., probing the th.sxstatus.MAEE bit).
16
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>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
MAINTAINERS | 1 +
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
33
34
diff --git a/MAINTAINERS b/MAINTAINERS
35
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
36
--- a/MAINTAINERS
15
--- a/target/riscv/insn32.decode
37
+++ b/MAINTAINERS
16
+++ b/target/riscv/insn32.decode
38
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
17
@@ -XXX,XX +XXX,XX @@
39
S: Supported
18
@r2 ....... ..... ..... ... ..... ....... %rs1 %rd
40
F: target/riscv/insn_trans/trans_xthead.c.inc
19
41
F: target/riscv/xthead*.decode
20
@hfence_gvma ....... ..... ..... ... ..... ....... %rs2 %rs1
42
+F: target/riscv/th_*
21
-@hfence_bvma ....... ..... ..... ... ..... ....... %rs2 %rs1
43
F: disas/riscv-xthead*
22
+@hfence_vvma ....... ..... ..... ... ..... ....... %rs2 %rs1
44
23
45
RISC-V XVentanaCondOps extension
24
@sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1
46
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
@sfence_vm ....... ..... ..... ... ..... ....... %rs1
26
@@ -XXX,XX +XXX,XX @@ uret 0000000 00010 00000 000 00000 1110011
27
sret 0001000 00010 00000 000 00000 1110011
28
mret 0011000 00010 00000 000 00000 1110011
29
wfi 0001000 00101 00000 000 00000 1110011
30
-hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
31
-hfence_bvma 0010001 ..... ..... 000 00000 1110011 @hfence_bvma
32
sfence_vma 0001001 ..... ..... 000 00000 1110011 @sfence_vma
33
sfence_vm 0001000 00100 ..... 000 00000 1110011 @sfence_vm
34
35
@@ -XXX,XX +XXX,XX @@ fcvt_w_d 1100001 00000 ..... ... ..... 1010011 @r2_rm
36
fcvt_wu_d 1100001 00001 ..... ... ..... 1010011 @r2_rm
37
fcvt_d_w 1101001 00000 ..... ... ..... 1010011 @r2_rm
38
fcvt_d_wu 1101001 00001 ..... ... ..... 1010011 @r2_rm
39
+
40
+# *** RV32H Base Instruction Set ***
41
+hfence_gvma 0110001 ..... ..... 000 00000 1110011 @hfence_gvma
42
+hfence_vvma 0010001 ..... ..... 000 00000 1110011 @hfence_vvma
43
diff --git a/target/riscv/insn_trans/trans_privileged.inc.c b/target/riscv/insn_trans/trans_privileged.inc.c
47
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/cpu.h
45
--- a/target/riscv/insn_trans/trans_privileged.inc.c
49
+++ b/target/riscv/cpu.h
46
+++ b/target/riscv/insn_trans/trans_privileged.inc.c
50
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_new_csr_seed(target_ulong new_value,
47
@@ -XXX,XX +XXX,XX @@ static bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a)
51
uint8_t satp_mode_max_from_map(uint32_t map);
48
{
52
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
49
return false;
53
50
}
54
+/* Implemented in th_csr.c */
51
-
55
+void th_register_custom_csrs(RISCVCPU *cpu);
52
-static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
56
+
53
-{
57
#endif /* RISCV_CPU_H */
54
-#ifndef CONFIG_USER_ONLY
58
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
55
- if (has_ext(ctx, RVH)) {
59
index XXXXXXX..XXXXXXX 100644
56
- /* Hpervisor extensions exist */
60
--- a/target/riscv/cpu.c
57
- /*
61
+++ b/target/riscv/cpu.c
58
- * if (env->priv == PRV_M ||
62
@@ -XXX,XX +XXX,XX @@ static void rv64_thead_c906_cpu_init(Object *obj)
59
- * (env->priv == PRV_S &&
63
cpu->cfg.mvendorid = THEAD_VENDOR_ID;
60
- * !riscv_cpu_virt_enabled(env) &&
64
#ifndef CONFIG_USER_ONLY
61
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
65
set_satp_mode_max_supported(cpu, VM_1_10_SV39);
62
- */
66
+ th_register_custom_csrs(cpu);
63
- gen_helper_tlb_flush(cpu_env);
67
#endif
64
- return true;
68
65
- /* } */
69
/* inherited from parent obj via riscv_cpu_init() */
66
- }
70
diff --git a/target/riscv/th_csr.c b/target/riscv/th_csr.c
67
-#endif
68
- return false;
69
-}
70
-
71
-static bool trans_hfence_bvma(DisasContext *ctx, arg_sfence_vma *a)
72
-{
73
-#ifndef CONFIG_USER_ONLY
74
- if (has_ext(ctx, RVH)) {
75
- /* Hpervisor extensions exist */
76
- /*
77
- * if (env->priv == PRV_M ||
78
- * (env->priv == PRV_S &&
79
- * !riscv_cpu_virt_enabled(env) &&
80
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
81
- */
82
- gen_helper_tlb_flush(cpu_env);
83
- return true;
84
- /* } */
85
- }
86
-#endif
87
- return false;
88
-}
89
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
71
new file mode 100644
90
new file mode 100644
72
index XXXXXXX..XXXXXXX
91
index XXXXXXX..XXXXXXX
73
--- /dev/null
92
--- /dev/null
74
+++ b/target/riscv/th_csr.c
93
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
75
@@ -XXX,XX +XXX,XX @@
94
@@ -XXX,XX +XXX,XX @@
76
+/*
95
+/*
77
+ * T-Head-specific CSRs.
96
+ * RISC-V translation routines for the RVXI Base Integer Instruction Set.
78
+ *
97
+ *
79
+ * Copyright (c) 2024 VRULL GmbH
98
+ * Copyright (c) 2020 Western Digital
80
+ *
99
+ *
81
+ * This program is free software; you can redistribute it and/or modify it
100
+ * 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,
101
+ * under the terms and conditions of the GNU General Public License,
83
+ * version 2 or later, as published by the Free Software Foundation.
102
+ * version 2 or later, as published by the Free Software Foundation.
84
+ *
103
+ *
...
...
89
+ *
108
+ *
90
+ * You should have received a copy of the GNU General Public License along with
109
+ * 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/>.
110
+ * this program. If not, see <http://www.gnu.org/licenses/>.
92
+ */
111
+ */
93
+
112
+
94
+#include "qemu/osdep.h"
113
+static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
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
+{
114
+{
113
+ if (riscv_has_ext(env, RVS)) {
115
+#ifndef CONFIG_USER_ONLY
114
+ return RISCV_EXCP_NONE;
116
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
117
+ has_ext(ctx, RVH)) {
118
+ /* Hpervisor extensions exist */
119
+ /*
120
+ * if (env->priv == PRV_M ||
121
+ * (env->priv == PRV_S &&
122
+ * !riscv_cpu_virt_enabled(env) &&
123
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
124
+ */
125
+ gen_helper_tlb_flush(cpu_env);
126
+ return true;
127
+ /* } */
115
+ }
128
+ }
116
+
129
+#endif
117
+ return RISCV_EXCP_ILLEGAL_INST;
130
+ return false;
118
+}
131
+}
119
+
132
+
120
+static int test_thead_mvendorid(RISCVCPU *cpu)
133
+static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
121
+{
134
+{
122
+ if (cpu->cfg.mvendorid != THEAD_VENDOR_ID) {
135
+#ifndef CONFIG_USER_ONLY
123
+ return -1;
136
+ if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
137
+ has_ext(ctx, RVH)) {
138
+ /* Hpervisor extensions exist */
139
+ /*
140
+ * if (env->priv == PRV_M ||
141
+ * (env->priv == PRV_S &&
142
+ * !riscv_cpu_virt_enabled(env) &&
143
+ * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
144
+ */
145
+ gen_helper_tlb_flush(cpu_env);
146
+ return true;
147
+ /* } */
124
+ }
148
+ }
125
+
149
+#endif
126
+ return 0;
150
+ return false;
127
+}
151
+}
128
+
152
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
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
153
index XXXXXXX..XXXXXXX 100644
157
--- a/target/riscv/meson.build
154
--- a/target/riscv/translate.c
158
+++ b/target/riscv/meson.build
155
+++ b/target/riscv/translate.c
159
@@ -XXX,XX +XXX,XX @@ riscv_system_ss.add(files(
156
@@ -XXX,XX +XXX,XX @@ static bool gen_shift(DisasContext *ctx, arg_r *a,
160
'monitor.c',
157
#include "insn_trans/trans_rva.inc.c"
161
'machine.c',
158
#include "insn_trans/trans_rvf.inc.c"
162
'pmu.c',
159
#include "insn_trans/trans_rvd.inc.c"
163
+ 'th_csr.c',
160
+#include "insn_trans/trans_rvh.inc.c"
164
'time_helper.c',
161
#include "insn_trans/trans_privileged.inc.c"
165
'riscv-qmp-cmds.c',
162
166
))
163
/* Include the auto-generated decoder for 16 bit insn */
167
--
164
--
168
2.45.1
165
2.27.0
169
166
170
167
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
Call the helper_hyp_tlb_flush() function on hfence instructions which
2
will generate an illegal insruction execption if we don't have
3
permission to flush the Hypervisor level TLBs.
2
4
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>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
5
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
---
7
---
21
target/riscv/helper.h | 1 +
8
target/riscv/helper.h | 5 ++++
22
target/riscv/op_helper.c | 11 ++++++++
9
target/riscv/insn_trans/trans_rvh.inc.c | 32 +++++--------------------
23
target/riscv/insn_trans/trans_rvzawrs.c.inc | 29 ++++++++++++++-------
10
target/riscv/op_helper.c | 13 ++++++++++
24
3 files changed, 32 insertions(+), 9 deletions(-)
11
3 files changed, 24 insertions(+), 26 deletions(-)
25
12
26
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
13
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
27
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/helper.h
15
--- a/target/riscv/helper.h
29
+++ b/target/riscv/helper.h
16
+++ b/target/riscv/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(mret, tl, env, tl)
31
DEF_HELPER_1(sret, tl, env)
32
DEF_HELPER_1(mret, tl, env)
33
DEF_HELPER_1(wfi, void, env)
18
DEF_HELPER_1(wfi, void, env)
34
+DEF_HELPER_1(wrs_nto, void, env)
35
DEF_HELPER_1(tlb_flush, void, env)
19
DEF_HELPER_1(tlb_flush, void, env)
36
DEF_HELPER_1(tlb_flush_all, void, env)
20
#endif
37
/* Native Debug */
21
+
22
+/* Hypervisor functions */
23
+#ifndef CONFIG_USER_ONLY
24
+DEF_HELPER_1(hyp_tlb_flush, void, env)
25
+#endif
26
diff --git a/target/riscv/insn_trans/trans_rvh.inc.c b/target/riscv/insn_trans/trans_rvh.inc.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/insn_trans/trans_rvh.inc.c
29
+++ b/target/riscv/insn_trans/trans_rvh.inc.c
30
@@ -XXX,XX +XXX,XX @@
31
32
static bool trans_hfence_gvma(DisasContext *ctx, arg_sfence_vma *a)
33
{
34
+ REQUIRE_EXT(ctx, RVH);
35
#ifndef CONFIG_USER_ONLY
36
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
37
- has_ext(ctx, RVH)) {
38
- /* Hpervisor extensions exist */
39
- /*
40
- * if (env->priv == PRV_M ||
41
- * (env->priv == PRV_S &&
42
- * !riscv_cpu_virt_enabled(env) &&
43
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
44
- */
45
- gen_helper_tlb_flush(cpu_env);
46
- return true;
47
- /* } */
48
- }
49
+ gen_helper_hyp_tlb_flush(cpu_env);
50
+ return true;
51
#endif
52
return false;
53
}
54
55
static bool trans_hfence_vvma(DisasContext *ctx, arg_sfence_vma *a)
56
{
57
+ REQUIRE_EXT(ctx, RVH);
58
#ifndef CONFIG_USER_ONLY
59
- if (ctx->priv_ver >= PRIV_VERSION_1_10_0 &&
60
- has_ext(ctx, RVH)) {
61
- /* Hpervisor extensions exist */
62
- /*
63
- * if (env->priv == PRV_M ||
64
- * (env->priv == PRV_S &&
65
- * !riscv_cpu_virt_enabled(env) &&
66
- * get_field(ctx->mstatus_fs, MSTATUS_TVM))) {
67
- */
68
- gen_helper_tlb_flush(cpu_env);
69
- return true;
70
- /* } */
71
- }
72
+ gen_helper_hyp_tlb_flush(cpu_env);
73
+ return true;
74
#endif
75
return false;
76
}
38
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
77
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
39
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/op_helper.c
79
--- a/target/riscv/op_helper.c
41
+++ b/target/riscv/op_helper.c
80
+++ b/target/riscv/op_helper.c
42
@@ -XXX,XX +XXX,XX @@ void helper_wfi(CPURISCVState *env)
81
@@ -XXX,XX +XXX,XX @@ void helper_tlb_flush(CPURISCVState *env)
43
}
82
}
44
}
83
}
45
84
46
+void helper_wrs_nto(CPURISCVState *env)
85
+void helper_hyp_tlb_flush(CPURISCVState *env)
47
+{
86
+{
48
+ if (env->virt_enabled && (env->priv == PRV_S || env->priv == PRV_U) &&
87
+ CPUState *cs = env_cpu(env);
49
+ get_field(env->hstatus, HSTATUS_VTW) &&
88
+
50
+ !get_field(env->mstatus, MSTATUS_TW)) {
89
+ if (env->priv == PRV_M ||
51
+ riscv_raise_exception(env, RISCV_EXCP_VIRT_INSTRUCTION_FAULT, GETPC());
90
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env))) {
52
+ } else if (env->priv != PRV_M && get_field(env->mstatus, MSTATUS_TW)) {
91
+ tlb_flush(cs);
53
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
92
+ return;
54
+ }
93
+ }
94
+
95
+ riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
55
+}
96
+}
56
+
97
+
57
void helper_tlb_flush(CPURISCVState *env)
98
#endif /* !CONFIG_USER_ONLY */
58
{
59
CPUState *cs = env_cpu(env);
60
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/riscv/insn_trans/trans_rvzawrs.c.inc
63
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
64
@@ -XXX,XX +XXX,XX @@
65
* this program. If not, see <http://www.gnu.org/licenses/>.
66
*/
67
68
-static bool trans_wrs(DisasContext *ctx)
69
+static bool trans_wrs_sto(DisasContext *ctx, arg_wrs_sto *a)
70
{
71
if (!ctx->cfg_ptr->ext_zawrs) {
72
return false;
73
@@ -XXX,XX +XXX,XX @@ static bool trans_wrs(DisasContext *ctx)
74
return true;
75
}
76
77
-#define GEN_TRANS_WRS(insn) \
78
-static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
79
-{ \
80
- (void)a; \
81
- return trans_wrs(ctx); \
82
-}
83
+static bool trans_wrs_nto(DisasContext *ctx, arg_wrs_nto *a)
84
+{
85
+ if (!ctx->cfg_ptr->ext_zawrs) {
86
+ return false;
87
+ }
88
89
-GEN_TRANS_WRS(wrs_nto)
90
-GEN_TRANS_WRS(wrs_sto)
91
+ /*
92
+ * Depending on the mode of execution, mstatus.TW and hstatus.VTW, wrs.nto
93
+ * should raise an exception when the implementation-specific bounded time
94
+ * limit has expired. Our time limit is zero, so we either return
95
+ * immediately, as does our implementation of wrs.sto, or raise an
96
+ * exception, as handled by the wrs.nto helper.
97
+ */
98
+#ifndef CONFIG_USER_ONLY
99
+ gen_helper_wrs_nto(tcg_env);
100
+#endif
101
+
102
+ /* We only get here when helper_wrs_nto() doesn't raise an exception. */
103
+ return trans_wrs_sto(ctx, NULL);
104
+}
105
--
99
--
106
2.45.1
100
2.27.0
107
101
108
102
diff view generated by jsdifflib
1
From: Jason Chien <jason.chien@sifive.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reported-by: Damien Hedde <damien.hedde@greensocs.com>
3
---
4
hw/riscv/opentitan.c | 3 ++-
5
1 file changed, 2 insertions(+), 1 deletion(-)
2
6
3
In current implementation, the gdbstub allows reading vector registers
7
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
4
only if V extension is supported. However, all vector extensions and
8
index XXXXXXX..XXXXXXX 100644
5
vector crypto extensions have the vector registers and they all depend
9
--- a/hw/riscv/opentitan.c
6
on Zve32x. The gdbstub should check for Zve32x instead.
10
+++ b/hw/riscv/opentitan.c
11
@@ -XXX,XX +XXX,XX @@
12
#include "hw/misc/unimp.h"
13
#include "hw/riscv/boot.h"
14
#include "exec/address-spaces.h"
15
+#include "qemu/units.h"
16
17
static const struct MemmapEntry {
18
hwaddr base;
19
hwaddr size;
20
} ibex_memmap[] = {
21
- [IBEX_ROM] = { 0x00008000, 0xc000 },
22
+ [IBEX_ROM] = { 0x00008000, 16 * KiB },
23
[IBEX_RAM] = { 0x10000000, 0x10000 },
24
[IBEX_FLASH] = { 0x20000000, 0x80000 },
25
[IBEX_UART] = { 0x40000000, 0x10000 },
26
--
27
2.27.0
7
28
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
29
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
This is the initial commit of the Ibex UART device. Serial TX is
2
working, while RX has been implemeneted but untested.
1
3
4
This is based on the documentation from:
5
https://docs.opentitan.org/hw/ip/uart/doc/
6
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: LIU Zhiwei<zhiwei_liu@c-sky.com>
9
---
10
include/hw/char/ibex_uart.h | 110 ++++++++
11
hw/char/ibex_uart.c | 492 ++++++++++++++++++++++++++++++++++++
12
MAINTAINERS | 2 +
13
hw/char/Makefile.objs | 1 +
14
hw/riscv/Kconfig | 4 +
15
5 files changed, 609 insertions(+)
16
create mode 100644 include/hw/char/ibex_uart.h
17
create mode 100644 hw/char/ibex_uart.c
18
19
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
20
new file mode 100644
21
index XXXXXXX..XXXXXXX
22
--- /dev/null
23
+++ b/include/hw/char/ibex_uart.h
24
@@ -XXX,XX +XXX,XX @@
25
+/*
26
+ * QEMU lowRISC Ibex UART device
27
+ *
28
+ * Copyright (c) 2020 Western Digital
29
+ *
30
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
31
+ * of this software and associated documentation files (the "Software"), to deal
32
+ * in the Software without restriction, including without limitation the rights
33
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
34
+ * copies of the Software, and to permit persons to whom the Software is
35
+ * furnished to do so, subject to the following conditions:
36
+ *
37
+ * The above copyright notice and this permission notice shall be included in
38
+ * all copies or substantial portions of the Software.
39
+ *
40
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
44
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
45
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
46
+ * THE SOFTWARE.
47
+ */
48
+
49
+#ifndef HW_IBEX_UART_H
50
+#define HW_IBEX_UART_H
51
+
52
+#include "hw/sysbus.h"
53
+#include "chardev/char-fe.h"
54
+#include "qemu/timer.h"
55
+
56
+#define IBEX_UART_INTR_STATE 0x00
57
+ #define INTR_STATE_TX_WATERMARK (1 << 0)
58
+ #define INTR_STATE_RX_WATERMARK (1 << 1)
59
+ #define INTR_STATE_TX_EMPTY (1 << 2)
60
+ #define INTR_STATE_RX_OVERFLOW (1 << 3)
61
+#define IBEX_UART_INTR_ENABLE 0x04
62
+#define IBEX_UART_INTR_TEST 0x08
63
+
64
+#define IBEX_UART_CTRL 0x0c
65
+ #define UART_CTRL_TX_ENABLE (1 << 0)
66
+ #define UART_CTRL_RX_ENABLE (1 << 1)
67
+ #define UART_CTRL_NF (1 << 2)
68
+ #define UART_CTRL_SLPBK (1 << 4)
69
+ #define UART_CTRL_LLPBK (1 << 5)
70
+ #define UART_CTRL_PARITY_EN (1 << 6)
71
+ #define UART_CTRL_PARITY_ODD (1 << 7)
72
+ #define UART_CTRL_RXBLVL (3 << 8)
73
+ #define UART_CTRL_NCO (0xFFFF << 16)
74
+
75
+#define IBEX_UART_STATUS 0x10
76
+ #define UART_STATUS_TXFULL (1 << 0)
77
+ #define UART_STATUS_RXFULL (1 << 1)
78
+ #define UART_STATUS_TXEMPTY (1 << 2)
79
+ #define UART_STATUS_RXIDLE (1 << 4)
80
+ #define UART_STATUS_RXEMPTY (1 << 5)
81
+
82
+#define IBEX_UART_RDATA 0x14
83
+#define IBEX_UART_WDATA 0x18
84
+
85
+#define IBEX_UART_FIFO_CTRL 0x1c
86
+ #define FIFO_CTRL_RXRST (1 << 0)
87
+ #define FIFO_CTRL_TXRST (1 << 1)
88
+ #define FIFO_CTRL_RXILVL (7 << 2)
89
+ #define FIFO_CTRL_RXILVL_SHIFT (2)
90
+ #define FIFO_CTRL_TXILVL (3 << 5)
91
+ #define FIFO_CTRL_TXILVL_SHIFT (5)
92
+
93
+#define IBEX_UART_FIFO_STATUS 0x20
94
+#define IBEX_UART_OVRD 0x24
95
+#define IBEX_UART_VAL 0x28
96
+#define IBEX_UART_TIMEOUT_CTRL 0x2c
97
+
98
+#define IBEX_UART_TX_FIFO_SIZE 16
99
+
100
+#define TYPE_IBEX_UART "ibex-uart"
101
+#define IBEX_UART(obj) \
102
+ OBJECT_CHECK(IbexUartState, (obj), TYPE_IBEX_UART)
103
+
104
+typedef struct {
105
+ /* <private> */
106
+ SysBusDevice parent_obj;
107
+
108
+ /* <public> */
109
+ MemoryRegion mmio;
110
+
111
+ uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
112
+ uint32_t tx_level;
113
+
114
+ QEMUTimer *fifo_trigger_handle;
115
+ uint64_t char_tx_time;
116
+
117
+ uint32_t uart_intr_state;
118
+ uint32_t uart_intr_enable;
119
+ uint32_t uart_ctrl;
120
+ uint32_t uart_status;
121
+ uint32_t uart_rdata;
122
+ uint32_t uart_fifo_ctrl;
123
+ uint32_t uart_fifo_status;
124
+ uint32_t uart_ovrd;
125
+ uint32_t uart_val;
126
+ uint32_t uart_timeout_ctrl;
127
+
128
+ CharBackend chr;
129
+ qemu_irq tx_watermark;
130
+ qemu_irq rx_watermark;
131
+ qemu_irq tx_empty;
132
+ qemu_irq rx_overflow;
133
+} IbexUartState;
134
+#endif /* HW_IBEX_UART_H */
135
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
136
new file mode 100644
137
index XXXXXXX..XXXXXXX
138
--- /dev/null
139
+++ b/hw/char/ibex_uart.c
140
@@ -XXX,XX +XXX,XX @@
141
+/*
142
+ * QEMU lowRISC Ibex UART device
143
+ *
144
+ * Copyright (c) 2020 Western Digital
145
+ *
146
+ * For details check the documentation here:
147
+ * https://docs.opentitan.org/hw/ip/uart/doc/
148
+ *
149
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
150
+ * of this software and associated documentation files (the "Software"), to deal
151
+ * in the Software without restriction, including without limitation the rights
152
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
153
+ * copies of the Software, and to permit persons to whom the Software is
154
+ * furnished to do so, subject to the following conditions:
155
+ *
156
+ * The above copyright notice and this permission notice shall be included in
157
+ * all copies or substantial portions of the Software.
158
+ *
159
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
160
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
161
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
162
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
163
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
164
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
165
+ * THE SOFTWARE.
166
+ */
167
+
168
+#include "qemu/osdep.h"
169
+#include "hw/char/ibex_uart.h"
170
+#include "hw/irq.h"
171
+#include "hw/qdev-properties.h"
172
+#include "migration/vmstate.h"
173
+#include "qemu/log.h"
174
+#include "qemu/module.h"
175
+
176
+static void ibex_uart_update_irqs(IbexUartState *s)
177
+{
178
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_WATERMARK) {
179
+ qemu_set_irq(s->tx_watermark, 1);
180
+ } else {
181
+ qemu_set_irq(s->tx_watermark, 0);
182
+ }
183
+
184
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_WATERMARK) {
185
+ qemu_set_irq(s->rx_watermark, 1);
186
+ } else {
187
+ qemu_set_irq(s->rx_watermark, 0);
188
+ }
189
+
190
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_TX_EMPTY) {
191
+ qemu_set_irq(s->tx_empty, 1);
192
+ } else {
193
+ qemu_set_irq(s->tx_empty, 0);
194
+ }
195
+
196
+ if (s->uart_intr_state & s->uart_intr_enable & INTR_STATE_RX_OVERFLOW) {
197
+ qemu_set_irq(s->rx_overflow, 1);
198
+ } else {
199
+ qemu_set_irq(s->rx_overflow, 0);
200
+ }
201
+}
202
+
203
+static int ibex_uart_can_receive(void *opaque)
204
+{
205
+ IbexUartState *s = opaque;
206
+
207
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
208
+ return 1;
209
+ }
210
+
211
+ return 0;
212
+}
213
+
214
+static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
215
+{
216
+ IbexUartState *s = opaque;
217
+ uint8_t rx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_RXILVL)
218
+ >> FIFO_CTRL_RXILVL_SHIFT;
219
+
220
+ s->uart_rdata = *buf;
221
+
222
+ s->uart_status &= ~UART_STATUS_RXIDLE;
223
+ s->uart_status &= ~UART_STATUS_RXEMPTY;
224
+
225
+ if (size > rx_fifo_level) {
226
+ s->uart_intr_state |= INTR_STATE_RX_WATERMARK;
227
+ }
228
+
229
+ ibex_uart_update_irqs(s);
230
+}
231
+
232
+static gboolean ibex_uart_xmit(GIOChannel *chan, GIOCondition cond,
233
+ void *opaque)
234
+{
235
+ IbexUartState *s = opaque;
236
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
237
+ >> FIFO_CTRL_TXILVL_SHIFT;
238
+ int ret;
239
+
240
+ /* instant drain the fifo when there's no back-end */
241
+ if (!qemu_chr_fe_backend_connected(&s->chr)) {
242
+ s->tx_level = 0;
243
+ return FALSE;
244
+ }
245
+
246
+ if (!s->tx_level) {
247
+ s->uart_status &= ~UART_STATUS_TXFULL;
248
+ s->uart_status |= UART_STATUS_TXEMPTY;
249
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
250
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
251
+ ibex_uart_update_irqs(s);
252
+ return FALSE;
253
+ }
254
+
255
+ ret = qemu_chr_fe_write(&s->chr, s->tx_fifo, s->tx_level);
256
+
257
+ if (ret >= 0) {
258
+ s->tx_level -= ret;
259
+ memmove(s->tx_fifo, s->tx_fifo + ret, s->tx_level);
260
+ }
261
+
262
+ if (s->tx_level) {
263
+ guint r = qemu_chr_fe_add_watch(&s->chr, G_IO_OUT | G_IO_HUP,
264
+ ibex_uart_xmit, s);
265
+ if (!r) {
266
+ s->tx_level = 0;
267
+ return FALSE;
268
+ }
269
+ }
270
+
271
+ /* Clear the TX Full bit */
272
+ if (s->tx_level != IBEX_UART_TX_FIFO_SIZE) {
273
+ s->uart_status &= ~UART_STATUS_TXFULL;
274
+ }
275
+
276
+ /* Disable the TX_WATERMARK IRQ */
277
+ if (s->tx_level < tx_fifo_level) {
278
+ s->uart_intr_state &= ~INTR_STATE_TX_WATERMARK;
279
+ }
280
+
281
+ /* Set TX empty */
282
+ if (s->tx_level == 0) {
283
+ s->uart_status |= UART_STATUS_TXEMPTY;
284
+ s->uart_intr_state |= INTR_STATE_TX_EMPTY;
285
+ }
286
+
287
+ ibex_uart_update_irqs(s);
288
+ return FALSE;
289
+}
290
+
291
+static void uart_write_tx_fifo(IbexUartState *s, const uint8_t *buf,
292
+ int size)
293
+{
294
+ uint64_t current_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);
295
+ uint8_t tx_fifo_level = (s->uart_fifo_ctrl & FIFO_CTRL_TXILVL)
296
+ >> FIFO_CTRL_TXILVL_SHIFT;
297
+
298
+ if (size > IBEX_UART_TX_FIFO_SIZE - s->tx_level) {
299
+ size = IBEX_UART_TX_FIFO_SIZE - s->tx_level;
300
+ qemu_log_mask(LOG_GUEST_ERROR, "ibex_uart: TX FIFO overflow");
301
+ }
302
+
303
+ memcpy(s->tx_fifo + s->tx_level, buf, size);
304
+ s->tx_level += size;
305
+
306
+ if (s->tx_level > 0) {
307
+ s->uart_status &= ~UART_STATUS_TXEMPTY;
308
+ }
309
+
310
+ if (s->tx_level >= tx_fifo_level) {
311
+ s->uart_intr_state |= INTR_STATE_TX_WATERMARK;
312
+ ibex_uart_update_irqs(s);
313
+ }
314
+
315
+ if (s->tx_level == IBEX_UART_TX_FIFO_SIZE) {
316
+ s->uart_status |= UART_STATUS_TXFULL;
317
+ }
318
+
319
+ timer_mod(s->fifo_trigger_handle, current_time +
320
+ (s->char_tx_time * 4));
321
+}
322
+
323
+static void ibex_uart_reset(DeviceState *dev)
324
+{
325
+ IbexUartState *s = IBEX_UART(dev);
326
+
327
+ s->uart_intr_state = 0x00000000;
328
+ s->uart_intr_state = 0x00000000;
329
+ s->uart_intr_enable = 0x00000000;
330
+ s->uart_ctrl = 0x00000000;
331
+ s->uart_status = 0x0000003c;
332
+ s->uart_rdata = 0x00000000;
333
+ s->uart_fifo_ctrl = 0x00000000;
334
+ s->uart_fifo_status = 0x00000000;
335
+ s->uart_ovrd = 0x00000000;
336
+ s->uart_val = 0x00000000;
337
+ s->uart_timeout_ctrl = 0x00000000;
338
+
339
+ s->tx_level = 0;
340
+
341
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
342
+
343
+ ibex_uart_update_irqs(s);
344
+}
345
+
346
+static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
347
+ unsigned int size)
348
+{
349
+ IbexUartState *s = opaque;
350
+ uint64_t retvalue = 0;
351
+
352
+ switch (addr) {
353
+ case IBEX_UART_INTR_STATE:
354
+ retvalue = s->uart_intr_state;
355
+ break;
356
+ case IBEX_UART_INTR_ENABLE:
357
+ retvalue = s->uart_intr_enable;
358
+ break;
359
+ case IBEX_UART_INTR_TEST:
360
+ qemu_log_mask(LOG_GUEST_ERROR,
361
+ "%s: wdata is write only\n", __func__);
362
+ break;
363
+
364
+ case IBEX_UART_CTRL:
365
+ retvalue = s->uart_ctrl;
366
+ break;
367
+ case IBEX_UART_STATUS:
368
+ retvalue = s->uart_status;
369
+ break;
370
+
371
+ case IBEX_UART_RDATA:
372
+ retvalue = s->uart_rdata;
373
+ if (s->uart_ctrl & UART_CTRL_RX_ENABLE) {
374
+ qemu_chr_fe_accept_input(&s->chr);
375
+
376
+ s->uart_status |= UART_STATUS_RXIDLE;
377
+ s->uart_status |= UART_STATUS_RXEMPTY;
378
+ }
379
+ break;
380
+ case IBEX_UART_WDATA:
381
+ qemu_log_mask(LOG_GUEST_ERROR,
382
+ "%s: wdata is write only\n", __func__);
383
+ break;
384
+
385
+ case IBEX_UART_FIFO_CTRL:
386
+ retvalue = s->uart_fifo_ctrl;
387
+ break;
388
+ case IBEX_UART_FIFO_STATUS:
389
+ retvalue = s->uart_fifo_status;
390
+
391
+ retvalue |= s->tx_level & 0x1F;
392
+
393
+ qemu_log_mask(LOG_UNIMP,
394
+ "%s: RX fifos are not supported\n", __func__);
395
+ break;
396
+
397
+ case IBEX_UART_OVRD:
398
+ retvalue = s->uart_ovrd;
399
+ qemu_log_mask(LOG_UNIMP,
400
+ "%s: ovrd is not supported\n", __func__);
401
+ break;
402
+ case IBEX_UART_VAL:
403
+ retvalue = s->uart_val;
404
+ qemu_log_mask(LOG_UNIMP,
405
+ "%s: val is not supported\n", __func__);
406
+ break;
407
+ case IBEX_UART_TIMEOUT_CTRL:
408
+ retvalue = s->uart_timeout_ctrl;
409
+ qemu_log_mask(LOG_UNIMP,
410
+ "%s: timeout_ctrl is not supported\n", __func__);
411
+ break;
412
+ default:
413
+ qemu_log_mask(LOG_GUEST_ERROR,
414
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
415
+ return 0;
416
+ }
417
+
418
+ return retvalue;
419
+}
420
+
421
+static void ibex_uart_write(void *opaque, hwaddr addr,
422
+ uint64_t val64, unsigned int size)
423
+{
424
+ IbexUartState *s = opaque;
425
+ uint32_t value = val64;
426
+
427
+ switch (addr) {
428
+ case IBEX_UART_INTR_STATE:
429
+ /* Write 1 clear */
430
+ s->uart_intr_state &= ~value;
431
+ ibex_uart_update_irqs(s);
432
+ break;
433
+ case IBEX_UART_INTR_ENABLE:
434
+ s->uart_intr_enable = value;
435
+ ibex_uart_update_irqs(s);
436
+ break;
437
+ case IBEX_UART_INTR_TEST:
438
+ s->uart_intr_state |= value;
439
+ ibex_uart_update_irqs(s);
440
+ break;
441
+
442
+ case IBEX_UART_CTRL:
443
+ s->uart_ctrl = value;
444
+
445
+ if (value & UART_CTRL_NF) {
446
+ qemu_log_mask(LOG_UNIMP,
447
+ "%s: UART_CTRL_NF is not supported\n", __func__);
448
+ }
449
+ if (value & UART_CTRL_SLPBK) {
450
+ qemu_log_mask(LOG_UNIMP,
451
+ "%s: UART_CTRL_SLPBK is not supported\n", __func__);
452
+ }
453
+ if (value & UART_CTRL_LLPBK) {
454
+ qemu_log_mask(LOG_UNIMP,
455
+ "%s: UART_CTRL_LLPBK is not supported\n", __func__);
456
+ }
457
+ if (value & UART_CTRL_PARITY_EN) {
458
+ qemu_log_mask(LOG_UNIMP,
459
+ "%s: UART_CTRL_PARITY_EN is not supported\n",
460
+ __func__);
461
+ }
462
+ if (value & UART_CTRL_PARITY_ODD) {
463
+ qemu_log_mask(LOG_UNIMP,
464
+ "%s: UART_CTRL_PARITY_ODD is not supported\n",
465
+ __func__);
466
+ }
467
+ if (value & UART_CTRL_RXBLVL) {
468
+ qemu_log_mask(LOG_UNIMP,
469
+ "%s: UART_CTRL_RXBLVL is not supported\n", __func__);
470
+ }
471
+ if (value & UART_CTRL_NCO) {
472
+ uint64_t baud = ((value & UART_CTRL_NCO) >> 16);
473
+ baud *= 1000;
474
+ baud /= 2 ^ 20;
475
+
476
+ s->char_tx_time = (NANOSECONDS_PER_SECOND / baud) * 10;
477
+ }
478
+ break;
479
+ case IBEX_UART_STATUS:
480
+ qemu_log_mask(LOG_GUEST_ERROR,
481
+ "%s: status is read only\n", __func__);
482
+ break;
483
+
484
+ case IBEX_UART_RDATA:
485
+ qemu_log_mask(LOG_GUEST_ERROR,
486
+ "%s: rdata is read only\n", __func__);
487
+ break;
488
+ case IBEX_UART_WDATA:
489
+ uart_write_tx_fifo(s, (uint8_t *) &value, 1);
490
+ break;
491
+
492
+ case IBEX_UART_FIFO_CTRL:
493
+ s->uart_fifo_ctrl = value;
494
+
495
+ if (value & FIFO_CTRL_RXRST) {
496
+ qemu_log_mask(LOG_UNIMP,
497
+ "%s: RX fifos are not supported\n", __func__);
498
+ }
499
+ if (value & FIFO_CTRL_TXRST) {
500
+ s->tx_level = 0;
501
+ }
502
+ break;
503
+ case IBEX_UART_FIFO_STATUS:
504
+ qemu_log_mask(LOG_GUEST_ERROR,
505
+ "%s: fifo_status is read only\n", __func__);
506
+ break;
507
+
508
+ case IBEX_UART_OVRD:
509
+ s->uart_ovrd = value;
510
+ qemu_log_mask(LOG_UNIMP,
511
+ "%s: ovrd is not supported\n", __func__);
512
+ break;
513
+ case IBEX_UART_VAL:
514
+ qemu_log_mask(LOG_GUEST_ERROR,
515
+ "%s: val is read only\n", __func__);
516
+ break;
517
+ case IBEX_UART_TIMEOUT_CTRL:
518
+ s->uart_timeout_ctrl = value;
519
+ qemu_log_mask(LOG_UNIMP,
520
+ "%s: timeout_ctrl is not supported\n", __func__);
521
+ break;
522
+ default:
523
+ qemu_log_mask(LOG_GUEST_ERROR,
524
+ "%s: Bad offset 0x%"HWADDR_PRIx"\n", __func__, addr);
525
+ }
526
+}
527
+
528
+static void fifo_trigger_update(void *opaque)
529
+{
530
+ IbexUartState *s = opaque;
531
+
532
+ if (s->uart_ctrl & UART_CTRL_TX_ENABLE) {
533
+ ibex_uart_xmit(NULL, G_IO_OUT, s);
534
+ }
535
+}
536
+
537
+static const MemoryRegionOps ibex_uart_ops = {
538
+ .read = ibex_uart_read,
539
+ .write = ibex_uart_write,
540
+ .endianness = DEVICE_NATIVE_ENDIAN,
541
+ .impl.min_access_size = 4,
542
+ .impl.max_access_size = 4,
543
+};
544
+
545
+static int ibex_uart_post_load(void *opaque, int version_id)
546
+{
547
+ IbexUartState *s = opaque;
548
+
549
+ ibex_uart_update_irqs(s);
550
+ return 0;
551
+}
552
+
553
+static const VMStateDescription vmstate_ibex_uart = {
554
+ .name = TYPE_IBEX_UART,
555
+ .version_id = 1,
556
+ .minimum_version_id = 1,
557
+ .post_load = ibex_uart_post_load,
558
+ .fields = (VMStateField[]) {
559
+ VMSTATE_UINT8_ARRAY(tx_fifo, IbexUartState,
560
+ IBEX_UART_TX_FIFO_SIZE),
561
+ VMSTATE_UINT32(tx_level, IbexUartState),
562
+ VMSTATE_UINT64(char_tx_time, IbexUartState),
563
+ VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexUartState),
564
+ VMSTATE_UINT32(uart_intr_state, IbexUartState),
565
+ VMSTATE_UINT32(uart_intr_enable, IbexUartState),
566
+ VMSTATE_UINT32(uart_ctrl, IbexUartState),
567
+ VMSTATE_UINT32(uart_status, IbexUartState),
568
+ VMSTATE_UINT32(uart_rdata, IbexUartState),
569
+ VMSTATE_UINT32(uart_fifo_ctrl, IbexUartState),
570
+ VMSTATE_UINT32(uart_fifo_status, IbexUartState),
571
+ VMSTATE_UINT32(uart_ovrd, IbexUartState),
572
+ VMSTATE_UINT32(uart_val, IbexUartState),
573
+ VMSTATE_UINT32(uart_timeout_ctrl, IbexUartState),
574
+ VMSTATE_END_OF_LIST()
575
+ }
576
+};
577
+
578
+static Property ibex_uart_properties[] = {
579
+ DEFINE_PROP_CHR("chardev", IbexUartState, chr),
580
+ DEFINE_PROP_END_OF_LIST(),
581
+};
582
+
583
+static void ibex_uart_init(Object *obj)
584
+{
585
+ IbexUartState *s = IBEX_UART(obj);
586
+
587
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_watermark);
588
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_watermark);
589
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->tx_empty);
590
+ sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->rx_overflow);
591
+
592
+ memory_region_init_io(&s->mmio, obj, &ibex_uart_ops, s,
593
+ TYPE_IBEX_UART, 0x400);
594
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
595
+}
596
+
597
+static void ibex_uart_realize(DeviceState *dev, Error **errp)
598
+{
599
+ IbexUartState *s = IBEX_UART(dev);
600
+
601
+ s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL,
602
+ fifo_trigger_update, s);
603
+
604
+ qemu_chr_fe_set_handlers(&s->chr, ibex_uart_can_receive,
605
+ ibex_uart_receive, NULL, NULL,
606
+ s, NULL, true);
607
+}
608
+
609
+static void ibex_uart_class_init(ObjectClass *klass, void *data)
610
+{
611
+ DeviceClass *dc = DEVICE_CLASS(klass);
612
+
613
+ dc->reset = ibex_uart_reset;
614
+ dc->realize = ibex_uart_realize;
615
+ dc->vmsd = &vmstate_ibex_uart;
616
+ device_class_set_props(dc, ibex_uart_properties);
617
+}
618
+
619
+static const TypeInfo ibex_uart_info = {
620
+ .name = TYPE_IBEX_UART,
621
+ .parent = TYPE_SYS_BUS_DEVICE,
622
+ .instance_size = sizeof(IbexUartState),
623
+ .instance_init = ibex_uart_init,
624
+ .class_init = ibex_uart_class_init,
625
+};
626
+
627
+static void ibex_uart_register_types(void)
628
+{
629
+ type_register_static(&ibex_uart_info);
630
+}
631
+
632
+type_init(ibex_uart_register_types)
633
diff --git a/MAINTAINERS b/MAINTAINERS
634
index XXXXXXX..XXXXXXX 100644
635
--- a/MAINTAINERS
636
+++ b/MAINTAINERS
637
@@ -XXX,XX +XXX,XX @@ M: Alistair Francis <Alistair.Francis@wdc.com>
638
L: qemu-riscv@nongnu.org
639
S: Supported
640
F: hw/riscv/opentitan.c
641
+F: hw/char/ibex_uart.c
642
F: include/hw/riscv/opentitan.h
643
+F: include/hw/char/ibex_uart.h
644
645
SH4 Machines
646
------------
647
diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs
648
index XXXXXXX..XXXXXXX 100644
649
--- a/hw/char/Makefile.objs
650
+++ b/hw/char/Makefile.objs
651
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_VIRTIO_SERIAL) += virtio-console.o
652
common-obj-$(CONFIG_XILINX) += xilinx_uartlite.o
653
common-obj-$(CONFIG_XEN) += xen_console.o
654
common-obj-$(CONFIG_CADENCE) += cadence_uart.o
655
+common-obj-$(CONFIG_IBEX) += ibex_uart.o
656
657
common-obj-$(CONFIG_EXYNOS4) += exynos4210_uart.o
658
common-obj-$(CONFIG_COLDFIRE) += mcf_uart.o
659
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
660
index XXXXXXX..XXXXXXX 100644
661
--- a/hw/riscv/Kconfig
662
+++ b/hw/riscv/Kconfig
663
@@ -XXX,XX +XXX,XX @@ config HTIF
664
config HART
665
bool
666
667
+config IBEX
668
+ bool
669
+
670
config SIFIVE
671
bool
672
select MSI_NONBROKEN
673
@@ -XXX,XX +XXX,XX @@ config SPIKE
674
675
config OPENTITAN
676
bool
677
+ select IBEX
678
select HART
679
select UNIMP
680
681
--
682
2.27.0
683
684
diff view generated by jsdifflib
New patch
1
1
The Ibex core contains a PLIC that although similar to the RISC-V spec
2
is not RISC-V spec compliant.
3
4
This patch implements a Ibex PLIC in a somewhat generic way.
5
6
As the current RISC-V PLIC needs tidying up, my hope is that as the Ibex
7
PLIC move towards spec compliance this PLIC implementation can be
8
updated until it can replace the current PLIC.
9
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
---
13
include/hw/intc/ibex_plic.h | 63 +++++++++
14
hw/intc/ibex_plic.c | 261 ++++++++++++++++++++++++++++++++++++
15
MAINTAINERS | 2 +
16
hw/intc/Makefile.objs | 1 +
17
4 files changed, 327 insertions(+)
18
create mode 100644 include/hw/intc/ibex_plic.h
19
create mode 100644 hw/intc/ibex_plic.c
20
21
diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
22
new file mode 100644
23
index XXXXXXX..XXXXXXX
24
--- /dev/null
25
+++ b/include/hw/intc/ibex_plic.h
26
@@ -XXX,XX +XXX,XX @@
27
+/*
28
+ * QEMU RISC-V lowRISC Ibex PLIC
29
+ *
30
+ * Copyright (c) 2020 Western Digital
31
+ *
32
+ * This program is free software; you can redistribute it and/or modify it
33
+ * under the terms and conditions of the GNU General Public License,
34
+ * version 2 or later, as published by the Free Software Foundation.
35
+ *
36
+ * This program is distributed in the hope it will be useful, but WITHOUT
37
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
38
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
39
+ * more details.
40
+ *
41
+ * You should have received a copy of the GNU General Public License along with
42
+ * this program. If not, see <http://www.gnu.org/licenses/>.
43
+ */
44
+
45
+#ifndef HW_IBEX_PLIC_H
46
+#define HW_IBEX_PLIC_H
47
+
48
+#include "hw/sysbus.h"
49
+
50
+#define TYPE_IBEX_PLIC "ibex-plic"
51
+#define IBEX_PLIC(obj) \
52
+ OBJECT_CHECK(IbexPlicState, (obj), TYPE_IBEX_PLIC)
53
+
54
+typedef struct IbexPlicState {
55
+ /*< private >*/
56
+ SysBusDevice parent_obj;
57
+
58
+ /*< public >*/
59
+ MemoryRegion mmio;
60
+
61
+ uint32_t *pending;
62
+ uint32_t *source;
63
+ uint32_t *priority;
64
+ uint32_t *enable;
65
+ uint32_t threshold;
66
+ uint32_t claim;
67
+
68
+ /* config */
69
+ uint32_t num_cpus;
70
+ uint32_t num_sources;
71
+
72
+ uint32_t pending_base;
73
+ uint32_t pending_num;
74
+
75
+ uint32_t source_base;
76
+ uint32_t source_num;
77
+
78
+ uint32_t priority_base;
79
+ uint32_t priority_num;
80
+
81
+ uint32_t enable_base;
82
+ uint32_t enable_num;
83
+
84
+ uint32_t threshold_base;
85
+
86
+ uint32_t claim_base;
87
+} IbexPlicState;
88
+
89
+#endif /* HW_IBEX_PLIC_H */
90
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
91
new file mode 100644
92
index XXXXXXX..XXXXXXX
93
--- /dev/null
94
+++ b/hw/intc/ibex_plic.c
95
@@ -XXX,XX +XXX,XX @@
96
+/*
97
+ * QEMU RISC-V lowRISC Ibex PLIC
98
+ *
99
+ * Copyright (c) 2020 Western Digital
100
+ *
101
+ * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
102
+ *
103
+ * This program is free software; you can redistribute it and/or modify it
104
+ * under the terms and conditions of the GNU General Public License,
105
+ * version 2 or later, as published by the Free Software Foundation.
106
+ *
107
+ * This program is distributed in the hope it will be useful, but WITHOUT
108
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
109
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
110
+ * more details.
111
+ *
112
+ * You should have received a copy of the GNU General Public License along with
113
+ * this program. If not, see <http://www.gnu.org/licenses/>.
114
+ */
115
+
116
+#include "qemu/osdep.h"
117
+#include "qemu/log.h"
118
+#include "hw/qdev-properties.h"
119
+#include "hw/core/cpu.h"
120
+#include "hw/boards.h"
121
+#include "hw/pci/msi.h"
122
+#include "target/riscv/cpu_bits.h"
123
+#include "target/riscv/cpu.h"
124
+#include "hw/intc/ibex_plic.h"
125
+
126
+static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
127
+{
128
+ uint32_t end = base + (num * 0x04);
129
+
130
+ if (addr >= base && addr < end) {
131
+ return true;
132
+ }
133
+
134
+ return false;
135
+}
136
+
137
+static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
138
+{
139
+ int pending_num = irq / 32;
140
+
141
+ s->pending[pending_num] |= level << (irq % 32);
142
+}
143
+
144
+static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
145
+{
146
+ int i;
147
+
148
+ for (i = 0; i < s->pending_num; i++) {
149
+ uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
150
+
151
+ if (!(s->pending[i] & s->enable[i])) {
152
+ /* No pending and enabled IRQ */
153
+ continue;
154
+ }
155
+
156
+ if (s->priority[irq_num] > s->threshold) {
157
+ if (!s->claim) {
158
+ s->claim = irq_num;
159
+ }
160
+ return true;
161
+ }
162
+ }
163
+
164
+ return false;
165
+}
166
+
167
+static void ibex_plic_update(IbexPlicState *s)
168
+{
169
+ CPUState *cpu;
170
+ int level, i;
171
+
172
+ for (i = 0; i < s->num_cpus; i++) {
173
+ cpu = qemu_get_cpu(i);
174
+
175
+ if (!cpu) {
176
+ continue;
177
+ }
178
+
179
+ level = ibex_plic_irqs_pending(s, 0);
180
+
181
+ riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
182
+ }
183
+}
184
+
185
+static void ibex_plic_reset(DeviceState *dev)
186
+{
187
+ IbexPlicState *s = IBEX_PLIC(dev);
188
+
189
+ s->threshold = 0x00000000;
190
+ s->claim = 0x00000000;
191
+}
192
+
193
+static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
194
+ unsigned int size)
195
+{
196
+ IbexPlicState *s = opaque;
197
+ int offset;
198
+ uint32_t ret = 0;
199
+
200
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
201
+ offset = (addr - s->pending_base) / 4;
202
+ ret = s->pending[offset];
203
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
204
+ qemu_log_mask(LOG_UNIMP,
205
+ "%s: Interrupt source mode not supported\n", __func__);
206
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
207
+ offset = (addr - s->priority_base) / 4;
208
+ ret = s->priority[offset];
209
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
210
+ offset = (addr - s->enable_base) / 4;
211
+ ret = s->enable[offset];
212
+ } else if (addr_between(addr, s->threshold_base, 1)) {
213
+ ret = s->threshold;
214
+ } else if (addr_between(addr, s->claim_base, 1)) {
215
+ int pending_num = s->claim / 32;
216
+ s->pending[pending_num] &= ~(1 << (s->claim % 32));
217
+
218
+ ret = s->claim;
219
+ }
220
+
221
+ return ret;
222
+}
223
+
224
+static void ibex_plic_write(void *opaque, hwaddr addr,
225
+ uint64_t value, unsigned int size)
226
+{
227
+ IbexPlicState *s = opaque;
228
+
229
+ if (addr_between(addr, s->pending_base, s->pending_num)) {
230
+ qemu_log_mask(LOG_GUEST_ERROR,
231
+ "%s: Pending registers are read only\n", __func__);
232
+ } else if (addr_between(addr, s->source_base, s->source_num)) {
233
+ qemu_log_mask(LOG_UNIMP,
234
+ "%s: Interrupt source mode not supported\n", __func__);
235
+ } else if (addr_between(addr, s->priority_base, s->priority_num)) {
236
+ uint32_t irq = ((addr - s->priority_base) >> 2) + 1;
237
+ s->priority[irq] = value & 7;
238
+ } else if (addr_between(addr, s->enable_base, s->enable_num)) {
239
+ uint32_t enable_reg = (addr - s->enable_base) / 4;
240
+
241
+ s->enable[enable_reg] = value;
242
+ } else if (addr_between(addr, s->threshold_base, 1)) {
243
+ s->threshold = value & 3;
244
+ } else if (addr_between(addr, s->claim_base, 1)) {
245
+ if (s->claim == value) {
246
+ /* Interrupt was completed */
247
+ s->claim = 0;
248
+ }
249
+ }
250
+
251
+ ibex_plic_update(s);
252
+}
253
+
254
+static const MemoryRegionOps ibex_plic_ops = {
255
+ .read = ibex_plic_read,
256
+ .write = ibex_plic_write,
257
+ .endianness = DEVICE_NATIVE_ENDIAN,
258
+ .valid = {
259
+ .min_access_size = 4,
260
+ .max_access_size = 4
261
+ }
262
+};
263
+
264
+static void ibex_plic_irq_request(void *opaque, int irq, int level)
265
+{
266
+ IbexPlicState *s = opaque;
267
+
268
+ ibex_plic_irqs_set_pending(s, irq, level > 0);
269
+ ibex_plic_update(s);
270
+}
271
+
272
+static Property ibex_plic_properties[] = {
273
+ DEFINE_PROP_UINT32("num-cpus", IbexPlicState, num_cpus, 1),
274
+ DEFINE_PROP_UINT32("num-sources", IbexPlicState, num_sources, 80),
275
+
276
+ DEFINE_PROP_UINT32("pending-base", IbexPlicState, pending_base, 0),
277
+ DEFINE_PROP_UINT32("pending-num", IbexPlicState, pending_num, 3),
278
+
279
+ DEFINE_PROP_UINT32("source-base", IbexPlicState, source_base, 0x0c),
280
+ DEFINE_PROP_UINT32("source-num", IbexPlicState, source_num, 3),
281
+
282
+ DEFINE_PROP_UINT32("priority-base", IbexPlicState, priority_base, 0x18),
283
+ DEFINE_PROP_UINT32("priority-num", IbexPlicState, priority_num, 80),
284
+
285
+ DEFINE_PROP_UINT32("enable-base", IbexPlicState, enable_base, 0x200),
286
+ DEFINE_PROP_UINT32("enable-num", IbexPlicState, enable_num, 3),
287
+
288
+ DEFINE_PROP_UINT32("threshold-base", IbexPlicState, threshold_base, 0x20c),
289
+
290
+ DEFINE_PROP_UINT32("claim-base", IbexPlicState, claim_base, 0x210),
291
+ DEFINE_PROP_END_OF_LIST(),
292
+};
293
+
294
+static void ibex_plic_init(Object *obj)
295
+{
296
+ IbexPlicState *s = IBEX_PLIC(obj);
297
+
298
+ memory_region_init_io(&s->mmio, obj, &ibex_plic_ops, s,
299
+ TYPE_IBEX_PLIC, 0x400);
300
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
301
+}
302
+
303
+static void ibex_plic_realize(DeviceState *dev, Error **errp)
304
+{
305
+ IbexPlicState *s = IBEX_PLIC(dev);
306
+ int i;
307
+
308
+ s->pending = g_new0(uint32_t, s->pending_num);
309
+ s->source = g_new0(uint32_t, s->source_num);
310
+ s->priority = g_new0(uint32_t, s->priority_num);
311
+ s->enable = g_new0(uint32_t, s->enable_num);
312
+
313
+ qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
314
+
315
+ /*
316
+ * We can't allow the supervisor to control SEIP as this would allow the
317
+ * supervisor to clear a pending external interrupt which will result in
318
+ * a lost interrupt in the case a PLIC is attached. The SEIP bit must be
319
+ * hardware controlled when a PLIC is attached.
320
+ */
321
+ MachineState *ms = MACHINE(qdev_get_machine());
322
+ unsigned int smp_cpus = ms->smp.cpus;
323
+ for (i = 0; i < smp_cpus; i++) {
324
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
325
+ if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
326
+ error_report("SEIP already claimed");
327
+ exit(1);
328
+ }
329
+ }
330
+
331
+ msi_nonbroken = true;
332
+}
333
+
334
+static void ibex_plic_class_init(ObjectClass *klass, void *data)
335
+{
336
+ DeviceClass *dc = DEVICE_CLASS(klass);
337
+
338
+ dc->reset = ibex_plic_reset;
339
+ device_class_set_props(dc, ibex_plic_properties);
340
+ dc->realize = ibex_plic_realize;
341
+}
342
+
343
+static const TypeInfo ibex_plic_info = {
344
+ .name = TYPE_IBEX_PLIC,
345
+ .parent = TYPE_SYS_BUS_DEVICE,
346
+ .instance_size = sizeof(IbexPlicState),
347
+ .instance_init = ibex_plic_init,
348
+ .class_init = ibex_plic_class_init,
349
+};
350
+
351
+static void ibex_plic_register_types(void)
352
+{
353
+ type_register_static(&ibex_plic_info);
354
+}
355
+
356
+type_init(ibex_plic_register_types)
357
diff --git a/MAINTAINERS b/MAINTAINERS
358
index XXXXXXX..XXXXXXX 100644
359
--- a/MAINTAINERS
360
+++ b/MAINTAINERS
361
@@ -XXX,XX +XXX,XX @@ L: qemu-riscv@nongnu.org
362
S: Supported
363
F: hw/riscv/opentitan.c
364
F: hw/char/ibex_uart.c
365
+F: hw/intc/ibex_plic.c
366
F: include/hw/riscv/opentitan.h
367
F: include/hw/char/ibex_uart.h
368
+F: include/hw/intc/ibex_plic.h
369
370
SH4 Machines
371
------------
372
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
373
index XXXXXXX..XXXXXXX 100644
374
--- a/hw/intc/Makefile.objs
375
+++ b/hw/intc/Makefile.objs
376
@@ -XXX,XX +XXX,XX @@ obj-$(CONFIG_ARM_GIC) += arm_gicv3_cpuif.o
377
obj-$(CONFIG_MIPS_CPS) += mips_gic.o
378
obj-$(CONFIG_NIOS2) += nios2_iic.o
379
obj-$(CONFIG_OMPIC) += ompic.o
380
+obj-$(CONFIG_IBEX) += ibex_plic.o
381
--
382
2.27.0
383
384
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
5
include/hw/riscv/opentitan.h | 3 +++
6
hw/riscv/opentitan.c | 14 ++++++++++++--
7
2 files changed, 15 insertions(+), 2 deletions(-)
1
8
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
12
+++ b/include/hw/riscv/opentitan.h
13
@@ -XXX,XX +XXX,XX @@
14
#define HW_OPENTITAN_H
15
16
#include "hw/riscv/riscv_hart.h"
17
+#include "hw/intc/ibex_plic.h"
18
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
20
#define RISCV_IBEX_SOC(obj) \
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
22
23
/*< public >*/
24
RISCVHartArrayState cpus;
25
+ IbexPlicState plic;
26
+
27
MemoryRegion flash_mem;
28
MemoryRegion rom;
29
} LowRISCIbexSoCState;
30
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/opentitan.c
33
+++ b/hw/riscv/opentitan.c
34
@@ -XXX,XX +XXX,XX @@
35
#include "hw/riscv/boot.h"
36
#include "exec/address-spaces.h"
37
#include "qemu/units.h"
38
+#include "sysemu/sysemu.h"
39
40
static const struct MemmapEntry {
41
hwaddr base;
42
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
43
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
44
45
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
46
+
47
+ object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
48
}
49
50
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
51
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
52
MachineState *ms = MACHINE(qdev_get_machine());
53
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
54
MemoryRegion *sys_mem = get_system_memory();
55
+ Error *err = NULL;
56
57
object_property_set_str(OBJECT(&s->cpus), ms->cpu_type, "cpu-type",
58
&error_abort);
59
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
60
memory_region_add_subregion(sys_mem, memmap[IBEX_FLASH].base,
61
&s->flash_mem);
62
63
+ /* PLIC */
64
+ sysbus_realize(SYS_BUS_DEVICE(&s->plic), &err);
65
+ if (err != NULL) {
66
+ error_propagate(errp, err);
67
+ return;
68
+ }
69
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
70
+
71
create_unimplemented_device("riscv.lowrisc.ibex.uart",
72
memmap[IBEX_UART].base, memmap[IBEX_UART].size);
73
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
74
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
75
memmap[IBEX_AES].base, memmap[IBEX_AES].size);
76
create_unimplemented_device("riscv.lowrisc.ibex.hmac",
77
memmap[IBEX_HMAC].base, memmap[IBEX_HMAC].size);
78
- create_unimplemented_device("riscv.lowrisc.ibex.plic",
79
- memmap[IBEX_PLIC].base, memmap[IBEX_PLIC].size);
80
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
81
memmap[IBEX_PINMUX].base, memmap[IBEX_PINMUX].size);
82
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
83
--
84
2.27.0
85
86
diff view generated by jsdifflib
New patch
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
4
---
5
include/hw/riscv/opentitan.h | 13 +++++++++++++
6
hw/riscv/opentitan.c | 25 +++++++++++++++++++++++--
7
2 files changed, 36 insertions(+), 2 deletions(-)
1
8
9
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
10
index XXXXXXX..XXXXXXX 100644
11
--- a/include/hw/riscv/opentitan.h
12
+++ b/include/hw/riscv/opentitan.h
13
@@ -XXX,XX +XXX,XX @@
14
15
#include "hw/riscv/riscv_hart.h"
16
#include "hw/intc/ibex_plic.h"
17
+#include "hw/char/ibex_uart.h"
18
19
#define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc"
20
#define RISCV_IBEX_SOC(obj) \
21
@@ -XXX,XX +XXX,XX @@ typedef struct LowRISCIbexSoCState {
22
/*< public >*/
23
RISCVHartArrayState cpus;
24
IbexPlicState plic;
25
+ IbexUartState uart;
26
27
MemoryRegion flash_mem;
28
MemoryRegion rom;
29
@@ -XXX,XX +XXX,XX @@ enum {
30
IBEX_PADCTRL,
31
};
32
33
+enum {
34
+ IBEX_UART_RX_PARITY_ERR_IRQ = 0x28,
35
+ IBEX_UART_RX_TIMEOUT_IRQ = 0x27,
36
+ IBEX_UART_RX_BREAK_ERR_IRQ = 0x26,
37
+ IBEX_UART_RX_FRAME_ERR_IRQ = 0x25,
38
+ IBEX_UART_RX_OVERFLOW_IRQ = 0x24,
39
+ IBEX_UART_TX_EMPTY_IRQ = 0x23,
40
+ IBEX_UART_RX_WATERMARK_IRQ = 0x22,
41
+ IBEX_UART_TX_WATERMARK_IRQ = 0x21,
42
+};
43
+
44
#endif
45
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/hw/riscv/opentitan.c
48
+++ b/hw/riscv/opentitan.c
49
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
50
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
51
52
object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
53
+
54
+ object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
55
}
56
57
static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
59
}
60
sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_PLIC].base);
61
62
- create_unimplemented_device("riscv.lowrisc.ibex.uart",
63
- memmap[IBEX_UART].base, memmap[IBEX_UART].size);
64
+ /* UART */
65
+ qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
66
+ sysbus_realize(SYS_BUS_DEVICE(&s->uart), &err);
67
+ if (err != NULL) {
68
+ error_propagate(errp, err);
69
+ return;
70
+ }
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->uart), 0, memmap[IBEX_UART].base);
72
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
73
+ 0, qdev_get_gpio_in(DEVICE(&s->plic),
74
+ IBEX_UART_TX_WATERMARK_IRQ));
75
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
76
+ 1, qdev_get_gpio_in(DEVICE(&s->plic),
77
+ IBEX_UART_RX_WATERMARK_IRQ));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
79
+ 2, qdev_get_gpio_in(DEVICE(&s->plic),
80
+ IBEX_UART_TX_EMPTY_IRQ));
81
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->uart),
82
+ 3, qdev_get_gpio_in(DEVICE(&s->plic),
83
+ IBEX_UART_RX_OVERFLOW_IRQ));
84
+
85
create_unimplemented_device("riscv.lowrisc.ibex.gpio",
86
memmap[IBEX_GPIO].base, memmap[IBEX_GPIO].size);
87
create_unimplemented_device("riscv.lowrisc.ibex.spi",
88
--
89
2.27.0
90
91
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
2
Reviewed-by: Bin Meng <bin.meng@windriver.com>
3
---
4
target/riscv/pmp.c | 14 +++++++++-----
5
1 file changed, 9 insertions(+), 5 deletions(-)
2
6
3
Commit 33a24910ae changed 'reg_width' to use 'vlenb', i.e. vector length
7
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
4
in bytes, when in this context we want 'reg_width' as the length in
5
bits.
6
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>
24
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
25
Cc: qemu-stable <qemu-stable@nongnu.org>
26
Message-ID: <20240517203054.880861-2-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
29
target/riscv/gdbstub.c | 6 +++---
30
1 file changed, 3 insertions(+), 3 deletions(-)
31
32
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
33
index XXXXXXX..XXXXXXX 100644
8
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/gdbstub.c
9
--- a/target/riscv/pmp.c
35
+++ b/target/riscv/gdbstub.c
10
+++ b/target/riscv/pmp.c
36
@@ -XXX,XX +XXX,XX @@ static GDBFeature *riscv_gen_dynamic_csr_feature(CPUState *cs, int base_reg)
11
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
37
static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
12
return true;
38
{
39
RISCVCPU *cpu = RISCV_CPU(cs);
40
- int reg_width = cpu->cfg.vlenb;
41
+ int bitsize = cpu->cfg.vlenb << 3;
42
GDBFeatureBuilder builder;
43
int i;
44
45
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
46
47
/* First define types and totals in a whole VL */
48
for (i = 0; i < ARRAY_SIZE(vec_lanes); i++) {
49
- int count = reg_width / vec_lanes[i].size;
50
+ int count = bitsize / vec_lanes[i].size;
51
gdb_feature_builder_append_tag(
52
&builder, "<vector id=\"%s\" type=\"%s\" count=\"%d\"/>",
53
vec_lanes[i].id, vec_lanes[i].gdb_type, count);
54
@@ -XXX,XX +XXX,XX @@ static GDBFeature *ricsv_gen_dynamic_vector_feature(CPUState *cs, int base_reg)
55
/* Define vector registers */
56
for (i = 0; i < 32; i++) {
57
gdb_feature_builder_append_reg(&builder, g_strdup_printf("v%d", i),
58
- reg_width, i, "riscv_vector", "vector");
59
+ bitsize, i, "riscv_vector", "vector");
60
}
13
}
61
14
62
gdb_feature_builder_end(&builder);
15
- /*
16
- * if size is unknown (0), assume that all bytes
17
- * from addr to the end of the page will be accessed.
18
- */
19
if (size == 0) {
20
- pmp_size = -(addr | TARGET_PAGE_MASK);
21
+ if (riscv_feature(env, RISCV_FEATURE_MMU)) {
22
+ /*
23
+ * If size is unknown (0), assume that all bytes
24
+ * from addr to the end of the page will be accessed.
25
+ */
26
+ pmp_size = -(addr | TARGET_PAGE_MASK);
27
+ } else {
28
+ pmp_size = sizeof(target_ulong);
29
+ }
30
} else {
31
pmp_size = size;
32
}
63
--
33
--
64
2.45.1
34
2.27.0
65
35
66
36
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
If the checking functions check both the single and double width
3
This was done in the virt & sifive_u codes, but sifive_e codes were
4
operators at the same time, then the single width operator checking
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
5
functions (require_rvf[min]) will check whether the SEW is 8.
6
5
7
Signed-off-by: Max Chou <max.chou@sifive.com>
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Cc: qemu-stable <qemu-stable@nongnu.org>
8
Message-id: 1591625864-31494-2-git-send-email-bmeng.cn@gmail.com
10
Message-ID: <20240322092600.1198921-5-max.chou@sifive.com>
9
Message-Id: <1591625864-31494-2-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/insn_trans/trans_rvv.c.inc | 16 ++++------------
12
hw/riscv/sifive_e.c | 24 ++++++++++++------------
14
1 file changed, 4 insertions(+), 12 deletions(-)
13
1 file changed, 12 insertions(+), 12 deletions(-)
15
14
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
--- a/hw/riscv/sifive_e.c
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/hw/riscv/sifive_e.c
20
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
21
return require_rvv(s) &&
20
[SIFIVE_E_DTIM] = { 0x80000000, 0x4000 }
22
require_rvf(s) &&
21
};
23
require_scale_rvf(s) &&
22
24
- (s->sew != MO_8) &&
23
-static void riscv_sifive_e_init(MachineState *machine)
25
vext_check_isa_ill(s) &&
24
+static void sifive_e_machine_init(MachineState *machine)
26
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
25
{
26
const struct MemmapEntry *memmap = sifive_e_memmap;
27
28
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
29
MachineClass *mc = MACHINE_CLASS(oc);
30
31
mc->desc = "RISC-V Board compatible with SiFive E SDK";
32
- mc->init = riscv_sifive_e_init;
33
+ mc->init = sifive_e_machine_init;
34
mc->max_cpus = 1;
35
mc->default_cpu_type = SIFIVE_E_CPU;
27
}
36
}
28
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
37
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init_register_types(void)
29
return require_rvv(s) &&
38
30
require_rvf(s) &&
39
type_init(sifive_e_machine_init_register_types)
31
require_scale_rvf(s) &&
40
32
- (s->sew != MO_8) &&
41
-static void riscv_sifive_e_soc_init(Object *obj)
33
vext_check_isa_ill(s) &&
42
+static void sifive_e_soc_init(Object *obj)
34
vext_check_ds(s, a->rd, a->rs2, a->vm);
43
{
44
MachineState *ms = MACHINE(qdev_get_machine());
45
SiFiveESoCState *s = RISCV_E_SOC(obj);
46
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_init(Object *obj)
47
TYPE_SIFIVE_GPIO);
35
}
48
}
36
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
49
37
return require_rvv(s) &&
50
-static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
38
require_rvf(s) &&
51
+static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
39
require_scale_rvf(s) &&
52
{
40
- (s->sew != MO_8) &&
53
MachineState *ms = MACHINE(qdev_get_machine());
41
vext_check_isa_ill(s) &&
54
const struct MemmapEntry *memmap = sifive_e_memmap;
42
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
55
@@ -XXX,XX +XXX,XX @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
56
&s->xip_mem);
43
}
57
}
44
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
58
45
return require_rvv(s) &&
59
-static void riscv_sifive_e_soc_class_init(ObjectClass *oc, void *data)
46
require_rvf(s) &&
60
+static void sifive_e_soc_class_init(ObjectClass *oc, void *data)
47
require_scale_rvf(s) &&
61
{
48
- (s->sew != MO_8) &&
62
DeviceClass *dc = DEVICE_CLASS(oc);
49
vext_check_isa_ill(s) &&
63
50
vext_check_dd(s, a->rd, a->rs2, a->vm);
64
- dc->realize = riscv_sifive_e_soc_realize;
65
+ dc->realize = sifive_e_soc_realize;
66
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
67
dc->user_creatable = false;
51
}
68
}
52
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
69
70
-static const TypeInfo riscv_sifive_e_soc_type_info = {
71
+static const TypeInfo sifive_e_soc_type_info = {
72
.name = TYPE_RISCV_E_SOC,
73
.parent = TYPE_DEVICE,
74
.instance_size = sizeof(SiFiveESoCState),
75
- .instance_init = riscv_sifive_e_soc_init,
76
- .class_init = riscv_sifive_e_soc_class_init,
77
+ .instance_init = sifive_e_soc_init,
78
+ .class_init = sifive_e_soc_class_init,
79
};
80
81
-static void riscv_sifive_e_soc_register_types(void)
82
+static void sifive_e_soc_register_types(void)
53
{
83
{
54
return opfv_widen_check(s, a) &&
84
- type_register_static(&riscv_sifive_e_soc_type_info);
55
require_rvfmin(s) &&
85
+ type_register_static(&sifive_e_soc_type_info);
56
- require_scale_rvfmin(s) &&
57
- (s->sew != MO_8);
58
+ require_scale_rvfmin(s);
59
}
86
}
60
87
61
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
88
-type_init(riscv_sifive_e_soc_register_types)
62
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
89
+type_init(sifive_e_soc_register_types)
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
--
90
--
92
2.45.1
91
2.27.0
92
93
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
SBI defines a Debug Console extension "DBCN" that will, in time, replace
3
This was done in the virt & sifive_u codes, but opentitan codes were
4
the legacy console putchar and getchar SBI extensions.
4
missed. Remove the riscv_ prefix of the machine* and soc* functions.
5
5
6
The appeal of the DBCN extension is that it allows multiple bytes to be
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
read/written in the SBI console in a single SBI call.
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
8
Message-id: 1591625864-31494-3-git-send-email-bmeng.cn@gmail.com
9
As far as KVM goes, the DBCN calls are forwarded by an in-kernel KVM
9
Message-Id: <1591625864-31494-3-git-send-email-bmeng.cn@gmail.com>
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>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
---
11
---
31
target/riscv/sbi_ecall_interface.h | 17 +++++
12
hw/riscv/opentitan.c | 29 ++++++++++++++---------------
32
target/riscv/kvm/kvm-cpu.c | 111 +++++++++++++++++++++++++++++
13
1 file changed, 14 insertions(+), 15 deletions(-)
33
2 files changed, 128 insertions(+)
34
14
35
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
36
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/sbi_ecall_interface.h
17
--- a/hw/riscv/opentitan.c
38
+++ b/target/riscv/sbi_ecall_interface.h
18
+++ b/hw/riscv/opentitan.c
39
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
40
20
[IBEX_PADCTRL] = { 0x40160000, 0x10000 }
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
};
21
};
84
22
85
+static KVMCPUConfig kvm_sbi_dbcn = {
23
-static void riscv_opentitan_init(MachineState *machine)
86
+ .name = "sbi_dbcn",
24
+static void opentitan_board_init(MachineState *machine)
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
{
25
{
93
CPURISCVState *env = &cpu->env;
26
const struct MemmapEntry *memmap = ibex_memmap;
94
@@ -XXX,XX +XXX,XX @@ static int uint64_cmp(const void *a, const void *b)
27
OpenTitanState *s = g_new0(OpenTitanState, 1);
95
return 0;
28
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
29
memory_region_add_subregion(sys_mem,
30
memmap[IBEX_RAM].base, main_mem);
31
32
-
33
if (machine->firmware) {
34
riscv_load_firmware(machine->firmware, memmap[IBEX_RAM].base, NULL);
35
}
36
@@ -XXX,XX +XXX,XX @@ static void riscv_opentitan_init(MachineState *machine)
37
}
96
}
38
}
97
39
98
+static void kvm_riscv_check_sbi_dbcn_support(RISCVCPU *cpu,
40
-static void riscv_opentitan_machine_init(MachineClass *mc)
99
+ KVMScratchCPU *kvmcpu,
41
+static void opentitan_machine_init(MachineClass *mc)
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
{
42
{
115
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
43
mc->desc = "RISC-V Board compatible with OpenTitan";
116
if (riscv_has_ext(&cpu->env, RVV)) {
44
- mc->init = riscv_opentitan_init;
117
kvm_riscv_read_vlenb(cpu, kvmcpu, reglist);
45
+ mc->init = opentitan_board_init;
118
}
46
mc->max_cpus = 1;
119
+
47
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
120
+ kvm_riscv_check_sbi_dbcn_support(cpu, kvmcpu, reglist);
121
}
48
}
122
49
123
static void riscv_init_kvm_registers(Object *cpu_obj)
50
-DEFINE_MACHINE("opentitan", riscv_opentitan_machine_init)
124
@@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
51
+DEFINE_MACHINE("opentitan", opentitan_machine_init)
125
return ret;
52
53
-static void riscv_lowrisc_ibex_soc_init(Object *obj)
54
+static void lowrisc_ibex_soc_init(Object *obj)
55
{
56
LowRISCIbexSoCState *s = RISCV_IBEX_SOC(obj);
57
58
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_init(Object *obj)
59
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
126
}
60
}
127
61
128
+static int kvm_vcpu_enable_sbi_dbcn(RISCVCPU *cpu, CPUState *cs)
62
-static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
129
+{
63
+static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
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
{
64
{
141
int ret = 0;
65
const struct MemmapEntry *memmap = ibex_memmap;
142
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
66
MachineState *ms = MACHINE(qdev_get_machine());
143
kvm_riscv_update_cpu_misa_ext(cpu, cs);
67
@@ -XXX,XX +XXX,XX @@ static void riscv_lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
144
kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
68
memmap[IBEX_PADCTRL].base, memmap[IBEX_PADCTRL].size);
145
146
+ ret = kvm_vcpu_enable_sbi_dbcn(cpu, cs);
147
+
148
return ret;
149
}
69
}
150
70
151
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
71
-static void riscv_lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
152
return true;
72
+static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
73
{
74
DeviceClass *dc = DEVICE_CLASS(oc);
75
76
- dc->realize = riscv_lowrisc_ibex_soc_realize;
77
+ dc->realize = lowrisc_ibex_soc_realize;
78
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
79
dc->user_creatable = false;
153
}
80
}
154
81
155
+static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
82
-static const TypeInfo riscv_lowrisc_ibex_soc_type_info = {
156
+{
83
+static const TypeInfo lowrisc_ibex_soc_type_info = {
157
+ g_autofree uint8_t *buf = NULL;
84
.name = TYPE_RISCV_IBEX_SOC,
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
85
.parent = TYPE_DEVICE,
159
+ target_ulong num_bytes;
86
.instance_size = sizeof(LowRISCIbexSoCState),
160
+ uint64_t addr;
87
- .instance_init = riscv_lowrisc_ibex_soc_init,
161
+ unsigned char ch;
88
- .class_init = riscv_lowrisc_ibex_soc_class_init,
162
+ int ret;
89
+ .instance_init = lowrisc_ibex_soc_init,
163
+
90
+ .class_init = lowrisc_ibex_soc_class_init,
164
+ switch (run->riscv_sbi.function_id) {
91
};
165
+ case SBI_EXT_DBCN_CONSOLE_READ:
92
166
+ case SBI_EXT_DBCN_CONSOLE_WRITE:
93
-static void riscv_lowrisc_ibex_soc_register_types(void)
167
+ num_bytes = run->riscv_sbi.args[0];
94
+static void lowrisc_ibex_soc_register_types(void)
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
{
95
{
230
int ret = 0;
96
- type_register_static(&riscv_lowrisc_ibex_soc_type_info);
231
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
97
+ type_register_static(&lowrisc_ibex_soc_type_info);
232
}
98
}
233
ret = 0;
99
234
break;
100
-type_init(riscv_lowrisc_ibex_soc_register_types)
235
+ case SBI_EXT_DBCN:
101
+type_init(lowrisc_ibex_soc_register_types)
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
--
102
--
242
2.45.1
103
2.27.0
104
105
diff view generated by jsdifflib
1
From: Clément Léger <cleger@rivosinc.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The current semihost exception number (16) is a reserved number (range
3
There is no need to retrieve all PLIC IRQ information in order to
4
[16-17]). The upcoming double trap specification uses that number for
4
just connect the GEM IRQ. Use qdev_get_gpio_in() directly like
5
the double trap exception. Since the privileged spec (Table 22) defines
5
what is done for other peripherals.
6
ranges for custom uses change the semihosting exception number to 63
7
which belongs to the range [48-63] in order to avoid any future
8
collisions with reserved exception.
9
6
10
Signed-off-by: Clément Léger <cleger@rivosinc.com>
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
11
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20240422135840.1959967-1-cleger@rivosinc.com>
9
Message-id: 1591625864-31494-4-git-send-email-bmeng.cn@gmail.com
10
Message-Id: <1591625864-31494-4-git-send-email-bmeng.cn@gmail.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
12
---
16
target/riscv/cpu_bits.h | 2 +-
13
hw/riscv/sifive_u.c | 7 +------
17
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 6 deletions(-)
18
15
19
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu_bits.h
18
--- a/hw/riscv/sifive_u.c
22
+++ b/target/riscv/cpu_bits.h
19
+++ b/hw/riscv/sifive_u.c
23
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
20
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
24
RISCV_EXCP_INST_PAGE_FAULT = 0xc, /* since: priv-1.10.0 */
21
MemoryRegion *system_memory = get_system_memory();
25
RISCV_EXCP_LOAD_PAGE_FAULT = 0xd, /* since: priv-1.10.0 */
22
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
26
RISCV_EXCP_STORE_PAGE_FAULT = 0xf, /* since: priv-1.10.0 */
23
MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
27
- RISCV_EXCP_SEMIHOST = 0x10,
24
- qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
28
RISCV_EXCP_INST_GUEST_PAGE_FAULT = 0x14,
25
char *plic_hart_config;
29
RISCV_EXCP_LOAD_GUEST_ACCESS_FAULT = 0x15,
26
size_t plic_hart_config_len;
30
RISCV_EXCP_VIRT_INSTRUCTION_FAULT = 0x16,
27
int i;
31
RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT = 0x17,
28
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
32
+ RISCV_EXCP_SEMIHOST = 0x3f,
29
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
33
} RISCVException;
30
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
34
31
35
#define RISCV_EXCP_INT_FLAG 0x80000000
32
- for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
33
- plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
34
- }
35
-
36
if (nd->used) {
37
qemu_check_nic_model(nd, TYPE_CADENCE_GEM);
38
qdev_set_nic_properties(DEVICE(&s->gem), nd);
39
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
40
}
41
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_GEM].base);
42
sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
43
- plic_gpios[SIFIVE_U_GEM_IRQ]);
44
+ qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_GEM_IRQ));
45
46
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
47
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
36
--
48
--
37
2.45.1
49
2.27.0
38
50
39
51
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The opfv_narrow_check needs to check the single width float operator by
3
Upstream U-Boot v2020.07 codes switch to access SiFive FU540 OTP
4
require_rvf.
4
based on device tree information. Let's generate the device tree
5
node for OTP.
5
6
6
Signed-off-by: Max Chou <max.chou@sifive.com>
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Cc: qemu-stable <qemu-stable@nongnu.org>
9
Message-id: 1591625864-31494-5-git-send-email-bmeng.cn@gmail.com
9
Message-ID: <20240322092600.1198921-4-max.chou@sifive.com>
10
Message-Id: <1591625864-31494-5-git-send-email-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
13
hw/riscv/sifive_u.c | 11 +++++++++++
13
1 file changed, 1 insertion(+)
14
1 file changed, 11 insertions(+)
14
15
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
--- a/hw/riscv/sifive_u.c
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/hw/riscv/sifive_u.c
19
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
20
static bool opffv_rod_narrow_check(DisasContext *s, arg_rmr *a)
21
g_free(cells);
21
{
22
g_free(nodename);
22
return opfv_narrow_check(s, a) &&
23
23
+ require_rvf(s) &&
24
+ nodename = g_strdup_printf("/soc/otp@%lx",
24
require_scale_rvf(s) &&
25
+ (long)memmap[SIFIVE_U_OTP].base);
25
(s->sew != MO_8);
26
+ qemu_fdt_add_subnode(fdt, nodename);
26
}
27
+ qemu_fdt_setprop_cell(fdt, nodename, "fuse-count", SIFIVE_U_OTP_REG_SIZE);
28
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
29
+ 0x0, memmap[SIFIVE_U_OTP].base,
30
+ 0x0, memmap[SIFIVE_U_OTP].size);
31
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
32
+ "sifive,fu540-c000-otp");
33
+ g_free(nodename);
34
+
35
prci_phandle = phandle++;
36
nodename = g_strdup_printf("/soc/clock-controller@%lx",
37
(long)memmap[SIFIVE_U_PRCI].base);
27
--
38
--
28
2.45.1
39
2.27.0
40
41
diff view generated by jsdifflib
1
From: Alistair Francis <alistair23@gmail.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
When running the instruction
3
Do various minor clean-ups to the exisiting codes for:
4
4
5
```
5
- coding convention conformance
6
cbo.flush 0(x0)
6
- remove unnecessary blank lines
7
```
7
- spell SiFive correctly
8
8
9
QEMU would segfault.
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
The issue was in cpu_gpr[a->rs1] as QEMU does not have cpu_gpr[0]
11
Message-id: 1591625864-31494-6-git-send-email-bmeng.cn@gmail.com
12
allocated.
12
Message-Id: <1591625864-31494-6-git-send-email-bmeng.cn@gmail.com>
13
14
In order to fix this let's use the existing get_address()
15
helper. This also has the benefit of performing pointer mask
16
calculations on the address specified in rs1.
17
18
The pointer masking specificiation specifically states:
19
20
"""
21
Cache Management Operations: All instructions in Zicbom, Zicbop and Zicboz
22
"""
23
24
So this is the correct behaviour and we previously have been incorrectly
25
not masking the address.
26
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
Reported-by: Fabian Thomas <fabian.thomas@cispa.de>
29
Fixes: e05da09b7cfd ("target/riscv: implement Zicbom extension")
30
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
31
Cc: qemu-stable <qemu-stable@nongnu.org>
32
Message-ID: <20240514023910.301766-1-alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
34
---
14
---
35
target/riscv/insn_trans/trans_rvzicbo.c.inc | 16 ++++++++++++----
15
include/hw/riscv/sifive_gpio.h | 7 ++++---
36
1 file changed, 12 insertions(+), 4 deletions(-)
16
hw/riscv/sifive_gpio.c | 13 +++++--------
17
2 files changed, 9 insertions(+), 11 deletions(-)
37
18
38
diff --git a/target/riscv/insn_trans/trans_rvzicbo.c.inc b/target/riscv/insn_trans/trans_rvzicbo.c.inc
19
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
39
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/insn_trans/trans_rvzicbo.c.inc
21
--- a/include/hw/riscv/sifive_gpio.h
41
+++ b/target/riscv/insn_trans/trans_rvzicbo.c.inc
22
+++ b/include/hw/riscv/sifive_gpio.h
42
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
43
static bool trans_cbo_clean(DisasContext *ctx, arg_cbo_clean *a)
24
/*
25
- * sifive System-on-Chip general purpose input/output register definition
26
+ * SiFive System-on-Chip general purpose input/output register definition
27
*
28
* Copyright 2019 AdaCore
29
*
30
@@ -XXX,XX +XXX,XX @@
31
* This code is licensed under the GPL version 2 or later. See
32
* the COPYING file in the top-level directory.
33
*/
34
+
35
#ifndef SIFIVE_GPIO_H
36
#define SIFIVE_GPIO_H
37
38
#include "hw/sysbus.h"
39
+
40
#define TYPE_SIFIVE_GPIO "sifive_soc.gpio"
41
#define SIFIVE_GPIO(obj) OBJECT_CHECK(SIFIVEGPIOState, (obj), TYPE_SIFIVE_GPIO)
42
43
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
44
uint32_t out_xor;
45
uint32_t in;
46
uint32_t in_mask;
47
-
48
} SIFIVEGPIOState;
49
50
-#endif
51
+#endif /* SIFIVE_GPIO_H */
52
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
53
index XXXXXXX..XXXXXXX 100644
54
--- a/hw/riscv/sifive_gpio.c
55
+++ b/hw/riscv/sifive_gpio.c
56
@@ -XXX,XX +XXX,XX @@
57
/*
58
- * sifive System-on-Chip general purpose input/output register definition
59
+ * SiFive System-on-Chip general purpose input/output register definition
60
*
61
* Copyright 2019 AdaCore
62
*
63
@@ -XXX,XX +XXX,XX @@
64
65
static void update_output_irq(SIFIVEGPIOState *s)
44
{
66
{
45
REQUIRE_ZICBOM(ctx);
67
-
46
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
68
uint32_t pending;
47
+ TCGv src = get_address(ctx, a->rs1, 0);
69
uint32_t pin;
48
+
70
49
+ gen_helper_cbo_clean_flush(tcg_env, src);
71
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_gpio_read(void *opaque, hwaddr offset, unsigned int size)
50
return true;
51
}
72
}
52
73
53
static bool trans_cbo_flush(DisasContext *ctx, arg_cbo_flush *a)
74
static void sifive_gpio_write(void *opaque, hwaddr offset,
75
- uint64_t value, unsigned int size)
76
+ uint64_t value, unsigned int size)
54
{
77
{
55
REQUIRE_ZICBOM(ctx);
78
SIFIVEGPIOState *s = SIFIVE_GPIO(opaque);
56
- gen_helper_cbo_clean_flush(tcg_env, cpu_gpr[a->rs1]);
79
57
+ TCGv src = get_address(ctx, a->rs1, 0);
80
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_reset(DeviceState *dev)
58
+
81
s->out_xor = 0;
59
+ gen_helper_cbo_clean_flush(tcg_env, src);
82
s->in = 0;
60
return true;
83
s->in_mask = 0;
84
-
61
}
85
}
62
86
63
static bool trans_cbo_inval(DisasContext *ctx, arg_cbo_inval *a)
87
static const VMStateDescription vmstate_sifive_gpio = {
64
{
88
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
65
REQUIRE_ZICBOM(ctx);
89
VMSTATE_UINT32(iof_en, SIFIVEGPIOState),
66
- gen_helper_cbo_inval(tcg_env, cpu_gpr[a->rs1]);
90
VMSTATE_UINT32(iof_sel, SIFIVEGPIOState),
67
+ TCGv src = get_address(ctx, a->rs1, 0);
91
VMSTATE_UINT32(out_xor, SIFIVEGPIOState),
68
+
92
- VMSTATE_UINT32(in, SIFIVEGPIOState),
69
+ gen_helper_cbo_inval(tcg_env, src);
93
- VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
70
return true;
94
+ VMSTATE_UINT32(in, SIFIVEGPIOState),
95
+ VMSTATE_UINT32(in_mask, SIFIVEGPIOState),
96
VMSTATE_END_OF_LIST()
97
}
98
};
99
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_init(Object *obj)
100
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
101
sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
102
103
-
104
for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
105
sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void sifive_gpio_class_init(ObjectClass *klass, void *data)
108
109
dc->vmsd = &vmstate_sifive_gpio;
110
dc->reset = sifive_gpio_reset;
111
- dc->desc = "sifive GPIO";
112
+ dc->desc = "SiFive GPIO";
71
}
113
}
72
114
73
static bool trans_cbo_zero(DisasContext *ctx, arg_cbo_zero *a)
115
static const TypeInfo sifive_gpio_info = {
74
{
75
REQUIRE_ZICBOZ(ctx);
76
- gen_helper_cbo_zero(tcg_env, cpu_gpr[a->rs1]);
77
+ TCGv src = get_address(ctx, a->rs1, 0);
78
+
79
+ gen_helper_cbo_zero(tcg_env, src);
80
return true;
81
}
82
--
116
--
83
2.45.1
117
2.27.0
118
119
diff view generated by jsdifflib
1
From: Andrew Jones <ajones@ventanamicro.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The Zkr extension may only be exposed to KVM guests if the VMM
3
Add a new property to represent the number of GPIO pins supported
4
implements the SEED CSR. Use the same implementation as TCG.
4
by the GPIO controller.
5
5
6
Without this patch, running with a KVM which does not forward the
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
SEED CSR access to QEMU will result in an ILL exception being
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
injected into the guest (this results in Linux guests crashing on
8
Message-id: 1591625864-31494-7-git-send-email-bmeng.cn@gmail.com
9
boot). And, when running with a KVM which does forward the access,
9
Message-Id: <1591625864-31494-7-git-send-email-bmeng.cn@gmail.com>
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>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
11
---
19
target/riscv/cpu.h | 3 +++
12
include/hw/riscv/sifive_gpio.h | 3 +++
20
target/riscv/csr.c | 18 ++++++++++++++----
13
hw/riscv/sifive_gpio.c | 30 +++++++++++++++++++-----------
21
target/riscv/kvm/kvm-cpu.c | 25 +++++++++++++++++++++++++
14
2 files changed, 22 insertions(+), 11 deletions(-)
22
3 files changed, 42 insertions(+), 4 deletions(-)
23
15
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
diff --git a/include/hw/riscv/sifive_gpio.h b/include/hw/riscv/sifive_gpio.h
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
18
--- a/include/hw/riscv/sifive_gpio.h
27
+++ b/target/riscv/cpu.h
19
+++ b/include/hw/riscv/sifive_gpio.h
28
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
20
@@ -XXX,XX +XXX,XX @@ typedef struct SIFIVEGPIOState {
29
21
uint32_t out_xor;
30
void riscv_cpu_register_gdb_regs_for_features(CPUState *cs);
22
uint32_t in;
31
23
uint32_t in_mask;
32
+target_ulong riscv_new_csr_seed(target_ulong new_value,
33
+ target_ulong write_mask);
34
+
24
+
35
uint8_t satp_mode_max_from_map(uint32_t map);
25
+ /* config */
36
const char *satp_mode_str(uint8_t satp_mode, bool is_32_bit);
26
+ uint32_t ngpio;
37
27
} SIFIVEGPIOState;
38
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
28
29
#endif /* SIFIVE_GPIO_H */
30
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
39
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/csr.c
32
--- a/hw/riscv/sifive_gpio.c
41
+++ b/target/riscv/csr.c
33
+++ b/hw/riscv/sifive_gpio.c
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
34
@@ -XXX,XX +XXX,XX @@
43
#endif
35
#include "qemu/osdep.h"
44
36
#include "qemu/log.h"
45
/* Crypto Extension */
37
#include "hw/irq.h"
46
-static RISCVException rmw_seed(CPURISCVState *env, int csrno,
38
+#include "hw/qdev-properties.h"
47
- target_ulong *ret_value,
39
#include "hw/riscv/sifive_gpio.h"
48
- target_ulong new_value,
40
#include "migration/vmstate.h"
49
- target_ulong write_mask)
41
#include "trace.h"
50
+target_ulong riscv_new_csr_seed(target_ulong new_value,
42
@@ -XXX,XX +XXX,XX @@ static void update_output_irq(SIFIVEGPIOState *s)
51
+ target_ulong write_mask)
43
pending |= s->rise_ip & s->rise_ie;
44
pending |= s->fall_ip & s->fall_ie;
45
46
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
47
+ for (int i = 0; i < s->ngpio; i++) {
48
pin = 1 << i;
49
qemu_set_irq(s->irq[i], (pending & pin) != 0);
50
trace_sifive_gpio_update_output_irq(i, (pending & pin) != 0);
51
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
52
bool prev_ival, in, in_mask, port, out_xor, pull, output_en, input_en,
53
rise_ip, fall_ip, low_ip, high_ip, oval, actual_value, ival;
54
55
- for (i = 0; i < SIFIVE_GPIO_PINS; i++) {
56
+ for (i = 0; i < s->ngpio; i++) {
57
58
prev_ival = extract32(s->value, i, 1);
59
in = extract32(s->in, i, 1);
60
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_gpio = {
61
}
62
};
63
64
-static void sifive_gpio_init(Object *obj)
65
+static Property sifive_gpio_properties[] = {
66
+ DEFINE_PROP_UINT32("ngpio", SIFIVEGPIOState, ngpio, SIFIVE_GPIO_PINS),
67
+ DEFINE_PROP_END_OF_LIST(),
68
+};
69
+
70
+static void sifive_gpio_realize(DeviceState *dev, Error **errp)
52
{
71
{
53
uint16_t random_v;
72
- SIFIVEGPIOState *s = SIFIVE_GPIO(obj);
54
Error *random_e = NULL;
73
+ SIFIVEGPIOState *s = SIFIVE_GPIO(dev);
55
@@ -XXX,XX +XXX,XX @@ static RISCVException rmw_seed(CPURISCVState *env, int csrno,
74
56
rval = random_v | SEED_OPST_ES16;
75
- memory_region_init_io(&s->mmio, obj, &gpio_ops, s,
76
+ memory_region_init_io(&s->mmio, OBJECT(dev), &gpio_ops, s,
77
TYPE_SIFIVE_GPIO, SIFIVE_GPIO_SIZE);
78
- sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
79
80
- for (int i = 0; i < SIFIVE_GPIO_PINS; i++) {
81
- sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->irq[i]);
82
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
83
+
84
+ for (int i = 0; i < s->ngpio; i++) {
85
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq[i]);
57
}
86
}
58
87
59
+ return rval;
88
- qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, SIFIVE_GPIO_PINS);
60
+}
89
- qdev_init_gpio_out(DEVICE(s), s->output, SIFIVE_GPIO_PINS);
61
+
90
+ qdev_init_gpio_in(DEVICE(s), sifive_gpio_set, s->ngpio);
62
+static RISCVException rmw_seed(CPURISCVState *env, int csrno,
91
+ qdev_init_gpio_out(DEVICE(s), s->output, s->ngpio);
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
}
92
}
81
93
82
+static int kvm_riscv_handle_csr(CPUState *cs, struct kvm_run *run)
94
static void sifive_gpio_class_init(ObjectClass *klass, void *data)
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
{
95
{
106
int ret = 0;
96
DeviceClass *dc = DEVICE_CLASS(klass);
107
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
97
108
case KVM_EXIT_RISCV_SBI:
98
+ device_class_set_props(dc, sifive_gpio_properties);
109
ret = kvm_riscv_handle_sbi(cs, run);
99
dc->vmsd = &vmstate_sifive_gpio;
110
break;
100
+ dc->realize = sifive_gpio_realize;
111
+ case KVM_EXIT_RISCV_CSR:
101
dc->reset = sifive_gpio_reset;
112
+ ret = kvm_riscv_handle_csr(cs, run);
102
dc->desc = "SiFive GPIO";
113
+ break;
103
}
114
default:
104
@@ -XXX,XX +XXX,XX @@ static const TypeInfo sifive_gpio_info = {
115
qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
105
.name = TYPE_SIFIVE_GPIO,
116
__func__, run->exit_reason);
106
.parent = TYPE_SYS_BUS_DEVICE,
107
.instance_size = sizeof(SIFIVEGPIOState),
108
- .instance_init = sifive_gpio_init,
109
.class_init = sifive_gpio_class_init
110
};
111
117
--
112
--
118
2.45.1
113
2.27.0
114
115
diff view generated by jsdifflib
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
In AIA spec, each hart (or each hart within a group) has a unique hart
3
SiFive FU540 SoC integrates a GPIO controller with 16 GPIO lines.
4
number to locate the memory pages of interrupt files in the address
4
This hooks the exsiting SiFive GPIO model to the SoC, and adds its
5
space. The number of bits required to represent any hart number is equal
5
device tree data as well.
6
to ceil(log2(hmax + 1)), where hmax is the largest hart number among
7
groups.
8
6
9
However, if the largest hart number among groups is a power of 2, QEMU
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
will pass an inaccurate hart-index-bit setting to Linux. For example, when
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
the guest OS has 4 harts, only ceil(log2(3 + 1)) = 2 bits are sufficient
9
Message-id: 1591625864-31494-8-git-send-email-bmeng.cn@gmail.com
12
to represent 4 harts, but we passes 3 to Linux. The code needs to be
10
Message-Id: <1591625864-31494-8-git-send-email-bmeng.cn@gmail.com>
13
updated to ensure accurate hart-index-bit settings.
14
15
Additionally, a Linux patch[1] is necessary to correctly recover the hart
16
index when the guest OS has only 1 hart, where the hart-index-bit is 0.
17
18
[1] https://lore.kernel.org/lkml/20240415064905.25184-1-yongxuan.wang@sifive.com/t/
19
20
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
21
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
22
Cc: qemu-stable <qemu-stable@nongnu.org>
23
Message-ID: <20240515091129.28116-1-yongxuan.wang@sifive.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
12
---
26
target/riscv/kvm/kvm-cpu.c | 9 ++++++++-
13
include/hw/riscv/sifive_u.h | 19 ++++++++++++++++
27
1 file changed, 8 insertions(+), 1 deletion(-)
14
hw/riscv/sifive_u.c | 43 +++++++++++++++++++++++++++++++++++--
15
2 files changed, 60 insertions(+), 2 deletions(-)
28
16
29
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
17
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
30
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/kvm/kvm-cpu.c
19
--- a/include/hw/riscv/sifive_u.h
32
+++ b/target/riscv/kvm/kvm-cpu.c
20
+++ b/include/hw/riscv/sifive_u.h
33
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
21
@@ -XXX,XX +XXX,XX @@
34
}
22
#include "hw/net/cadence_gem.h"
35
}
23
#include "hw/riscv/riscv_hart.h"
36
24
#include "hw/riscv/sifive_cpu.h"
37
- hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
25
+#include "hw/riscv/sifive_gpio.h"
26
#include "hw/riscv/sifive_u_prci.h"
27
#include "hw/riscv/sifive_u_otp.h"
28
29
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUSoCState {
30
RISCVHartArrayState u_cpus;
31
DeviceState *plic;
32
SiFiveUPRCIState prci;
33
+ SIFIVEGPIOState gpio;
34
SiFiveUOTPState otp;
35
CadenceGEMState gem;
36
37
@@ -XXX,XX +XXX,XX @@ enum {
38
SIFIVE_U_PRCI,
39
SIFIVE_U_UART0,
40
SIFIVE_U_UART1,
41
+ SIFIVE_U_GPIO,
42
SIFIVE_U_OTP,
43
SIFIVE_U_FLASH0,
44
SIFIVE_U_DRAM,
45
@@ -XXX,XX +XXX,XX @@ enum {
46
enum {
47
SIFIVE_U_UART0_IRQ = 4,
48
SIFIVE_U_UART1_IRQ = 5,
49
+ SIFIVE_U_GPIO_IRQ0 = 7,
50
+ SIFIVE_U_GPIO_IRQ1 = 8,
51
+ SIFIVE_U_GPIO_IRQ2 = 9,
52
+ SIFIVE_U_GPIO_IRQ3 = 10,
53
+ SIFIVE_U_GPIO_IRQ4 = 11,
54
+ SIFIVE_U_GPIO_IRQ5 = 12,
55
+ SIFIVE_U_GPIO_IRQ6 = 13,
56
+ SIFIVE_U_GPIO_IRQ7 = 14,
57
+ SIFIVE_U_GPIO_IRQ8 = 15,
58
+ SIFIVE_U_GPIO_IRQ9 = 16,
59
+ SIFIVE_U_GPIO_IRQ10 = 17,
60
+ SIFIVE_U_GPIO_IRQ11 = 18,
61
+ SIFIVE_U_GPIO_IRQ12 = 19,
62
+ SIFIVE_U_GPIO_IRQ13 = 20,
63
+ SIFIVE_U_GPIO_IRQ14 = 21,
64
+ SIFIVE_U_GPIO_IRQ15 = 22,
65
SIFIVE_U_GEM_IRQ = 0x35
66
};
67
68
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/riscv/sifive_u.c
71
+++ b/hw/riscv/sifive_u.c
72
@@ -XXX,XX +XXX,XX @@
73
* 1) CLINT (Core Level Interruptor)
74
* 2) PLIC (Platform Level Interrupt Controller)
75
* 3) PRCI (Power, Reset, Clock, Interrupt)
76
- * 4) OTP (One-Time Programmable) memory with stored serial number
77
- * 5) GEM (Gigabit Ethernet Controller) and management block
78
+ * 4) GPIO (General Purpose Input/Output Controller)
79
+ * 5) OTP (One-Time Programmable) memory with stored serial number
80
+ * 6) GEM (Gigabit Ethernet Controller) and management block
81
*
82
* This board currently generates devicetree dynamically that indicates at least
83
* two harts and up to five harts.
84
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
85
[SIFIVE_U_PRCI] = { 0x10000000, 0x1000 },
86
[SIFIVE_U_UART0] = { 0x10010000, 0x1000 },
87
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
88
+ [SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
89
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
90
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
91
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
92
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
93
g_free(cells);
94
g_free(nodename);
95
96
+ nodename = g_strdup_printf("/soc/gpio@%lx",
97
+ (long)memmap[SIFIVE_U_GPIO].base);
98
+ qemu_fdt_add_subnode(fdt, nodename);
99
+ qemu_fdt_setprop_cells(fdt, nodename, "clocks",
100
+ prci_phandle, PRCI_CLK_TLCLK);
101
+ qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
102
+ qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
103
+ qemu_fdt_setprop_cell(fdt, nodename, "#gpio-cells", 2);
104
+ qemu_fdt_setprop(fdt, nodename, "gpio-controller", NULL, 0);
105
+ qemu_fdt_setprop_cells(fdt, nodename, "reg",
106
+ 0x0, memmap[SIFIVE_U_GPIO].base,
107
+ 0x0, memmap[SIFIVE_U_GPIO].size);
108
+ qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GPIO_IRQ0,
109
+ SIFIVE_U_GPIO_IRQ1, SIFIVE_U_GPIO_IRQ2, SIFIVE_U_GPIO_IRQ3,
110
+ SIFIVE_U_GPIO_IRQ4, SIFIVE_U_GPIO_IRQ5, SIFIVE_U_GPIO_IRQ6,
111
+ SIFIVE_U_GPIO_IRQ7, SIFIVE_U_GPIO_IRQ8, SIFIVE_U_GPIO_IRQ9,
112
+ SIFIVE_U_GPIO_IRQ10, SIFIVE_U_GPIO_IRQ11, SIFIVE_U_GPIO_IRQ12,
113
+ SIFIVE_U_GPIO_IRQ13, SIFIVE_U_GPIO_IRQ14, SIFIVE_U_GPIO_IRQ15);
114
+ qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
115
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
116
+ g_free(nodename);
38
+
117
+
39
+ if (max_hart_per_socket > 1) {
118
phy_phandle = phandle++;
40
+ max_hart_per_socket--;
119
nodename = g_strdup_printf("/soc/ethernet@%lx",
41
+ hart_bits = find_last_bit(&max_hart_per_socket, BITS_PER_LONG) + 1;
120
(long)memmap[SIFIVE_U_GEM].base);
42
+ } else {
121
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_instance_init(Object *obj)
43
+ hart_bits = 0;
122
object_initialize_child(obj, "prci", &s->prci, TYPE_SIFIVE_U_PRCI);
123
object_initialize_child(obj, "otp", &s->otp, TYPE_SIFIVE_U_OTP);
124
object_initialize_child(obj, "gem", &s->gem, TYPE_CADENCE_GEM);
125
+ object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
126
}
127
128
static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
129
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
130
sysbus_realize(SYS_BUS_DEVICE(&s->prci), &err);
131
sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base);
132
133
+ qdev_prop_set_uint32(DEVICE(&s->gpio), "ngpio", 16);
134
+ sysbus_realize(SYS_BUS_DEVICE(&s->gpio), &err);
135
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio), 0, memmap[SIFIVE_U_GPIO].base);
136
+
137
+ /* Pass all GPIOs to the SOC layer so they are available to the board */
138
+ qdev_pass_gpios(DEVICE(&s->gpio), dev, NULL);
139
+
140
+ /* Connect GPIO interrupts to the PLIC */
141
+ for (i = 0; i < 16; i++) {
142
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio), i,
143
+ qdev_get_gpio_in(DEVICE(s->plic),
144
+ SIFIVE_U_GPIO_IRQ0 + i));
44
+ }
145
+ }
45
+
146
+
46
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
147
qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
47
KVM_DEV_RISCV_AIA_CONFIG_HART_BITS,
148
sysbus_realize(SYS_BUS_DEVICE(&s->otp), &err);
48
&hart_bits, true, NULL);
149
sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base);
49
--
150
--
50
2.45.1
151
2.27.0
152
153
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
The require_scale_rvf function only checks the double width operator for
3
At present the GPIO output IRQs are triggered each time any GPIO
4
the vector floating point widen instructions, so most of the widen
4
register is written. However this is not correct. We should only
5
checking functions need to add require_rvf for single width operator.
5
trigger the output IRQ when the pin is configured as output enable.
6
6
7
The vfwcvt.f.x.v and vfwcvt.f.xu.v instructions convert single width
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
integer to double width float, so the opfxv_widen_check function doesn’t
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
need require_rvf for the single width operator(integer).
9
Message-id: 1591625864-31494-9-git-send-email-bmeng.cn@gmail.com
10
10
Message-Id: <1591625864-31494-9-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Max Chou <max.chou@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-3-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
12
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 5 +++++
13
hw/riscv/sifive_gpio.c | 4 +++-
18
1 file changed, 5 insertions(+)
14
1 file changed, 3 insertions(+), 1 deletion(-)
19
15
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
diff --git a/hw/riscv/sifive_gpio.c b/hw/riscv/sifive_gpio.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
--- a/hw/riscv/sifive_gpio.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/hw/riscv/sifive_gpio.c
24
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_TRANS(vfrsub_vf, opfvf_check)
20
@@ -XXX,XX +XXX,XX @@ static void update_state(SIFIVEGPIOState *s)
25
static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
21
actual_value = pull;
26
{
22
}
27
return require_rvv(s) &&
23
28
+ require_rvf(s) &&
24
- qemu_set_irq(s->output[i], actual_value);
29
require_scale_rvf(s) &&
25
+ if (output_en) {
30
(s->sew != MO_8) &&
26
+ qemu_set_irq(s->output[i], actual_value);
31
vext_check_isa_ill(s) &&
27
+ }
32
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_WIDEN_TRANS(vfwsub_vv, opfvv_widen_check)
28
33
static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
29
/* Input value */
34
{
30
ival = input_en && actual_value;
35
return require_rvv(s) &&
36
+ require_rvf(s) &&
37
require_scale_rvf(s) &&
38
(s->sew != MO_8) &&
39
vext_check_isa_ill(s) &&
40
@@ -XXX,XX +XXX,XX @@ GEN_OPFVF_WIDEN_TRANS(vfwsub_vf)
41
static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
42
{
43
return require_rvv(s) &&
44
+ require_rvf(s) &&
45
require_scale_rvf(s) &&
46
(s->sew != MO_8) &&
47
vext_check_isa_ill(s) &&
48
@@ -XXX,XX +XXX,XX @@ GEN_OPFWV_WIDEN_TRANS(vfwsub_wv)
49
static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
50
{
51
return require_rvv(s) &&
52
+ require_rvf(s) &&
53
require_scale_rvf(s) &&
54
(s->sew != MO_8) &&
55
vext_check_isa_ill(s) &&
56
@@ -XXX,XX +XXX,XX @@ GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
57
static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
58
{
59
return reduction_widen_check(s, a) &&
60
+ require_rvf(s) &&
61
require_scale_rvf(s) &&
62
(s->sew != MO_8);
63
}
64
--
31
--
65
2.45.1
32
2.27.0
66
33
67
34
diff view generated by jsdifflib
1
From: Max Chou <max.chou@sifive.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
According v spec 18.4, only the vfwcvt.f.f.v and vfncvt.f.f.w
3
The HiFive Unleashed board wires GPIO pin#10 to the input of the
4
instructions will be affected by Zvfhmin extension.
4
system reset signal. Let's set up the GPIO pin#10 and insert a
5
And the vfwcvt.f.f.v and vfncvt.f.f.w instructions only support the
5
"gpio-restart" device tree node so that reboot is now functional
6
conversions of
6
with QEMU 'sifive_u' machine.
7
7
8
* From 1*SEW(16/32) to 2*SEW(32/64)
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
9
* From 2*SEW(32/64) to 1*SEW(16/32)
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
10
Message-id: 1591625864-31494-10-git-send-email-bmeng.cn@gmail.com
11
Signed-off-by: Max Chou <max.chou@sifive.com>
11
Message-Id: <1591625864-31494-10-git-send-email-bmeng.cn@gmail.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Cc: qemu-stable <qemu-stable@nongnu.org>
14
Message-ID: <20240322092600.1198921-2-max.chou@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
13
---
17
target/riscv/insn_trans/trans_rvv.c.inc | 20 ++++++++++++++++++--
14
hw/riscv/sifive_u.c | 24 +++++++++++++++++++++++-
18
1 file changed, 18 insertions(+), 2 deletions(-)
15
1 file changed, 23 insertions(+), 1 deletion(-)
19
16
20
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
21
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
--- a/hw/riscv/sifive_u.c
23
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
+++ b/hw/riscv/sifive_u.c
24
@@ -XXX,XX +XXX,XX @@ static bool require_rvf(DisasContext *s)
21
@@ -XXX,XX +XXX,XX @@
25
}
22
#include "qapi/error.h"
23
#include "qapi/visitor.h"
24
#include "hw/boards.h"
25
+#include "hw/irq.h"
26
#include "hw/loader.h"
27
#include "hw/sysbus.h"
28
#include "hw/char/serial.h"
29
@@ -XXX,XX +XXX,XX @@
30
#include "net/eth.h"
31
#include "sysemu/arch_init.h"
32
#include "sysemu/device_tree.h"
33
+#include "sysemu/runstate.h"
34
#include "sysemu/sysemu.h"
35
#include "exec/address-spaces.h"
36
37
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
38
uint32_t *cells;
39
char *nodename;
40
char ethclk_names[] = "pclk\0hclk";
41
- uint32_t plic_phandle, prci_phandle, phandle = 1;
42
+ uint32_t plic_phandle, prci_phandle, gpio_phandle, phandle = 1;
43
uint32_t hfclk_phandle, rtcclk_phandle, phy_phandle;
44
45
fdt = s->fdt = create_device_tree(&s->fdt_size);
46
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
47
g_free(cells);
48
g_free(nodename);
49
50
+ gpio_phandle = phandle++;
51
nodename = g_strdup_printf("/soc/gpio@%lx",
52
(long)memmap[SIFIVE_U_GPIO].base);
53
qemu_fdt_add_subnode(fdt, nodename);
54
+ qemu_fdt_setprop_cell(fdt, nodename, "phandle", gpio_phandle);
55
qemu_fdt_setprop_cells(fdt, nodename, "clocks",
56
prci_phandle, PRCI_CLK_TLCLK);
57
qemu_fdt_setprop_cell(fdt, nodename, "#interrupt-cells", 2);
58
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
59
qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,gpio0");
60
g_free(nodename);
61
62
+ nodename = g_strdup_printf("/gpio-restart");
63
+ qemu_fdt_add_subnode(fdt, nodename);
64
+ qemu_fdt_setprop_cells(fdt, nodename, "gpios", gpio_phandle, 10, 1);
65
+ qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart");
66
+ g_free(nodename);
67
+
68
phy_phandle = phandle++;
69
nodename = g_strdup_printf("/soc/ethernet@%lx",
70
(long)memmap[SIFIVE_U_GEM].base);
71
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
72
g_free(nodename);
26
}
73
}
27
74
28
+static bool require_rvfmin(DisasContext *s)
75
+static void sifive_u_machine_reset(void *opaque, int n, int level)
29
+{
76
+{
30
+ if (s->mstatus_fs == EXT_STATUS_DISABLED) {
77
+ /* gpio pin active low triggers reset */
31
+ return false;
78
+ if (!level) {
32
+ }
79
+ qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
33
+
34
+ switch (s->sew) {
35
+ case MO_16:
36
+ return s->cfg_ptr->ext_zvfhmin;
37
+ case MO_32:
38
+ return s->cfg_ptr->ext_zve32f;
39
+ default:
40
+ return false;
41
+ }
80
+ }
42
+}
81
+}
43
+
82
+
44
static bool require_scale_rvf(DisasContext *s)
83
static void sifive_u_machine_init(MachineState *machine)
45
{
84
{
46
if (s->mstatus_fs == EXT_STATUS_DISABLED) {
85
const struct MemmapEntry *memmap = sifive_u_memmap;
47
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvfmin(DisasContext *s)
86
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
48
}
87
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_FLASH0].base,
49
88
flash0);
50
switch (s->sew) {
89
51
- case MO_8:
90
+ /* register gpio-restart */
52
- return s->cfg_ptr->ext_zvfhmin;
91
+ qdev_connect_gpio_out(DEVICE(&(s->soc.gpio)), 10,
53
case MO_16:
92
+ qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
54
return s->cfg_ptr->ext_zve32f;
93
+
55
case MO_32:
94
/* create device tree */
56
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
95
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
57
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
96
58
{
59
return opfv_widen_check(s, a) &&
60
+ require_rvfmin(s) &&
61
require_scale_rvfmin(s) &&
62
(s->sew != MO_8);
63
}
64
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
65
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
66
{
67
return opfv_narrow_check(s, a) &&
68
+ require_rvfmin(s) &&
69
require_scale_rvfmin(s) &&
70
(s->sew != MO_8);
71
}
72
--
97
--
73
2.45.1
98
2.27.0
99
100
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Privileged spec section 4.1.9 mentions:
3
In prepration to add more properties to this machine, rename the
4
existing serial property get/set functions to a generic name.
4
5
5
"When a trap is taken into S-mode, stval is written with
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Message-id: 1591625864-31494-11-git-send-email-bmeng.cn@gmail.com
25
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-Id: <1591625864-31494-11-git-send-email-bmeng.cn@gmail.com>
26
Message-ID: <20240416230437.1869024-3-dbarboza@ventanamicro.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
11
---
29
target/riscv/insn_trans/trans_privileged.c.inc | 2 ++
12
hw/riscv/sifive_u.c | 14 ++++++++------
30
1 file changed, 2 insertions(+)
13
1 file changed, 8 insertions(+), 6 deletions(-)
31
14
32
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
15
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
33
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/insn_trans/trans_privileged.c.inc
17
--- a/hw/riscv/sifive_u.c
35
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
18
+++ b/hw/riscv/sifive_u.c
36
@@ -XXX,XX +XXX,XX @@ static bool trans_ebreak(DisasContext *ctx, arg_ebreak *a)
19
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error *
37
if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) {
20
s->start_in_flash = value;
38
generate_exception(ctx, RISCV_EXCP_SEMIHOST);
21
}
39
} else {
22
40
+ tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env,
23
-static void sifive_u_machine_get_serial(Object *obj, Visitor *v, const char *name,
41
+ offsetof(CPURISCVState, badaddr));
24
- void *opaque, Error **errp)
42
generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
25
+static void sifive_u_machine_get_uint32_prop(Object *obj, Visitor *v,
43
}
26
+ const char *name, void *opaque,
44
return true;
27
+ Error **errp)
28
{
29
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
30
}
31
32
-static void sifive_u_machine_set_serial(Object *obj, Visitor *v, const char *name,
33
- void *opaque, Error **errp)
34
+static void sifive_u_machine_set_uint32_prop(Object *obj, Visitor *v,
35
+ const char *name, void *opaque,
36
+ Error **errp)
37
{
38
visit_type_uint32(v, name, (uint32_t *)opaque, errp);
39
}
40
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
41
42
s->serial = OTP_SERIAL;
43
object_property_add(obj, "serial", "uint32",
44
- sifive_u_machine_get_serial,
45
- sifive_u_machine_set_serial, NULL, &s->serial);
46
+ sifive_u_machine_get_uint32_prop,
47
+ sifive_u_machine_set_uint32_prop, NULL, &s->serial);
48
object_property_set_description(obj, "serial", "Board serial number");
49
}
50
45
--
51
--
46
2.45.1
52
2.27.0
53
54
diff view generated by jsdifflib
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Running a KVM guest using a 6.9-rc3 kernel, in a 6.8 host that has zkr
3
On SiFive FU540 SoC, the value stored at physical address 0x1000
4
enabled, will fail with a kernel oops SIGILL right at the start. The
4
stores the MSEL pin state that is used to control the next boot
5
reason is that we can't expose zkr without implementing the SEED CSR.
5
location that ROM codes jump to.
6
Disabling zkr in the guest would be a workaround, but if the KVM doesn't
7
allow it we'll error out and never boot.
8
6
9
In hindsight this is too strict. If we keep proceeding, despite not
7
Add a new property msel to sifive_u machine for this.
10
disabling the extension in the KVM vcpu, we'll not add the extension in
11
the riscv,isa. The guest kernel will be unaware of the extension, i.e.
12
it doesn't matter if the KVM vcpu has it enabled underneath or not. So
13
it's ok to keep booting in this case.
14
8
15
Change our current logic to not error out if we fail to disable an
9
Signed-off-by: Bin Meng <bin.meng@windriver.com>
16
extension in kvm_set_one_reg(), but show a warning and keep booting. It
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
is important to throw a warning because we must make the user aware that
11
Message-id: 1591625864-31494-12-git-send-email-bmeng.cn@gmail.com
18
the extension is still available in the vcpu, meaning that an
12
Message-Id: <1591625864-31494-12-git-send-email-bmeng.cn@gmail.com>
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>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
14
---
36
target/riscv/kvm/kvm-cpu.c | 12 ++++++++----
15
include/hw/riscv/sifive_u.h | 1 +
37
1 file changed, 8 insertions(+), 4 deletions(-)
16
hw/riscv/sifive_u.c | 7 +++++++
17
2 files changed, 8 insertions(+)
38
18
39
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
19
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
40
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm/kvm-cpu.c
21
--- a/include/hw/riscv/sifive_u.h
42
+++ b/target/riscv/kvm/kvm-cpu.c
22
+++ b/include/hw/riscv/sifive_u.h
43
@@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
23
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveUState {
44
reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
24
int fdt_size;
45
ret = kvm_set_one_reg(cs, id, &reg);
25
46
if (ret != 0) {
26
bool start_in_flash;
47
- error_report("Unable to %s extension %s in KVM, error %d",
27
+ uint32_t msel;
48
- reg ? "enable" : "disable",
28
uint32_t serial;
49
- multi_ext_cfg->name, ret);
29
} SiFiveUState;
50
- exit(EXIT_FAILURE);
30
51
+ if (!reg && ret == -EINVAL) {
31
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
52
+ warn_report("KVM cannot disable extension %s",
32
index XXXXXXX..XXXXXXX 100644
53
+ multi_ext_cfg->name);
33
--- a/hw/riscv/sifive_u.c
54
+ } else {
34
+++ b/hw/riscv/sifive_u.c
55
+ error_report("Unable to enable extension %s in KVM, error %d",
35
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
56
+ multi_ext_cfg->name, ret);
36
"Set on to tell QEMU's ROM to jump to "
57
+ exit(EXIT_FAILURE);
37
"flash. Otherwise QEMU will jump to DRAM");
58
+ }
38
59
}
39
+ s->msel = 0;
60
}
40
+ object_property_add(obj, "msel", "uint32",
61
}
41
+ sifive_u_machine_get_uint32_prop,
42
+ sifive_u_machine_set_uint32_prop, NULL, &s->msel);
43
+ object_property_set_description(obj, "msel",
44
+ "Mode Select (MSEL[3:0]) pin state");
45
+
46
s->serial = OTP_SERIAL;
47
object_property_add(obj, "serial", "uint32",
48
sifive_u_machine_get_uint32_prop,
62
--
49
--
63
2.45.1
50
2.27.0
51
52
diff view generated by jsdifflib
1
From: Rob Bradford <rbradford@rivosinc.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
This extension has now been ratified:
3
Current IBEX CPU init routine name seems to be too generic.
4
https://jira.riscv.org/browse/RVS-2006 so the "x-" prefix can be
4
Since it uses a different reset vector from the generic one,
5
removed.
5
it merits a dedicated name.
6
6
7
Since this is now a ratified extension add it to the list of extensions
7
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
included in the "max" CPU variant.
9
10
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
11
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-id: 1592268641-7478-2-git-send-email-bmeng.cn@gmail.com
14
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Message-Id: <1592268641-7478-2-git-send-email-bmeng.cn@gmail.com>
15
Message-ID: <20240514110217.22516-1-rbradford@rivosinc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
12
---
18
target/riscv/cpu.c | 2 +-
13
target/riscv/cpu.c | 4 ++--
19
target/riscv/tcg/tcg-cpu.c | 2 +-
14
1 file changed, 2 insertions(+), 2 deletions(-)
20
2 files changed, 2 insertions(+), 2 deletions(-)
21
15
22
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu.c
18
--- a/target/riscv/cpu.c
25
+++ b/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
26
@@ -XXX,XX +XXX,XX @@ static const MISAExtInfo misa_ext_info_arr[] = {
20
@@ -XXX,XX +XXX,XX @@ static void rvxx_imacu_nommu_cpu_init(Object *obj)
27
MISA_EXT_INFO(RVJ, "x-j", "Dynamic translated languages"),
21
28
MISA_EXT_INFO(RVV, "v", "Vector operations"),
22
#if defined(TARGET_RISCV32)
29
MISA_EXT_INFO(RVG, "g", "General purpose (IMAFD_Zicsr_Zifencei)"),
23
30
- MISA_EXT_INFO(RVB, "x-b", "Bit manipulation (Zba_Zbb_Zbs)")
24
-static void rv32_imcu_nommu_cpu_init(Object *obj)
31
+ MISA_EXT_INFO(RVB, "b", "Bit manipulation (Zba_Zbb_Zbs)")
25
+static void rv32_ibex_cpu_init(Object *obj)
32
};
26
{
33
27
CPURISCVState *env = &RISCV_CPU(obj)->env;
34
static void riscv_cpu_validate_misa_mxl(RISCVCPUClass *mcc)
28
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
35
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
29
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
36
index XXXXXXX..XXXXXXX 100644
30
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
37
--- a/target/riscv/tcg/tcg-cpu.c
31
#if defined(TARGET_RISCV32)
38
+++ b/target/riscv/tcg/tcg-cpu.c
32
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
39
@@ -XXX,XX +XXX,XX @@ static void riscv_init_max_cpu_extensions(Object *obj)
33
- DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_imcu_nommu_cpu_init),
40
const RISCVCPUMultiExtConfig *prop;
34
+ DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
41
35
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
42
/* Enable RVG, RVJ and RVV that are disabled by default */
36
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
43
- riscv_cpu_set_misa_ext(env, env->misa_ext | RVG | RVJ | RVV);
37
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
44
+ riscv_cpu_set_misa_ext(env, env->misa_ext | RVB | RVG | RVJ | RVV);
45
46
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
47
isa_ext_update_enabled(cpu, prop->offset, true);
48
--
38
--
49
2.45.1
39
2.27.0
40
41
diff view generated by jsdifflib
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
In this patch, we modify the decoder to be a freely composable data
3
Per the SiFive manual, all E/U series CPU cores' reset vector is
4
structure instead of a hardcoded one. It can be dynamically builded up
4
at 0x1004. Update our codes to match the hardware.
5
according to the extensions.
6
This approach has several benefits:
7
1. Provides support for heterogeneous cpu architectures. As we add decoder in
8
RISCVCPU, each cpu can have their own decoder, and the decoders can be
9
different due to cpu's features.
10
2. Improve the decoding efficiency. We run the guard_func to see if the decoder
11
can be added to the dynamic_decoder when building up the decoder. Therefore,
12
there is no need to run the guard_func when decoding each instruction. It can
13
improve the decoding efficiency
14
3. For vendor or dynamic cpus, it allows them to customize their own decoder
15
functions to improve decoding efficiency, especially when vendor-defined
16
instruction sets increase. Because of dynamic building up, it can skip the other
17
decoder guard functions when decoding.
18
4. Pre patch for allowing adding a vendor decoder before decode_insn32() with minimal
19
overhead for users that don't need this particular vendor decoder.
20
5
21
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
22
Suggested-by: Christoph Muellner <christoph.muellner@vrull.eu>
23
Co-authored-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
26
Message-ID: <20240506023607.29544-1-eric.huang@linux.alibaba.com>
8
Message-id: 1592268641-7478-3-git-send-email-bmeng.cn@gmail.com
9
Message-Id: <1592268641-7478-3-git-send-email-bmeng.cn@gmail.com>
27
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
28
---
11
---
29
target/riscv/cpu.h | 1 +
12
hw/riscv/sifive_e.c | 10 ++++++----
30
target/riscv/tcg/tcg-cpu.h | 15 +++++++++++++++
13
hw/riscv/sifive_u.c | 6 +++---
31
target/riscv/cpu.c | 1 +
14
target/riscv/cpu.c | 16 ++++++++--------
32
target/riscv/tcg/tcg-cpu.c | 15 +++++++++++++++
15
3 files changed, 17 insertions(+), 15 deletions(-)
33
target/riscv/translate.c | 31 +++++++++++++++----------------
34
5 files changed, 47 insertions(+), 16 deletions(-)
35
16
36
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
17
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
37
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/cpu.h
19
--- a/hw/riscv/sifive_e.c
39
+++ b/target/riscv/cpu.h
20
+++ b/hw/riscv/sifive_e.c
40
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
21
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
41
uint32_t pmu_avail_ctrs;
22
memmap[SIFIVE_E_DTIM].base, main_mem);
42
/* Mapping of events to counters */
23
43
GHashTable *pmu_event_ctr_map;
24
/* Mask ROM reset vector */
44
+ const GPtrArray *decoders;
25
- uint32_t reset_vec[2];
45
};
26
+ uint32_t reset_vec[4];
46
27
47
/**
28
if (s->revb) {
48
diff --git a/target/riscv/tcg/tcg-cpu.h b/target/riscv/tcg/tcg-cpu.h
29
- reset_vec[0] = 0x200102b7; /* 0x1000: lui t0,0x20010 */
30
+ reset_vec[1] = 0x200102b7; /* 0x1004: lui t0,0x20010 */
31
} else {
32
- reset_vec[0] = 0x204002b7; /* 0x1000: lui t0,0x20400 */
33
+ reset_vec[1] = 0x204002b7; /* 0x1004: lui t0,0x20400 */
34
}
35
- reset_vec[1] = 0x00028067; /* 0x1004: jr t0 */
36
+ reset_vec[2] = 0x00028067; /* 0x1008: jr t0 */
37
+
38
+ reset_vec[0] = reset_vec[3] = 0;
39
40
/* copy in the reset vector in little_endian byte order */
41
for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
42
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
49
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
50
--- a/target/riscv/tcg/tcg-cpu.h
44
--- a/hw/riscv/sifive_u.c
51
+++ b/target/riscv/tcg/tcg-cpu.h
45
+++ b/hw/riscv/sifive_u.c
52
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp);
46
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
53
void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp);
47
54
bool riscv_cpu_tcg_compatible(RISCVCPU *cpu);
48
/* reset vector */
55
49
uint32_t reset_vec[8] = {
56
+struct DisasContext;
50
+ 0x00000000,
57
+struct RISCVCPUConfig;
51
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
58
+typedef struct RISCVDecoder {
52
- 0x02028593, /* addi a1, t0, %pcrel_lo(1b) */
59
+ bool (*guard_func)(const struct RISCVCPUConfig *);
53
+ 0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
60
+ bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
54
0xf1402573, /* csrr a0, mhartid */
61
+} RISCVDecoder;
55
#if defined(TARGET_RISCV32)
62
+
56
0x0182a283, /* lw t0, 24(t0) */
63
+typedef bool (*riscv_cpu_decode_fn)(struct DisasContext *, uint32_t);
57
#elif defined(TARGET_RISCV64)
64
+
58
- 0x0182b283, /* ld t0, 24(t0) */
65
+extern const size_t decoder_table_size;
59
+ 0x0182e283, /* lwu t0, 24(t0) */
66
+
67
+extern const RISCVDecoder decoder_table[];
68
+
69
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu);
70
+
71
#endif
60
#endif
61
0x00028067, /* jr t0 */
62
0x00000000,
63
start_addr, /* start: .dword */
64
- 0x00000000,
65
/* dtb: */
66
};
67
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
68
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
73
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu.c
70
--- a/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
71
+++ b/target/riscv/cpu.c
76
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp)
72
@@ -XXX,XX +XXX,XX @@ static void riscv_base_cpu_init(Object *obj)
77
error_propagate(errp, local_err);
73
set_resetvec(env, DEFAULT_RSTVEC);
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
}
74
}
91
75
92
+void riscv_tcg_cpu_finalize_dynamic_decoder(RISCVCPU *cpu)
76
-static void rvxx_gcsu_priv1_10_0_cpu_init(Object *obj)
93
+{
77
+static void rvxx_sifive_u_cpu_init(Object *obj)
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
{
78
{
109
return object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST) == NULL;
79
CPURISCVState *env = &RISCV_CPU(obj)->env;
110
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
80
set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
111
index XXXXXXX..XXXXXXX 100644
81
set_priv_version(env, PRIV_VERSION_1_10_0);
112
--- a/target/riscv/translate.c
82
- set_resetvec(env, DEFAULT_RSTVEC);
113
+++ b/target/riscv/translate.c
83
+ set_resetvec(env, 0x1004);
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
}
84
}
134
85
135
+const RISCVDecoder decoder_table[] = {
86
-static void rvxx_imacu_nommu_cpu_init(Object *obj)
136
+ { always_true_p, decode_insn32 },
87
+static void rvxx_sifive_e_cpu_init(Object *obj)
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
{
88
{
145
- /*
89
CPURISCVState *env = &RISCV_CPU(obj)->env;
146
- * A table with predicate (i.e., guard) functions and decoder functions
90
set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
147
- * that are tested in-order until a decoder matches onto the opcode.
91
set_priv_version(env, PRIV_VERSION_1_10_0);
148
- */
92
- set_resetvec(env, DEFAULT_RSTVEC);
149
- static const struct {
93
+ set_resetvec(env, 0x1004);
150
- bool (*guard_func)(const RISCVCPUConfig *);
94
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
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
}
95
}
180
96
181
static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
97
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
98
#if defined(TARGET_RISCV32)
99
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
100
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
101
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_imacu_nommu_cpu_init),
102
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_sifive_e_cpu_init),
103
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
104
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_gcsu_priv1_10_0_cpu_init),
105
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_sifive_u_cpu_init),
106
#elif defined(TARGET_RISCV64)
107
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
108
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_imacu_nommu_cpu_init),
109
- DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_gcsu_priv1_10_0_cpu_init),
110
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_sifive_e_cpu_init),
111
+ DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_sifive_u_cpu_init),
112
#endif
113
};
114
182
--
115
--
183
2.45.1
116
2.27.0
117
118
diff view generated by jsdifflib
1
From: "yang.zhang" <yang.zhang@hexintek.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Since only root APLICs can have hw IRQ lines, aplic->parent should
3
SiFive FU540 SoC supports booting from several sources, which are
4
be initialized first.
4
controlled using the Mode Select (MSEL[3:0]) pins on the chip.
5
Typically, the boot process runs through several stages before it
6
begins execution of user-provided programs.
5
7
6
Fixes: e8f79343cf ("hw/intc: Add RISC-V AIA APLIC device emulation")
8
The SoC supports booting from memory-mapped QSPI flash, which is
7
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
how start_in_flash property is used for at present. This matches
8
Signed-off-by: yang.zhang <yang.zhang@hexintek.com>
10
MSEL = 1 configuration (QSPI0).
9
Cc: qemu-stable <qemu-stable@nongnu.org>
11
10
Message-ID: <20240409014445.278-1-gaoshanliukou@163.com>
12
Typical booting flows involve the Zeroth Stage Boot Loader (ZSBL).
13
It's not necessary for QEMU to implement the full ZSBL ROM codes,
14
because we know ZSBL downloads the next stage program into the L2
15
LIM at address 0x8000000 and executes from there. We can bypass
16
the whole ZSBL execution and use "-bios" to load the next stage
17
program directly if MSEL indicates a ZSBL booting flow.
18
19
Signed-off-by: Bin Meng <bin.meng@windriver.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-id: 1592268641-7478-4-git-send-email-bmeng.cn@gmail.com
22
Message-Id: <1592268641-7478-4-git-send-email-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
24
---
13
hw/intc/riscv_aplic.c | 8 ++++----
25
include/hw/riscv/sifive_u.h | 6 ++++++
14
1 file changed, 4 insertions(+), 4 deletions(-)
26
hw/riscv/sifive_u.c | 39 +++++++++++++++++++++++++++++--------
27
2 files changed, 37 insertions(+), 8 deletions(-)
15
28
16
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
29
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
17
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/intc/riscv_aplic.c
31
--- a/include/hw/riscv/sifive_u.h
19
+++ b/hw/intc/riscv_aplic.c
32
+++ b/include/hw/riscv/sifive_u.h
20
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
33
@@ -XXX,XX +XXX,XX @@ enum {
21
qdev_prop_set_bit(dev, "msimode", msimode);
34
SIFIVE_U_RTCCLK_FREQ = 1000000
22
qdev_prop_set_bit(dev, "mmode", mmode);
35
};
23
36
24
+ if (parent) {
37
+enum {
25
+ riscv_aplic_add_child(parent, dev);
38
+ MSEL_MEMMAP_QSPI0_FLASH = 1,
39
+ MSEL_L2LIM_QSPI0_FLASH = 6,
40
+ MSEL_L2LIM_QSPI2_SD = 11
41
+};
42
+
43
#define SIFIVE_U_MANAGEMENT_CPU_COUNT 1
44
#define SIFIVE_U_COMPUTE_CPU_COUNT 4
45
46
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/riscv/sifive_u.c
49
+++ b/hw/riscv/sifive_u.c
50
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
51
/* create device tree */
52
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
53
54
- riscv_find_and_load_firmware(machine, BIOS_FILENAME,
55
- memmap[SIFIVE_U_DRAM].base, NULL);
56
+ if (s->start_in_flash) {
57
+ /*
58
+ * If start_in_flash property is given, assign s->msel to a value
59
+ * that representing booting from QSPI0 memory-mapped flash.
60
+ *
61
+ * This also means that when both start_in_flash and msel properties
62
+ * are given, start_in_flash takes the precedence over msel.
63
+ *
64
+ * Note this is to keep backward compatibility not to break existing
65
+ * users that use start_in_flash property.
66
+ */
67
+ s->msel = MSEL_MEMMAP_QSPI0_FLASH;
26
+ }
68
+ }
27
+
69
+
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
70
+ switch (s->msel) {
29
71
+ case MSEL_MEMMAP_QSPI0_FLASH:
30
if (!is_kvm_aia(msimode)) {
72
+ start_addr = memmap[SIFIVE_U_FLASH0].base;
31
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
73
+ break;
74
+ case MSEL_L2LIM_QSPI0_FLASH:
75
+ case MSEL_L2LIM_QSPI2_SD:
76
+ start_addr = memmap[SIFIVE_U_L2LIM].base;
77
+ break;
78
+ default:
79
+ start_addr = memmap[SIFIVE_U_DRAM].base;
80
+ break;
81
+ }
82
+
83
+ riscv_find_and_load_firmware(machine, BIOS_FILENAME, start_addr, NULL);
84
85
if (machine->kernel_filename) {
86
uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename,
87
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
88
}
32
}
89
}
33
90
34
- if (parent) {
91
- if (s->start_in_flash) {
35
- riscv_aplic_add_child(parent, dev);
92
- start_addr = memmap[SIFIVE_U_FLASH0].base;
36
- }
93
- }
37
-
94
-
38
if (!msimode) {
95
/* reset vector */
39
for (i = 0; i < num_harts; i++) {
96
uint32_t reset_vec[8] = {
40
CPUState *cpu = cpu_by_arch_id(hartid_base + i);
97
- 0x00000000,
98
+ s->msel, /* MSEL pin state */
99
0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */
100
0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */
101
0xf1402573, /* csrr a0, mhartid */
102
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_instance_init(Object *obj)
103
sifive_u_machine_set_start_in_flash);
104
object_property_set_description(obj, "start-in-flash",
105
"Set on to tell QEMU's ROM to jump to "
106
- "flash. Otherwise QEMU will jump to DRAM");
107
+ "flash. Otherwise QEMU will jump to DRAM "
108
+ "or L2LIM depending on the msel value");
109
110
s->msel = 0;
111
object_property_add(obj, "msel", "uint32",
41
--
112
--
42
2.45.1
113
2.27.0
114
115
diff view generated by jsdifflib
1
From: Cheng Yang <yangcheng.work@foxmail.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
Use qemu_fdt_setprop_u64() instead of qemu_fdt_setprop_cell()
3
Move the flash and DRAM to the end of the SoC memmap table.
4
to set the address of initrd in FDT to support 64-bit address.
5
4
6
Signed-off-by: Cheng Yang <yangcheng.work@foxmail.com>
5
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <tencent_A4482251DD0890F312758FA6B33F60815609@qq.com>
7
Message-id: 1592268641-7478-5-git-send-email-bmeng.cn@gmail.com
8
Message-Id: <1592268641-7478-5-git-send-email-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
10
---
11
hw/riscv/boot.c | 4 ++--
11
hw/riscv/sifive_u.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
13
14
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
14
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/boot.c
16
--- a/hw/riscv/sifive_u.c
17
+++ b/hw/riscv/boot.c
17
+++ b/hw/riscv/sifive_u.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
18
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
19
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
19
[SIFIVE_U_UART1] = { 0x10011000, 0x1000 },
20
if (fdt) {
20
[SIFIVE_U_GPIO] = { 0x10060000, 0x1000 },
21
end = start + size;
21
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
22
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-start", start);
22
- [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
23
- qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end", end);
23
- [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
24
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-start", start);
24
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
25
+ qemu_fdt_setprop_u64(fdt, "/chosen", "linux,initrd-end", end);
25
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
26
}
26
+ [SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
27
}
27
+ [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
28
28
};
29
30
#define OTP_SERIAL 1
29
--
31
--
30
2.45.1
32
2.27.0
33
34
diff view generated by jsdifflib
1
From: Huang Tao <eric.huang@linux.alibaba.com>
1
From: Bin Meng <bin.meng@windriver.com>
2
2
3
In RVV and vcrypto instructions, the masked and tail elements are set to 1s
3
It is enough to simply map the SiFive FU540 DDR memory controller
4
using vext_set_elems_1s function if the vma/vta bit is set. It is the element
4
into the MMIO space using create_unimplemented_device(), to make
5
agnostic policy.
5
the upstream U-Boot v2020.07 DDR memory initialization codes happy.
6
6
7
However, this function can't deal the big endian situation. This patch fixes
7
Note we do not generate device tree fragment for the DDR memory
8
the problem by adding handling of such case.
8
controller. Since the controller data in device tree consumes a
9
very large space (see fu540-hifive-unleashed-a00-ddr.dtsi in the
10
U-Boot source), and it is only needed by U-Boot SPL but not any
11
operating system, we choose not to generate the fragment here.
12
This also means when testing with U-Boot SPL, the device tree has
13
to come from U-Boot SPL itself, but not the one generated by QEMU
14
on the fly. The memory has to be set to 8GiB to match the real
15
HiFive Unleashed board when invoking QEMU (-m 8G).
9
16
10
Signed-off-by: Huang Tao <eric.huang@linux.alibaba.com>
17
With this commit, QEMU can boot U-Boot SPL built for SiFive FU540
11
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
18
all the way up to loading U-Boot proper from MMC:
12
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
19
13
Cc: qemu-stable <qemu-stable@nongnu.org>
20
$ qemu-system-riscv64 -nographic -M sifive_u,msel=6 -m 8G -bios u-boot-spl.bin
14
Message-ID: <20240325021654.6594-1-eric.huang@linux.alibaba.com>
21
22
U-Boot SPL 2020.07-rc3-00208-g88bd5b1 (Jun 08 2020 - 20:16:10 +0800)
23
Trying to boot from MMC1
24
Unhandled exception: Load access fault
25
EPC: 0000000008009be6 TVAL: 0000000010050014
26
27
The above exception is expected because QSPI is unsupported yet.
28
29
Signed-off-by: Bin Meng <bin.meng@windriver.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-id: 1592268641-7478-6-git-send-email-bmeng.cn@gmail.com
32
Message-Id: <1592268641-7478-6-git-send-email-bmeng.cn@gmail.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
34
---
17
target/riscv/vector_internals.c | 22 ++++++++++++++++++++++
35
include/hw/riscv/sifive_u.h | 1 +
18
1 file changed, 22 insertions(+)
36
hw/riscv/sifive_u.c | 4 ++++
37
2 files changed, 5 insertions(+)
19
38
20
diff --git a/target/riscv/vector_internals.c b/target/riscv/vector_internals.c
39
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
21
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/vector_internals.c
41
--- a/include/hw/riscv/sifive_u.h
23
+++ b/target/riscv/vector_internals.c
42
+++ b/include/hw/riscv/sifive_u.h
24
@@ -XXX,XX +XXX,XX @@ void vext_set_elems_1s(void *base, uint32_t is_agnostic, uint32_t cnt,
43
@@ -XXX,XX +XXX,XX @@ enum {
25
if (tot - cnt == 0) {
44
SIFIVE_U_UART1,
26
return ;
45
SIFIVE_U_GPIO,
27
}
46
SIFIVE_U_OTP,
47
+ SIFIVE_U_DMC,
48
SIFIVE_U_FLASH0,
49
SIFIVE_U_DRAM,
50
SIFIVE_U_GEM,
51
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/riscv/sifive_u.c
54
+++ b/hw/riscv/sifive_u.c
55
@@ -XXX,XX +XXX,XX @@ static const struct MemmapEntry {
56
[SIFIVE_U_OTP] = { 0x10070000, 0x1000 },
57
[SIFIVE_U_GEM] = { 0x10090000, 0x2000 },
58
[SIFIVE_U_GEM_MGMT] = { 0x100a0000, 0x1000 },
59
+ [SIFIVE_U_DMC] = { 0x100b0000, 0x10000 },
60
[SIFIVE_U_FLASH0] = { 0x20000000, 0x10000000 },
61
[SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
62
};
63
@@ -XXX,XX +XXX,XX @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
64
65
create_unimplemented_device("riscv.sifive.u.gem-mgmt",
66
memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size);
28
+
67
+
29
+ if (HOST_BIG_ENDIAN) {
68
+ create_unimplemented_device("riscv.sifive.u.dmc",
30
+ /*
69
+ memmap[SIFIVE_U_DMC].base, memmap[SIFIVE_U_DMC].size);
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
}
70
}
52
71
72
static Property sifive_u_soc_props[] = {
53
--
73
--
54
2.45.1
74
2.27.0
75
76
diff view generated by jsdifflib