1
The following changes since commit c95bd5ff1660883d15ad6e0005e4c8571604f51a:
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Merge remote-tracking branch 'remotes/philmd/tags/mips-fixes-20210322' into staging (2021-03-22 14:26:13 +0000)
3
The following changes since commit 4c127fdbe81d66e7cafed90908d0fd1f6f2a6cd0:
4
5
Merge remote-tracking branch 'remotes/rth/tags/pull-arm-20211021' into staging (2021-10-21 09:53:27 -0700)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20210322-2
9
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20211022-2
8
10
9
for you to fetch changes up to 9a27f69bd668d9d71674407badc412ce1231c7d5:
11
for you to fetch changes up to 11ec06f9eaedc801ded34c79861367b76ab2b731:
10
12
11
target/riscv: Prevent lost illegal instruction exceptions (2021-03-22 21:54:40 -0400)
13
hw/riscv: spike: Use MachineState::ram and MachineClass::default_ram_id (2021-10-22 23:35:47 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
RISC-V PR for 6.0
16
Fourth RISC-V PR for QEMU 6.2
15
17
16
This PR includes:
18
- Vector extension bug fixes
17
- Fix for vector CSR access
19
- Bit manipulation extension bug fix
18
- Improvements to the Ibex UART device
20
- Support vhost-user and numa mem options on all boards
19
- PMP improvements and bug fixes
21
- Rationalise XLEN and operand lengths
20
- Hypervisor extension bug fixes
22
- Bump the OpenTitan FPGA support
21
- ramfb support for the virt machine
23
- Remove the Ibex PLIC
22
- Fast read support for SST flash
24
- General code cleanup
23
- Improvements to the microchip_pfsoc machine
24
25
25
----------------------------------------------------------------
26
----------------------------------------------------------------
26
Alexander Wagner (1):
27
Alistair Francis (7):
27
hw/char: disable ibex uart receive if the buffer is full
28
target/riscv: Remove some unused macros
29
target/riscv: Organise the CPU properties
30
hw/riscv: opentitan: Update to the latest build
31
hw/intc: Remove the Ibex PLIC
32
hw/intc: sifive_plic: Move the properties
33
hw/intc: sifive_plic: Cleanup the realize function
34
hw/intc: sifive_plic: Cleanup the irq_request function
28
35
29
Asherah Connor (2):
36
Bin Meng (6):
30
hw/riscv: Add fw_cfg support to virt
37
hw/riscv: microchip_pfsoc: Use MachineState::ram and MachineClass::default_ram_id
31
hw/riscv: allow ramfb on virt
38
hw/riscv: opentitan: Use MachineState::ram and MachineClass::default_ram_id
39
hw/riscv: shakti_c: Use MachineState::ram and MachineClass::default_ram_id
40
hw/riscv: sifive_e: Use MachineState::ram and MachineClass::default_ram_id
41
hw/riscv: sifive_u: Use MachineState::ram and MachineClass::default_ram_id
42
hw/riscv: spike: Use MachineState::ram and MachineClass::default_ram_id
32
43
33
Bin Meng (3):
44
Frank Chang (2):
34
hw/block: m25p80: Support fast read for SST flashes
45
target/riscv: Pass the same value to oprsz and maxsz for vmv.v.v
35
hw/riscv: microchip_pfsoc: Map EMMC/SD mux register
46
target/riscv: fix TB_FLAGS bits overlapping bug for rvv/rvh
36
docs/system: riscv: Add documentation for 'microchip-icicle-kit' machine
37
47
38
Frank Chang (1):
48
Mingwang Li (1):
39
target/riscv: fix vs() to return proper error code
49
hw/riscv: virt: Use machine->ram as the system memory
40
50
41
Georg Kotheimer (6):
51
Philipp Tomsich (1):
42
target/riscv: Adjust privilege level for HLV(X)/HSV instructions
52
target/riscv: Fix orc.b implementation
43
target/riscv: Make VSTIP and VSEIP read-only in hip
44
target/riscv: Use background registers also for MSTATUS_MPV
45
target/riscv: Fix read and write accesses to vsip and vsie
46
target/riscv: Add proper two-stage lookup exception detection
47
target/riscv: Prevent lost illegal instruction exceptions
48
53
49
Jim Shu (3):
54
Richard Henderson (15):
50
target/riscv: propagate PMP permission to TLB page
55
target/riscv: Move cpu_get_tb_cpu_state out of line
51
target/riscv: add log of PMP permission checking
56
target/riscv: Create RISCVMXL enumeration
52
target/riscv: flush TLB pages if PMP permission has been changed
57
target/riscv: Split misa.mxl and misa.ext
58
target/riscv: Replace riscv_cpu_is_32bit with riscv_cpu_mxl
59
target/riscv: Add MXL/SXL/UXL to TB_FLAGS
60
target/riscv: Use REQUIRE_64BIT in amo_check64
61
target/riscv: Properly check SEW in amo_op
62
target/riscv: Replace is_32bit with get_xl/get_xlen
63
target/riscv: Replace DisasContext.w with DisasContext.ol
64
target/riscv: Use gen_arith_per_ol for RVM
65
target/riscv: Adjust trans_rev8_32 for riscv64
66
target/riscv: Use gen_unary_per_ol for RVB
67
target/riscv: Use gen_shift*_per_ol for RVB, RVI
68
target/riscv: Use riscv_csrrw_debug for cpu_dump
69
target/riscv: Compute mstatus.sd on demand
53
70
54
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++
71
Travis Geiselbrecht (1):
55
docs/system/target-riscv.rst | 1 +
72
target/riscv: line up all of the registers in the info register dump
56
include/hw/char/ibex_uart.h | 4 +
57
include/hw/riscv/microchip_pfsoc.h | 1 +
58
include/hw/riscv/virt.h | 2 +
59
target/riscv/cpu.h | 4 +
60
target/riscv/pmp.h | 4 +-
61
hw/block/m25p80.c | 3 +
62
hw/char/ibex_uart.c | 23 +++-
63
hw/riscv/microchip_pfsoc.c | 6 +
64
hw/riscv/virt.c | 33 ++++++
65
target/riscv/cpu.c | 1 +
66
target/riscv/cpu_helper.c | 144 +++++++++++++++--------
67
target/riscv/csr.c | 77 +++++++------
68
target/riscv/pmp.c | 84 ++++++++++----
69
target/riscv/translate.c | 179 +----------------------------
70
hw/riscv/Kconfig | 1 +
71
17 files changed, 367 insertions(+), 289 deletions(-)
72
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
73
73
74
include/hw/riscv/opentitan.h | 6 +-
75
target/riscv/cpu.h | 87 +++------
76
target/riscv/cpu_bits.h | 16 +-
77
hw/intc/ibex_plic.c | 307 --------------------------------
78
hw/intc/sifive_plic.c | 85 ++++-----
79
hw/riscv/boot.c | 2 +-
80
hw/riscv/microchip_pfsoc.c | 36 ++--
81
hw/riscv/opentitan.c | 38 +++-
82
hw/riscv/shakti_c.c | 6 +-
83
hw/riscv/sifive_e.c | 16 +-
84
hw/riscv/sifive_u.c | 6 +-
85
hw/riscv/spike.c | 6 +-
86
hw/riscv/virt.c | 6 +-
87
linux-user/elfload.c | 2 +-
88
linux-user/riscv/cpu_loop.c | 2 +-
89
semihosting/arm-compat-semi.c | 2 +-
90
target/riscv/cpu.c | 216 ++++++++++++----------
91
target/riscv/cpu_helper.c | 92 +++++++++-
92
target/riscv/csr.c | 104 ++++++-----
93
target/riscv/gdbstub.c | 10 +-
94
target/riscv/machine.c | 10 +-
95
target/riscv/monitor.c | 4 +-
96
target/riscv/translate.c | 174 +++++++++++++-----
97
target/riscv/insn_trans/trans_rvb.c.inc | 153 +++++++++-------
98
target/riscv/insn_trans/trans_rvi.c.inc | 44 ++---
99
target/riscv/insn_trans/trans_rvm.c.inc | 36 +++-
100
target/riscv/insn_trans/trans_rvv.c.inc | 32 ++--
101
hw/intc/meson.build | 1 -
102
28 files changed, 720 insertions(+), 779 deletions(-)
103
delete mode 100644 hw/intc/ibex_plic.c
104
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
oprsz and maxsz are passed with the same value in commit: eee2d61e202.
4
However, vmv.v.v was missed in that commit and should pass the same
5
value as well in its tcg_gen_gvec_2_ptr() call.
6
7
Signed-off-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211007081803.1705656-1-frank.chang@sifive.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool trans_vmv_v_v(DisasContext *s, arg_vmv_v_v *a)
20
tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_vl, 0, over);
21
22
tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs1),
23
- cpu_env, 0, s->vlen / 8, data, fns[s->sew]);
24
+ cpu_env, s->vlen / 8, s->vlen / 8, data,
25
+ fns[s->sew]);
26
gen_set_label(over);
27
}
28
return true;
29
--
30
2.31.1
31
32
diff view generated by jsdifflib
New patch
1
From: Travis Geiselbrecht <travisg@gmail.com>
1
2
3
Ensure the columns for all of the register names and values line up.
4
No functional change, just a minor tweak to the output.
5
6
Signed-off-by: Travis Geiselbrecht <travisg@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20211009055019.545153-1-travisg@gmail.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu.c | 10 +++++-----
12
1 file changed, 5 insertions(+), 5 deletions(-)
13
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
19
}
20
if (riscv_has_ext(env, RVH)) {
21
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
22
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
23
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus",
24
(target_ulong)env->vsstatus);
25
}
26
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ", env->mip);
27
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
28
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
29
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->stval);
30
if (riscv_has_ext(env, RVH)) {
31
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
32
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
33
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
34
+ qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
35
}
36
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mscratch", env->mscratch);
37
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "sscratch", env->sscratch);
38
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
39
#endif
40
41
for (i = 0; i < 32; i++) {
42
- qemu_fprintf(f, " %s " TARGET_FMT_lx,
43
+ qemu_fprintf(f, " %-8s " TARGET_FMT_lx,
44
riscv_int_regnames[i], env->gpr[i]);
45
if ((i & 3) == 3) {
46
qemu_fprintf(f, "\n");
47
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
48
}
49
if (flags & CPU_DUMP_FPU) {
50
for (i = 0; i < 32; i++) {
51
- qemu_fprintf(f, " %s %016" PRIx64,
52
+ qemu_fprintf(f, " %-8s %016" PRIx64,
53
riscv_fpr_regnames[i], env->fpr[i]);
54
if ((i & 3) == 3) {
55
qemu_fprintf(f, "\n");
56
--
57
2.31.1
58
59
diff view generated by jsdifflib
New patch
1
From: Philipp Tomsich <philipp.tomsich@vrull.eu>
1
2
3
The earlier implementation fell into a corner case for bytes that were
4
0x01, giving a wrong result (but not affecting our application test
5
cases for strings, as an ASCII value 0x01 is rare in those...).
6
7
This changes the algorithm to:
8
1. Mask out the high-bit of each bytes (so that each byte is <= 127).
9
2. Add 127 to each byte (i.e. if the low 7 bits are not 0, this will overflow
10
into the highest bit of each byte).
11
3. Bitwise-or the original value back in (to cover those cases where the
12
source byte was exactly 128) to saturate the high-bit.
13
4. Shift-and-mask (implemented as a mask-and-shift) to extract the MSB of
14
each byte into its LSB.
15
5. Multiply with 0xff to fan out the LSB to all bits of each byte.
16
17
Fixes: d7a4fcb034 ("target/riscv: Add orc.b instruction for Zbb, removing gorc/gorci")
18
19
Signed-off-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
20
Reported-by: Vincent Palatin <vpalatin@rivosinc.com>
21
Tested-by: Vincent Palatin <vpalatin@rivosinc.com>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20211013184125.2010897-1-philipp.tomsich@vrull.eu
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
target/riscv/insn_trans/trans_rvb.c.inc | 13 ++++++++-----
27
1 file changed, 8 insertions(+), 5 deletions(-)
28
29
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/insn_trans/trans_rvb.c.inc
32
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
33
@@ -XXX,XX +XXX,XX @@ static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 *a)
34
static void gen_orc_b(TCGv ret, TCGv source1)
35
{
36
TCGv tmp = tcg_temp_new();
37
- TCGv ones = tcg_constant_tl(dup_const_tl(MO_8, 0x01));
38
+ TCGv low7 = tcg_constant_tl(dup_const_tl(MO_8, 0x7f));
39
40
- /* Set lsb in each byte if the byte was zero. */
41
- tcg_gen_sub_tl(tmp, source1, ones);
42
- tcg_gen_andc_tl(tmp, tmp, source1);
43
+ /* Set msb in each byte if the byte was non-zero. */
44
+ tcg_gen_and_tl(tmp, source1, low7);
45
+ tcg_gen_add_tl(tmp, tmp, low7);
46
+ tcg_gen_or_tl(tmp, tmp, source1);
47
+
48
+ /* Extract the msb to the lsb in each byte */
49
+ tcg_gen_andc_tl(tmp, tmp, low7);
50
tcg_gen_shri_tl(tmp, tmp, 7);
51
- tcg_gen_andc_tl(tmp, ones, tmp);
52
53
/* Replicate the lsb of each byte across the byte. */
54
tcg_gen_muli_tl(ret, tmp, 0xff);
55
--
56
2.31.1
57
58
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Mingwang Li <limingwang@huawei.com>
2
2
3
Allow ramfb on virt. This lets `-device ramfb' work.
3
If default main_mem is used to be registered as the system memory,
4
other memory cannot be initialized. Therefore, the system memory
5
should be initialized to the machine->ram, which consists of the
6
default main_mem and other possible memory required by applications,
7
such as shared hugepage memory in DPDK.
4
8
5
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
9
Also, the mc->defaul_ram_id should be set to the default main_mem,
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
10
such as "riscv_virt_board.ram" for the virt machine.
11
12
Signed-off-by: Mingwang Li <limingwang@huawei.com>
13
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210318235041.17175-3-ashe@kivikakk.ee
15
Message-id: 20211016030908.40480-1-limingwang@huawei.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
17
---
11
hw/riscv/virt.c | 3 +++
18
hw/riscv/virt.c | 6 ++----
12
1 file changed, 3 insertions(+)
19
1 file changed, 2 insertions(+), 4 deletions(-)
13
20
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
21
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
23
--- a/hw/riscv/virt.c
17
+++ b/hw/riscv/virt.c
24
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
19
#include "sysemu/sysemu.h"
26
const MemMapEntry *memmap = virt_memmap;
20
#include "hw/pci/pci.h"
27
RISCVVirtState *s = RISCV_VIRT_MACHINE(machine);
21
#include "hw/pci-host/gpex.h"
28
MemoryRegion *system_memory = get_system_memory();
22
+#include "hw/display/ramfb.h"
29
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
23
30
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
24
static const MemMapEntry virt_memmap[] = {
31
char *plic_hart_config, *soc_name;
25
[VIRT_DEBUG] = { 0x0, 0x100 },
32
target_ulong start_addr = memmap[VIRT_DRAM].base;
33
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
34
}
35
36
/* register system main memory (actual RAM) */
37
- memory_region_init_ram(main_mem, NULL, "riscv_virt_board.ram",
38
- machine->ram_size, &error_fatal);
39
memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base,
40
- main_mem);
41
+ machine->ram);
42
43
/* create device tree */
44
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
26
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
45
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
27
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
46
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
28
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
47
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
29
mc->numa_mem_supported = true;
48
mc->numa_mem_supported = true;
30
+
49
+ mc->default_ram_id = "riscv_virt_board.ram";
31
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
50
32
}
51
machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
33
52
34
static const TypeInfo virt_machine_typeinfo = {
35
--
53
--
36
2.30.1
54
2.31.1
37
55
38
56
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
vs() should return -RISCV_EXCP_ILLEGAL_INST instead of -1 if rvv feature
3
TB_FLAGS mem_idx bits was extended from 2 bits to 3 bits in
4
is not enabled.
4
commit: c445593, but other TB_FLAGS bits for rvv and rvh were
5
5
not shift as well so these bits may overlap with each other when
6
If -1 is returned, exception will be raised and cs->exception_index will
6
rvv is enabled.
7
be set to the negative return value. The exception will then be treated
8
as an instruction access fault instead of illegal instruction fault.
9
7
10
Signed-off-by: Frank Chang <frank.chang@sifive.com>
8
Signed-off-by: Frank Chang <frank.chang@sifive.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20210223065935.20208-1-frank.chang@sifive.com
11
Message-Id: <20211015074627.3957162-2-frank.chang@sifive.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
13
---
16
target/riscv/csr.c | 2 +-
14
target/riscv/cpu.h | 14 +++++++-------
17
1 file changed, 1 insertion(+), 1 deletion(-)
15
target/riscv/translate.c | 2 +-
16
2 files changed, 8 insertions(+), 8 deletions(-)
18
17
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
18
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
20
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/csr.c
21
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ static int vs(CPURISCVState *env, int csrno)
22
@@ -XXX,XX +XXX,XX @@ void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env,
24
if (env->misa & RVV) {
23
target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
25
return 0;
24
void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
26
}
25
27
- return -1;
26
-#define TB_FLAGS_MMU_MASK 7
28
+ return -RISCV_EXCP_ILLEGAL_INST;
27
#define TB_FLAGS_PRIV_MMU_MASK 3
29
}
28
#define TB_FLAGS_PRIV_HYP_ACCESS_MASK (1 << 2)
30
29
#define TB_FLAGS_MSTATUS_FS MSTATUS_FS
31
static int ctr(CPURISCVState *env, int csrno)
30
@@ -XXX,XX +XXX,XX @@ typedef CPURISCVState CPUArchState;
31
typedef RISCVCPU ArchCPU;
32
#include "exec/cpu-all.h"
33
34
-FIELD(TB_FLAGS, VL_EQ_VLMAX, 2, 1)
35
-FIELD(TB_FLAGS, LMUL, 3, 2)
36
-FIELD(TB_FLAGS, SEW, 5, 3)
37
-FIELD(TB_FLAGS, VILL, 8, 1)
38
+FIELD(TB_FLAGS, MEM_IDX, 0, 3)
39
+FIELD(TB_FLAGS, VL_EQ_VLMAX, 3, 1)
40
+FIELD(TB_FLAGS, LMUL, 4, 2)
41
+FIELD(TB_FLAGS, SEW, 6, 3)
42
+FIELD(TB_FLAGS, VILL, 9, 1)
43
/* Is a Hypervisor instruction load/store allowed? */
44
-FIELD(TB_FLAGS, HLSX, 9, 1)
45
-FIELD(TB_FLAGS, MSTATUS_HS_FS, 10, 2)
46
+FIELD(TB_FLAGS, HLSX, 10, 1)
47
+FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
48
49
bool riscv_cpu_is_32bit(CPURISCVState *env);
50
51
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/translate.c
54
+++ b/target/riscv/translate.c
55
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
56
uint32_t tb_flags = ctx->base.tb->flags;
57
58
ctx->pc_succ_insn = ctx->base.pc_first;
59
- ctx->mem_idx = tb_flags & TB_FLAGS_MMU_MASK;
60
+ ctx->mem_idx = FIELD_EX32(tb_flags, TB_FLAGS, MEM_IDX);
61
ctx->mstatus_fs = tb_flags & TB_FLAGS_MSTATUS_FS;
62
ctx->priv_ver = env->priv_ver;
63
#if !defined(CONFIG_USER_ONLY)
32
--
64
--
33
2.30.1
65
2.31.1
34
66
35
67
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
Since commit 1a9540d1f1a
4
("target/riscv: Drop support for ISA spec version 1.09.1")
5
these definitions are unused, remove them.
6
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
11
Message-id: f4d8a7a035f39c0a35d44c1e371c5c99cc2fa15a.1634531504.git.alistair.francis@wdc.com
12
---
13
target/riscv/cpu_bits.h | 8 --------
14
1 file changed, 8 deletions(-)
15
16
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu_bits.h
19
+++ b/target/riscv/cpu_bits.h
20
@@ -XXX,XX +XXX,XX @@
21
#define SATP64_ASID 0x0FFFF00000000000ULL
22
#define SATP64_PPN 0x00000FFFFFFFFFFFULL
23
24
-/* VM modes (mstatus.vm) privileged ISA 1.9.1 */
25
-#define VM_1_09_MBARE 0
26
-#define VM_1_09_MBB 1
27
-#define VM_1_09_MBBID 2
28
-#define VM_1_09_SV32 8
29
-#define VM_1_09_SV39 9
30
-#define VM_1_09_SV48 10
31
-
32
/* VM modes (satp.mode) privileged ISA 1.10 */
33
#define VM_1_10_MBARE 0
34
#define VM_1_10_SV32 1
35
--
36
2.31.1
37
38
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
Organise the CPU properties so that standard extensions come first
4
then followed by experimental extensions.
5
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Message-id: b6598570f60c5ee7f402be56d837bb44b289cc4d.1634531504.git.alistair.francis@wdc.com
10
---
11
target/riscv/cpu.c | 17 ++++++++++-------
12
1 file changed, 10 insertions(+), 7 deletions(-)
13
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu.c
17
+++ b/target/riscv/cpu.c
18
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_init(Object *obj)
19
}
20
21
static Property riscv_cpu_properties[] = {
22
+ /* Defaults for standard extensions */
23
DEFINE_PROP_BOOL("i", RISCVCPU, cfg.ext_i, true),
24
DEFINE_PROP_BOOL("e", RISCVCPU, cfg.ext_e, false),
25
DEFINE_PROP_BOOL("g", RISCVCPU, cfg.ext_g, true),
26
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
27
DEFINE_PROP_BOOL("c", RISCVCPU, cfg.ext_c, true),
28
DEFINE_PROP_BOOL("s", RISCVCPU, cfg.ext_s, true),
29
DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
30
- /* This is experimental so mark with 'x-' */
31
+ DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
32
+ DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
33
+ DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
34
+ DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
35
+ DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
36
+
37
+ DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
38
+
39
+ /* These are experimental so mark with 'x-' */
40
DEFINE_PROP_BOOL("x-zba", RISCVCPU, cfg.ext_zba, false),
41
DEFINE_PROP_BOOL("x-zbb", RISCVCPU, cfg.ext_zbb, false),
42
DEFINE_PROP_BOOL("x-zbc", RISCVCPU, cfg.ext_zbc, false),
43
DEFINE_PROP_BOOL("x-zbs", RISCVCPU, cfg.ext_zbs, false),
44
DEFINE_PROP_BOOL("x-h", RISCVCPU, cfg.ext_h, false),
45
DEFINE_PROP_BOOL("x-v", RISCVCPU, cfg.ext_v, false),
46
- DEFINE_PROP_BOOL("Counters", RISCVCPU, cfg.ext_counters, true),
47
- DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
48
- DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
49
- DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
50
DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
51
DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128),
52
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
53
- DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
54
- DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
55
/* ePMP 0.9.3 */
56
DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
57
58
--
59
2.31.1
60
61
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Currently, PMP permission checking of TLB page is bypassed if TLB hits
3
Move the function to cpu_helper.c, as it is large and growing.
4
Fix it by propagating PMP permission to TLB page permission.
5
4
6
PMP permission checking also use MMU-style API to change TLB permission
5
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
and size.
8
9
Signed-off-by: Jim Shu <cwshu@andestech.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1613916082-19528-2-git-send-email-cwshu@andestech.com
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20211020031709.359469-2-richard.henderson@linaro.org
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/pmp.h | 4 +-
11
target/riscv/cpu.h | 47 ++-------------------------------------
15
target/riscv/cpu_helper.c | 84 +++++++++++++++++++++++++++++----------
12
target/riscv/cpu_helper.c | 46 ++++++++++++++++++++++++++++++++++++++
16
target/riscv/pmp.c | 80 +++++++++++++++++++++++++++----------
13
2 files changed, 48 insertions(+), 45 deletions(-)
17
3 files changed, 125 insertions(+), 43 deletions(-)
18
14
19
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
15
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.h
17
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/pmp.h
18
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
19
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
24
target_ulong val);
20
return cpu->cfg.vlen >> (sew + 3 - lmul);
25
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
21
}
26
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
22
27
- target_ulong size, pmp_priv_t priv, target_ulong mode);
23
-static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
28
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
24
- target_ulong *cs_base, uint32_t *pflags)
29
+ target_ulong mode);
25
-{
30
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
26
- uint32_t flags = 0;
31
target_ulong *tlb_size);
27
-
32
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
28
- *pc = env->pc;
33
void pmp_update_rule_nums(CPURISCVState *env);
29
- *cs_base = 0;
34
uint32_t pmp_get_num_rules(CPURISCVState *env);
30
-
35
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
31
- if (riscv_has_ext(env, RVV)) {
36
32
- uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
37
#endif
33
- bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
34
- flags = FIELD_DP32(flags, TB_FLAGS, VILL,
35
- FIELD_EX64(env->vtype, VTYPE, VILL));
36
- flags = FIELD_DP32(flags, TB_FLAGS, SEW,
37
- FIELD_EX64(env->vtype, VTYPE, VSEW));
38
- flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
39
- FIELD_EX64(env->vtype, VTYPE, VLMUL));
40
- flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
41
- } else {
42
- flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
43
- }
44
-
45
-#ifdef CONFIG_USER_ONLY
46
- flags |= TB_FLAGS_MSTATUS_FS;
47
-#else
48
- flags |= cpu_mmu_index(env, 0);
49
- if (riscv_cpu_fp_enabled(env)) {
50
- flags |= env->mstatus & MSTATUS_FS;
51
- }
52
-
53
- if (riscv_has_ext(env, RVH)) {
54
- if (env->priv == PRV_M ||
55
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
56
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
57
- get_field(env->hstatus, HSTATUS_HU))) {
58
- flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
59
- }
60
-
61
- flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
62
- get_field(env->mstatus_hs, MSTATUS_FS));
63
- }
64
-#endif
65
-
66
- *pflags = flags;
67
-}
68
+void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
69
+ target_ulong *cs_base, uint32_t *pflags);
70
71
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
72
target_ulong *ret_value,
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
73
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
39
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
75
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
76
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
77
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
43
env->load_res = -1;
78
#endif
44
}
79
}
45
80
46
+/*
81
+void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
47
+ * get_physical_address_pmp - check PMP permission for this physical address
82
+ target_ulong *cs_base, uint32_t *pflags)
48
+ *
49
+ * Match the PMP region and check permission for this physical address and it's
50
+ * TLB page. Returns 0 if the permission checking was successful
51
+ *
52
+ * @env: CPURISCVState
53
+ * @prot: The returned protection attributes
54
+ * @tlb_size: TLB page size containing addr. It could be modified after PMP
55
+ * permission checking. NULL if not set TLB page for addr.
56
+ * @addr: The physical address to be checked permission
57
+ * @access_type: The type of MMU access
58
+ * @mode: Indicates current privilege level.
59
+ */
60
+static int get_physical_address_pmp(CPURISCVState *env, int *prot,
61
+ target_ulong *tlb_size, hwaddr addr,
62
+ int size, MMUAccessType access_type,
63
+ int mode)
64
+{
83
+{
65
+ pmp_priv_t pmp_priv;
84
+ uint32_t flags = 0;
66
+ target_ulong tlb_size_pmp = 0;
67
+
85
+
68
+ if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
86
+ *pc = env->pc;
69
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
87
+ *cs_base = 0;
70
+ return TRANSLATE_SUCCESS;
88
+
89
+ if (riscv_has_ext(env, RVV)) {
90
+ uint32_t vlmax = vext_get_vlmax(env_archcpu(env), env->vtype);
91
+ bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl);
92
+ flags = FIELD_DP32(flags, TB_FLAGS, VILL,
93
+ FIELD_EX64(env->vtype, VTYPE, VILL));
94
+ flags = FIELD_DP32(flags, TB_FLAGS, SEW,
95
+ FIELD_EX64(env->vtype, VTYPE, VSEW));
96
+ flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
97
+ FIELD_EX64(env->vtype, VTYPE, VLMUL));
98
+ flags = FIELD_DP32(flags, TB_FLAGS, VL_EQ_VLMAX, vl_eq_vlmax);
99
+ } else {
100
+ flags = FIELD_DP32(flags, TB_FLAGS, VILL, 1);
71
+ }
101
+ }
72
+
102
+
73
+ if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
103
+#ifdef CONFIG_USER_ONLY
74
+ mode)) {
104
+ flags |= TB_FLAGS_MSTATUS_FS;
75
+ *prot = 0;
105
+#else
76
+ return TRANSLATE_PMP_FAIL;
106
+ flags |= cpu_mmu_index(env, 0);
107
+ if (riscv_cpu_fp_enabled(env)) {
108
+ flags |= env->mstatus & MSTATUS_FS;
77
+ }
109
+ }
78
+
110
+
79
+ *prot = pmp_priv_to_page_prot(pmp_priv);
111
+ if (riscv_has_ext(env, RVH)) {
80
+ if (tlb_size != NULL) {
112
+ if (env->priv == PRV_M ||
81
+ if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
113
+ (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
82
+ *tlb_size = tlb_size_pmp;
114
+ (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
115
+ get_field(env->hstatus, HSTATUS_HU))) {
116
+ flags = FIELD_DP32(flags, TB_FLAGS, HLSX, 1);
83
+ }
117
+ }
118
+
119
+ flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_FS,
120
+ get_field(env->mstatus_hs, MSTATUS_FS));
84
+ }
121
+ }
122
+#endif
85
+
123
+
86
+ return TRANSLATE_SUCCESS;
124
+ *pflags = flags;
87
+}
125
+}
88
+
126
+
89
/* get_physical_address - get the physical address for this virtual address
90
*
91
* Do a page table walk to obtain the physical address corresponding to a
92
@@ -XXX,XX +XXX,XX @@ restart:
93
pte_addr = base + idx * ptesize;
94
}
95
96
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
97
- !pmp_hart_has_privs(env, pte_addr, sizeof(target_ulong),
98
- 1 << MMU_DATA_LOAD, PRV_S)) {
99
+ int pmp_prot;
100
+ int pmp_ret = get_physical_address_pmp(env, &pmp_prot, NULL, pte_addr,
101
+ sizeof(target_ulong),
102
+ MMU_DATA_LOAD, PRV_S);
103
+ if (pmp_ret != TRANSLATE_SUCCESS) {
104
return TRANSLATE_PMP_FAIL;
105
}
106
107
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
108
#ifndef CONFIG_USER_ONLY
127
#ifndef CONFIG_USER_ONLY
109
vaddr im_address;
128
static int riscv_cpu_local_irq_pending(CPURISCVState *env)
110
hwaddr pa = 0;
111
- int prot, prot2;
112
+ int prot, prot2, prot_pmp;
113
bool pmp_violation = false;
114
bool first_stage_error = true;
115
bool two_stage_lookup = false;
116
int ret = TRANSLATE_FAIL;
117
int mode = mmu_idx;
118
- target_ulong tlb_size = 0;
119
+ /* default TLB page size */
120
+ target_ulong tlb_size = TARGET_PAGE_SIZE;
121
122
env->guest_phys_fault_addr = 0;
123
124
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
125
126
prot &= prot2;
127
128
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
129
- (ret == TRANSLATE_SUCCESS) &&
130
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
131
- ret = TRANSLATE_PMP_FAIL;
132
+ if (ret == TRANSLATE_SUCCESS) {
133
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
134
+ size, access_type, mode);
135
+ prot &= prot_pmp;
136
}
137
138
if (ret != TRANSLATE_SUCCESS) {
139
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
140
"%s address=%" VADDR_PRIx " ret %d physical "
141
TARGET_FMT_plx " prot %d\n",
142
__func__, address, ret, pa, prot);
143
- }
144
145
- if (riscv_feature(env, RISCV_FEATURE_PMP) &&
146
- (ret == TRANSLATE_SUCCESS) &&
147
- !pmp_hart_has_privs(env, pa, size, 1 << access_type, mode)) {
148
- ret = TRANSLATE_PMP_FAIL;
149
+ if (ret == TRANSLATE_SUCCESS) {
150
+ ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
151
+ size, access_type, mode);
152
+ prot &= prot_pmp;
153
+ }
154
}
155
+
156
if (ret == TRANSLATE_PMP_FAIL) {
157
pmp_violation = true;
158
}
159
160
if (ret == TRANSLATE_SUCCESS) {
161
- if (pmp_is_range_in_tlb(env, pa & TARGET_PAGE_MASK, &tlb_size)) {
162
- tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
163
- prot, mmu_idx, tlb_size);
164
- } else {
165
- tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
166
- prot, mmu_idx, TARGET_PAGE_SIZE);
167
- }
168
+ tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
169
+ prot, mmu_idx, tlb_size);
170
return true;
171
} else if (probe) {
172
return false;
173
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/riscv/pmp.c
176
+++ b/target/riscv/pmp.c
177
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
178
return result;
179
}
180
181
+/*
182
+ * Check if the address has required RWX privs when no PMP entry is matched.
183
+ */
184
+static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
185
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
186
+ target_ulong mode)
187
+{
188
+ bool ret;
189
+
190
+ if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
191
+ /*
192
+ * Privileged spec v1.10 states if HW doesn't implement any PMP entry
193
+ * or no PMP entry matches an M-Mode access, the access succeeds.
194
+ */
195
+ ret = true;
196
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
197
+ } else {
198
+ /*
199
+ * Other modes are not allowed to succeed if they don't * match a rule,
200
+ * but there are rules. We've checked for no rule earlier in this
201
+ * function.
202
+ */
203
+ ret = false;
204
+ *allowed_privs = 0;
205
+ }
206
+
207
+ return ret;
208
+}
209
+
210
211
/*
212
* Public Interface
213
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
214
* Check if the address has required RWX privs to complete desired operation
215
*/
216
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
217
- target_ulong size, pmp_priv_t privs, target_ulong mode)
218
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
219
+ target_ulong mode)
220
{
129
{
221
int i = 0;
222
int ret = -1;
223
int pmp_size = 0;
224
target_ulong s = 0;
225
target_ulong e = 0;
226
- pmp_priv_t allowed_privs = 0;
227
228
/* Short cut if no rules */
229
if (0 == pmp_get_num_rules(env)) {
230
- return (env->priv == PRV_M) ? true : false;
231
+ return pmp_hart_has_privs_default(env, addr, size, privs,
232
+ allowed_privs, mode);
233
}
234
235
if (size == 0) {
236
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
237
* check
238
*/
239
if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
240
- allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
241
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
242
if ((mode != PRV_M) || pmp_is_locked(env, i)) {
243
- allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
244
+ *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
245
}
246
247
- if ((privs & allowed_privs) == privs) {
248
- ret = 1;
249
- break;
250
- } else {
251
- ret = 0;
252
- break;
253
- }
254
+ ret = ((privs & *allowed_privs) == privs);
255
+ break;
256
}
257
}
258
259
/* No rule matched */
260
if (ret == -1) {
261
- if (mode == PRV_M) {
262
- ret = 1; /* Privileged spec v1.10 states if no PMP entry matches an
263
- * M-Mode access, the access succeeds */
264
- } else {
265
- ret = 0; /* Other modes are not allowed to succeed if they don't
266
- * match a rule, but there are rules. We've checked for
267
- * no rule earlier in this function. */
268
- }
269
+ return pmp_hart_has_privs_default(env, addr, size, privs,
270
+ allowed_privs, mode);
271
}
272
273
return ret == 1 ? true : false;
274
}
275
276
-
277
/*
278
* Handle a write to a pmpcfg CSP
279
*/
280
@@ -XXX,XX +XXX,XX @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
281
282
return false;
283
}
284
+
285
+/*
286
+ * Convert PMP privilege to TLB page privilege.
287
+ */
288
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
289
+{
290
+ int prot = 0;
291
+
292
+ if (pmp_priv & PMP_READ) {
293
+ prot |= PAGE_READ;
294
+ }
295
+ if (pmp_priv & PMP_WRITE) {
296
+ prot |= PAGE_WRITE;
297
+ }
298
+ if (pmp_priv & PMP_EXEC) {
299
+ prot |= PAGE_EXEC;
300
+ }
301
+
302
+ return prot;
303
+}
304
--
130
--
305
2.30.1
131
2.31.1
306
132
307
133
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Move the MXL_RV* defines to enumerators.
4
5
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20211020031709.359469-3-richard.henderson@linaro.org
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/cpu_bits.h | 8 +++++---
12
1 file changed, 5 insertions(+), 3 deletions(-)
13
14
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu_bits.h
17
+++ b/target/riscv/cpu_bits.h
18
@@ -XXX,XX +XXX,XX @@
19
#define MISA32_MXL 0xC0000000
20
#define MISA64_MXL 0xC000000000000000ULL
21
22
-#define MXL_RV32 1
23
-#define MXL_RV64 2
24
-#define MXL_RV128 3
25
+typedef enum {
26
+ MXL_RV32 = 1,
27
+ MXL_RV64 = 2,
28
+ MXL_RV128 = 3,
29
+} RISCVMXL;
30
31
/* sstatus CSR bits */
32
#define SSTATUS_UIE 0x00000001
33
--
34
2.31.1
35
36
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
3
The hw representation of misa.mxl is at the high bits of the
4
misa csr. Representing this in the same way inside QEMU
5
results in overly complex code trying to check that field.
6
7
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20210311094902.1377593-1-georg.kotheimer@kernkonzept.com
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20211020031709.359469-4-richard.henderson@linaro.org
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
12
---
8
target/riscv/csr.c | 7 ++++---
13
target/riscv/cpu.h | 15 +++----
9
1 file changed, 4 insertions(+), 3 deletions(-)
14
linux-user/elfload.c | 2 +-
15
linux-user/riscv/cpu_loop.c | 2 +-
16
target/riscv/cpu.c | 78 +++++++++++++++++++++----------------
17
target/riscv/csr.c | 44 ++++++++++++++-------
18
target/riscv/gdbstub.c | 8 ++--
19
target/riscv/machine.c | 10 +++--
20
target/riscv/translate.c | 10 +++--
21
8 files changed, 100 insertions(+), 69 deletions(-)
10
22
23
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/cpu.h
26
+++ b/target/riscv/cpu.h
27
@@ -XXX,XX +XXX,XX @@
28
#include "exec/cpu-defs.h"
29
#include "fpu/softfloat-types.h"
30
#include "qom/object.h"
31
+#include "cpu_bits.h"
32
33
#define TCG_GUEST_DEFAULT_MO 0
34
35
@@ -XXX,XX +XXX,XX @@
36
# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE64
37
#endif
38
39
-#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
40
-#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
41
-
42
#define RV(x) ((target_ulong)1 << (x - 'A'))
43
44
#define RVI RV('I')
45
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
46
target_ulong priv_ver;
47
target_ulong bext_ver;
48
target_ulong vext_ver;
49
- target_ulong misa;
50
- target_ulong misa_mask;
51
+
52
+ /* RISCVMXL, but uint32_t for vmstate migration */
53
+ uint32_t misa_mxl; /* current mxl */
54
+ uint32_t misa_mxl_max; /* max mxl for this cpu */
55
+ uint32_t misa_ext; /* current extensions */
56
+ uint32_t misa_ext_mask; /* max ext for this cpu */
57
58
uint32_t features;
59
60
@@ -XXX,XX +XXX,XX @@ struct RISCVCPU {
61
62
static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
63
{
64
- return (env->misa & ext) != 0;
65
+ return (env->misa_ext & ext) != 0;
66
}
67
68
static inline bool riscv_feature(CPURISCVState *env, int feature)
69
@@ -XXX,XX +XXX,XX @@ static inline bool riscv_feature(CPURISCVState *env, int feature)
70
}
71
72
#include "cpu_user.h"
73
-#include "cpu_bits.h"
74
75
extern const char * const riscv_int_regnames[];
76
extern const char * const riscv_fpr_regnames[];
77
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/linux-user/elfload.c
80
+++ b/linux-user/elfload.c
81
@@ -XXX,XX +XXX,XX @@ static uint32_t get_elf_hwcap(void)
82
uint32_t mask = MISA_BIT('I') | MISA_BIT('M') | MISA_BIT('A')
83
| MISA_BIT('F') | MISA_BIT('D') | MISA_BIT('C');
84
85
- return cpu->env.misa & mask;
86
+ return cpu->env.misa_ext & mask;
87
#undef MISA_BIT
88
}
89
90
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/linux-user/riscv/cpu_loop.c
93
+++ b/linux-user/riscv/cpu_loop.c
94
@@ -XXX,XX +XXX,XX @@ void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs)
95
env->gpr[xSP] = regs->sp;
96
env->elf_flags = info->elf_flags;
97
98
- if ((env->misa & RVE) && !(env->elf_flags & EF_RISCV_RVE)) {
99
+ if ((env->misa_ext & RVE) && !(env->elf_flags & EF_RISCV_RVE)) {
100
error_report("Incompatible ELF: RVE cpu requires RVE ABI binary");
101
exit(EXIT_FAILURE);
102
}
103
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
104
index XXXXXXX..XXXXXXX 100644
105
--- a/target/riscv/cpu.c
106
+++ b/target/riscv/cpu.c
107
@@ -XXX,XX +XXX,XX @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
108
109
bool riscv_cpu_is_32bit(CPURISCVState *env)
110
{
111
- if (env->misa & RV64) {
112
- return false;
113
- }
114
-
115
- return true;
116
+ return env->misa_mxl == MXL_RV32;
117
}
118
119
-static void set_misa(CPURISCVState *env, target_ulong misa)
120
+static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
121
{
122
- env->misa_mask = env->misa = misa;
123
+ env->misa_mxl_max = env->misa_mxl = mxl;
124
+ env->misa_ext_mask = env->misa_ext = ext;
125
}
126
127
static void set_priv_version(CPURISCVState *env, int priv_ver)
128
@@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj)
129
{
130
CPURISCVState *env = &RISCV_CPU(obj)->env;
131
#if defined(TARGET_RISCV32)
132
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
133
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
134
#elif defined(TARGET_RISCV64)
135
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVU);
136
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU);
137
#endif
138
set_priv_version(env, PRIV_VERSION_1_11_0);
139
}
140
@@ -XXX,XX +XXX,XX @@ static void rv64_base_cpu_init(Object *obj)
141
{
142
CPURISCVState *env = &RISCV_CPU(obj)->env;
143
/* We set this in the realise function */
144
- set_misa(env, RV64);
145
+ set_misa(env, MXL_RV64, 0);
146
}
147
148
static void rv64_sifive_u_cpu_init(Object *obj)
149
{
150
CPURISCVState *env = &RISCV_CPU(obj)->env;
151
- set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
152
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
153
set_priv_version(env, PRIV_VERSION_1_10_0);
154
}
155
156
static void rv64_sifive_e_cpu_init(Object *obj)
157
{
158
CPURISCVState *env = &RISCV_CPU(obj)->env;
159
- set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
160
+ set_misa(env, MXL_RV64, RVI | RVM | RVA | RVC | RVU);
161
set_priv_version(env, PRIV_VERSION_1_10_0);
162
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
163
}
164
@@ -XXX,XX +XXX,XX @@ static void rv32_base_cpu_init(Object *obj)
165
{
166
CPURISCVState *env = &RISCV_CPU(obj)->env;
167
/* We set this in the realise function */
168
- set_misa(env, RV32);
169
+ set_misa(env, MXL_RV32, 0);
170
}
171
172
static void rv32_sifive_u_cpu_init(Object *obj)
173
{
174
CPURISCVState *env = &RISCV_CPU(obj)->env;
175
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
176
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
177
set_priv_version(env, PRIV_VERSION_1_10_0);
178
}
179
180
static void rv32_sifive_e_cpu_init(Object *obj)
181
{
182
CPURISCVState *env = &RISCV_CPU(obj)->env;
183
- set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
184
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVC | RVU);
185
set_priv_version(env, PRIV_VERSION_1_10_0);
186
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
187
}
188
@@ -XXX,XX +XXX,XX @@ static void rv32_sifive_e_cpu_init(Object *obj)
189
static void rv32_ibex_cpu_init(Object *obj)
190
{
191
CPURISCVState *env = &RISCV_CPU(obj)->env;
192
- set_misa(env, RV32 | RVI | RVM | RVC | RVU);
193
+ set_misa(env, MXL_RV32, RVI | RVM | RVC | RVU);
194
set_priv_version(env, PRIV_VERSION_1_10_0);
195
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
196
qdev_prop_set_bit(DEVICE(obj), "x-epmp", true);
197
@@ -XXX,XX +XXX,XX @@ static void rv32_ibex_cpu_init(Object *obj)
198
static void rv32_imafcu_nommu_cpu_init(Object *obj)
199
{
200
CPURISCVState *env = &RISCV_CPU(obj)->env;
201
- set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU);
202
+ set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
203
set_priv_version(env, PRIV_VERSION_1_10_0);
204
set_resetvec(env, DEFAULT_RSTVEC);
205
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
206
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
207
208
mcc->parent_reset(dev);
209
#ifndef CONFIG_USER_ONLY
210
+ env->misa_mxl = env->misa_mxl_max;
211
env->priv = PRV_M;
212
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
213
env->mcause = 0;
214
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
215
CPURISCVState *env = &cpu->env;
216
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
217
int priv_version = 0;
218
- target_ulong target_misa = env->misa;
219
Error *local_err = NULL;
220
221
cpu_exec_realizefn(cs, &local_err);
222
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
223
224
set_resetvec(env, cpu->cfg.resetvec);
225
226
- /* If only XLEN is set for misa, then set misa from properties */
227
- if (env->misa == RV32 || env->misa == RV64) {
228
+ /* Validate that MISA_MXL is set properly. */
229
+ switch (env->misa_mxl_max) {
230
+#ifdef TARGET_RISCV64
231
+ case MXL_RV64:
232
+ break;
233
+#endif
234
+ case MXL_RV32:
235
+ break;
236
+ default:
237
+ g_assert_not_reached();
238
+ }
239
+ assert(env->misa_mxl_max == env->misa_mxl);
240
+
241
+ /* If only MISA_EXT is unset for misa, then set it from properties */
242
+ if (env->misa_ext == 0) {
243
+ uint32_t ext = 0;
244
+
245
/* Do some ISA extension error checking */
246
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
247
error_setg(errp,
248
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
249
250
/* Set the ISA extensions, checks should have happened above */
251
if (cpu->cfg.ext_i) {
252
- target_misa |= RVI;
253
+ ext |= RVI;
254
}
255
if (cpu->cfg.ext_e) {
256
- target_misa |= RVE;
257
+ ext |= RVE;
258
}
259
if (cpu->cfg.ext_m) {
260
- target_misa |= RVM;
261
+ ext |= RVM;
262
}
263
if (cpu->cfg.ext_a) {
264
- target_misa |= RVA;
265
+ ext |= RVA;
266
}
267
if (cpu->cfg.ext_f) {
268
- target_misa |= RVF;
269
+ ext |= RVF;
270
}
271
if (cpu->cfg.ext_d) {
272
- target_misa |= RVD;
273
+ ext |= RVD;
274
}
275
if (cpu->cfg.ext_c) {
276
- target_misa |= RVC;
277
+ ext |= RVC;
278
}
279
if (cpu->cfg.ext_s) {
280
- target_misa |= RVS;
281
+ ext |= RVS;
282
}
283
if (cpu->cfg.ext_u) {
284
- target_misa |= RVU;
285
+ ext |= RVU;
286
}
287
if (cpu->cfg.ext_h) {
288
- target_misa |= RVH;
289
+ ext |= RVH;
290
}
291
if (cpu->cfg.ext_v) {
292
int vext_version = VEXT_VERSION_0_07_1;
293
- target_misa |= RVV;
294
+ ext |= RVV;
295
if (!is_power_of_2(cpu->cfg.vlen)) {
296
error_setg(errp,
297
"Vector extension VLEN must be power of 2");
298
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
299
set_vext_version(env, vext_version);
300
}
301
302
- set_misa(env, target_misa);
303
+ set_misa(env, env->misa_mxl, ext);
304
}
305
306
riscv_cpu_register_gdb_regs_for_features(cs);
307
@@ -XXX,XX +XXX,XX @@ char *riscv_isa_string(RISCVCPU *cpu)
308
char *isa_str = g_new(char, maxlen);
309
char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS);
310
for (i = 0; i < sizeof(riscv_exts); i++) {
311
- if (cpu->env.misa & RV(riscv_exts[i])) {
312
+ if (cpu->env.misa_ext & RV(riscv_exts[i])) {
313
*p++ = qemu_tolower(riscv_exts[i]);
314
}
315
}
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
316
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
12
index XXXXXXX..XXXXXXX 100644
317
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/csr.c
318
--- a/target/riscv/csr.c
14
+++ b/target/riscv/csr.c
319
+++ b/target/riscv/csr.c
15
@@ -XXX,XX +XXX,XX @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
320
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
16
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
321
{
17
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
322
#if !defined(CONFIG_USER_ONLY)
18
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
323
/* loose check condition for fcsr in vector extension */
19
-static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
324
- if ((csrno == CSR_FCSR) && (env->misa & RVV)) {
20
+static const target_ulong hip_writable_mask = MIP_VSSIP;
325
+ if ((csrno == CSR_FCSR) && (env->misa_ext & RVV)) {
21
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
326
return RISCV_EXCP_NONE;
22
static const target_ulong vsip_writable_mask = MIP_VSSIP;
327
}
23
328
if (!env->debugger && !riscv_cpu_fp_enabled(env)) {
24
static const char valid_vm_1_10_32[16] = {
329
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
25
@@ -XXX,XX +XXX,XX @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
330
26
target_ulong new_value, target_ulong write_mask)
331
static RISCVException vs(CPURISCVState *env, int csrno)
27
{
332
{
28
int ret = rmw_mip(env, 0, ret_value, new_value,
333
- if (env->misa & RVV) {
29
- write_mask & hip_writable_mask);
334
+ if (env->misa_ext & RVV) {
30
+ write_mask & hvip_writable_mask);
335
return RISCV_EXCP_NONE;
31
336
}
32
- *ret_value &= hip_writable_mask;
337
return RISCV_EXCP_ILLEGAL_INST;
33
+ *ret_value &= hvip_writable_mask;
338
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatush(CPURISCVState *env, int csrno,
34
339
static RISCVException read_misa(CPURISCVState *env, int csrno,
35
return ret;
340
target_ulong *val)
36
}
341
{
342
- *val = env->misa;
343
+ target_ulong misa;
344
+
345
+ switch (env->misa_mxl) {
346
+ case MXL_RV32:
347
+ misa = (target_ulong)MXL_RV32 << 30;
348
+ break;
349
+#ifdef TARGET_RISCV64
350
+ case MXL_RV64:
351
+ misa = (target_ulong)MXL_RV64 << 62;
352
+ break;
353
+#endif
354
+ default:
355
+ g_assert_not_reached();
356
+ }
357
+
358
+ *val = misa | env->misa_ext;
359
return RISCV_EXCP_NONE;
360
}
361
362
@@ -XXX,XX +XXX,XX @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
363
return RISCV_EXCP_NONE;
364
}
365
366
+ /*
367
+ * misa.MXL writes are not supported by QEMU.
368
+ * Drop writes to those bits.
369
+ */
370
+
371
/* Mask extensions that are not supported by this hart */
372
- val &= env->misa_mask;
373
+ val &= env->misa_ext_mask;
374
375
/* Mask extensions that are not supported by QEMU */
376
val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
377
@@ -XXX,XX +XXX,XX @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
378
val &= ~RVC;
379
}
380
381
- /* misa.MXL writes are not supported by QEMU */
382
- if (riscv_cpu_is_32bit(env)) {
383
- val = (env->misa & MISA32_MXL) | (val & ~MISA32_MXL);
384
- } else {
385
- val = (env->misa & MISA64_MXL) | (val & ~MISA64_MXL);
386
+ /* If nothing changed, do nothing. */
387
+ if (val == env->misa_ext) {
388
+ return RISCV_EXCP_NONE;
389
}
390
391
/* flush translation cache */
392
- if (val != env->misa) {
393
- tb_flush(env_cpu(env));
394
- }
395
-
396
- env->misa = val;
397
-
398
+ tb_flush(env_cpu(env));
399
+ env->misa_ext = val;
400
return RISCV_EXCP_NONE;
401
}
402
403
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
404
index XXXXXXX..XXXXXXX 100644
405
--- a/target/riscv/gdbstub.c
406
+++ b/target/riscv/gdbstub.c
407
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
408
static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
409
{
410
if (n < 32) {
411
- if (env->misa & RVD) {
412
+ if (env->misa_ext & RVD) {
413
return gdb_get_reg64(buf, env->fpr[n]);
414
}
415
- if (env->misa & RVF) {
416
+ if (env->misa_ext & RVF) {
417
return gdb_get_reg32(buf, env->fpr[n]);
418
}
419
/* there is hole between ft11 and fflags in fpu.xml */
420
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
421
{
422
RISCVCPU *cpu = RISCV_CPU(cs);
423
CPURISCVState *env = &cpu->env;
424
- if (env->misa & RVD) {
425
+ if (env->misa_ext & RVD) {
426
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
427
36, "riscv-64bit-fpu.xml", 0);
428
- } else if (env->misa & RVF) {
429
+ } else if (env->misa_ext & RVF) {
430
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
431
36, "riscv-32bit-fpu.xml", 0);
432
}
433
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
434
index XXXXXXX..XXXXXXX 100644
435
--- a/target/riscv/machine.c
436
+++ b/target/riscv/machine.c
437
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_hyper = {
438
439
const VMStateDescription vmstate_riscv_cpu = {
440
.name = "cpu",
441
- .version_id = 2,
442
- .minimum_version_id = 2,
443
+ .version_id = 3,
444
+ .minimum_version_id = 3,
445
.fields = (VMStateField[]) {
446
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
447
VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
448
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
449
VMSTATE_UINTTL(env.guest_phys_fault_addr, RISCVCPU),
450
VMSTATE_UINTTL(env.priv_ver, RISCVCPU),
451
VMSTATE_UINTTL(env.vext_ver, RISCVCPU),
452
- VMSTATE_UINTTL(env.misa, RISCVCPU),
453
- VMSTATE_UINTTL(env.misa_mask, RISCVCPU),
454
+ VMSTATE_UINT32(env.misa_mxl, RISCVCPU),
455
+ VMSTATE_UINT32(env.misa_ext, RISCVCPU),
456
+ VMSTATE_UINT32(env.misa_mxl_max, RISCVCPU),
457
+ VMSTATE_UINT32(env.misa_ext_mask, RISCVCPU),
458
VMSTATE_UINT32(env.features, RISCVCPU),
459
VMSTATE_UINTTL(env.priv, RISCVCPU),
460
VMSTATE_UINTTL(env.virt, RISCVCPU),
461
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
462
index XXXXXXX..XXXXXXX 100644
463
--- a/target/riscv/translate.c
464
+++ b/target/riscv/translate.c
465
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
466
/* pc_succ_insn points to the instruction following base.pc_next */
467
target_ulong pc_succ_insn;
468
target_ulong priv_ver;
469
- target_ulong misa;
470
+ RISCVMXL xl;
471
+ uint32_t misa_ext;
472
uint32_t opcode;
473
uint32_t mstatus_fs;
474
uint32_t mstatus_hs_fs;
475
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
476
477
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
478
{
479
- return ctx->misa & ext;
480
+ return ctx->misa_ext & ext;
481
}
482
483
#ifdef TARGET_RISCV32
484
@@ -XXX,XX +XXX,XX @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
485
#else
486
static inline bool is_32bit(DisasContext *ctx)
487
{
488
- return (ctx->misa & RV32) == RV32;
489
+ return ctx->xl == MXL_RV32;
490
}
491
#endif
492
493
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
494
#else
495
ctx->virt_enabled = false;
496
#endif
497
- ctx->misa = env->misa;
498
+ ctx->xl = env->misa_mxl;
499
+ ctx->misa_ext = env->misa_ext;
500
ctx->frm = -1; /* unknown rounding mode */
501
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
502
ctx->vlen = cpu->cfg.vlen;
37
--
503
--
38
2.30.1
504
2.31.1
39
505
40
506
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
According to the specification the "field SPVP of hstatus controls the
3
Shortly, the set of supported XL will not be just 32 and 64,
4
privilege level of the access" for the hypervisor virtual-machine load
4
and representing that properly using the enumeration will be
5
and store instructions HLV, HLVX and HSV.
5
imperative.
6
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
7
Two places, booting and gdb, intentionally use misa_mxl_max
8
to emphasize the use of the reset value of misa.mxl, and not
9
the current cpu state.
10
11
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103005.1400718-1-georg.kotheimer@kernkonzept.com
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20211020031709.359469-5-richard.henderson@linaro.org
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
16
---
12
target/riscv/cpu_helper.c | 25 ++++++++++++++-----------
17
target/riscv/cpu.h | 9 ++++++++-
13
1 file changed, 14 insertions(+), 11 deletions(-)
18
hw/riscv/boot.c | 2 +-
14
19
semihosting/arm-compat-semi.c | 2 +-
20
target/riscv/cpu.c | 24 ++++++++++++++----------
21
target/riscv/cpu_helper.c | 12 ++++++------
22
target/riscv/csr.c | 24 ++++++++++++------------
23
target/riscv/gdbstub.c | 2 +-
24
target/riscv/monitor.c | 4 ++--
25
8 files changed, 45 insertions(+), 34 deletions(-)
26
27
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/riscv/cpu.h
30
+++ b/target/riscv/cpu.h
31
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, VILL, 9, 1)
32
FIELD(TB_FLAGS, HLSX, 10, 1)
33
FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
34
35
-bool riscv_cpu_is_32bit(CPURISCVState *env);
36
+#ifdef TARGET_RISCV32
37
+#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
38
+#else
39
+static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
40
+{
41
+ return env->misa_mxl;
42
+}
43
+#endif
44
45
/*
46
* A simplification for VLMAX
47
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/hw/riscv/boot.c
50
+++ b/hw/riscv/boot.c
51
@@ -XXX,XX +XXX,XX @@
52
53
bool riscv_is_32bit(RISCVHartArrayState *harts)
54
{
55
- return riscv_cpu_is_32bit(&harts->harts[0].env);
56
+ return harts->harts[0].env.misa_mxl_max == MXL_RV32;
57
}
58
59
target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
60
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/semihosting/arm-compat-semi.c
63
+++ b/semihosting/arm-compat-semi.c
64
@@ -XXX,XX +XXX,XX @@ static inline bool is_64bit_semihosting(CPUArchState *env)
65
#if defined(TARGET_ARM)
66
return is_a64(env);
67
#elif defined(TARGET_RISCV)
68
- return !riscv_cpu_is_32bit(env);
69
+ return riscv_cpu_mxl(env) != MXL_RV32;
70
#else
71
#error un-handled architecture
72
#endif
73
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/riscv/cpu.c
76
+++ b/target/riscv/cpu.c
77
@@ -XXX,XX +XXX,XX @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
78
}
79
}
80
81
-bool riscv_cpu_is_32bit(CPURISCVState *env)
82
-{
83
- return env->misa_mxl == MXL_RV32;
84
-}
85
-
86
static void set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext)
87
{
88
env->misa_mxl_max = env->misa_mxl = mxl;
89
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
90
#ifndef CONFIG_USER_ONLY
91
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
92
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
93
- if (riscv_cpu_is_32bit(env)) {
94
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
95
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
96
(target_ulong)(env->mstatus >> 32));
97
}
98
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
99
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
100
{
101
RISCVCPU *cpu = RISCV_CPU(s);
102
- if (riscv_cpu_is_32bit(&cpu->env)) {
103
+
104
+ switch (riscv_cpu_mxl(&cpu->env)) {
105
+ case MXL_RV32:
106
info->print_insn = print_insn_riscv32;
107
- } else {
108
+ break;
109
+ case MXL_RV64:
110
info->print_insn = print_insn_riscv64;
111
+ break;
112
+ default:
113
+ g_assert_not_reached();
114
}
115
}
116
117
@@ -XXX,XX +XXX,XX @@ static gchar *riscv_gdb_arch_name(CPUState *cs)
118
RISCVCPU *cpu = RISCV_CPU(cs);
119
CPURISCVState *env = &cpu->env;
120
121
- if (riscv_cpu_is_32bit(env)) {
122
+ switch (riscv_cpu_mxl(env)) {
123
+ case MXL_RV32:
124
return g_strdup("riscv:rv32");
125
- } else {
126
+ case MXL_RV64:
127
return g_strdup("riscv:rv64");
128
+ default:
129
+ g_assert_not_reached();
130
}
131
}
132
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
133
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
134
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
135
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
136
+++ b/target/riscv/cpu_helper.c
137
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
138
139
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
140
{
141
- uint64_t sd = riscv_cpu_is_32bit(env) ? MSTATUS32_SD : MSTATUS64_SD;
142
+ uint64_t sd = riscv_cpu_mxl(env) == MXL_RV32 ? MSTATUS32_SD : MSTATUS64_SD;
143
uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
144
MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
145
MSTATUS64_UXL | sd;
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
146
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
use_background = true;
147
21
}
148
if (first_stage == true) {
22
149
if (use_background) {
23
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
150
- if (riscv_cpu_is_32bit(env)) {
24
+ /* MPRV does not affect the virtual-machine load/store
151
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
25
+ instructions, HLV, HLVX, and HSV. */
152
base = (hwaddr)get_field(env->vsatp, SATP32_PPN) << PGSHIFT;
26
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
153
vm = get_field(env->vsatp, SATP32_MODE);
27
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
154
} else {
28
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
155
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
29
if (get_field(env->mstatus, MSTATUS_MPRV)) {
156
vm = get_field(env->vsatp, SATP64_MODE);
30
mode = get_field(env->mstatus, MSTATUS_MPP);
157
}
158
} else {
159
- if (riscv_cpu_is_32bit(env)) {
160
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
161
base = (hwaddr)get_field(env->satp, SATP32_PPN) << PGSHIFT;
162
vm = get_field(env->satp, SATP32_MODE);
163
} else {
164
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
31
}
165
}
32
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
166
widened = 0;
33
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
167
} else {
34
__func__, address, access_type, mmu_idx);
168
- if (riscv_cpu_is_32bit(env)) {
35
169
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
36
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
170
base = (hwaddr)get_field(env->hgatp, SATP32_PPN) << PGSHIFT;
37
- if (get_field(env->mstatus, MSTATUS_MPRV)) {
171
vm = get_field(env->hgatp, SATP32_MODE);
38
- mode = get_field(env->mstatus, MSTATUS_MPP);
172
} else {
39
+ /* MPRV does not affect the virtual-machine load/store
173
@@ -XXX,XX +XXX,XX @@ restart:
40
+ instructions, HLV, HLVX, and HSV. */
41
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
42
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
43
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH &&
44
+ get_field(env->mstatus, MSTATUS_MPRV)) {
45
+ mode = get_field(env->mstatus, MSTATUS_MPP);
46
+ if (riscv_has_ext(env, RVH) && get_field(env->mstatus, MSTATUS_MPV)) {
47
+ two_stage_lookup = true;
48
}
174
}
49
}
175
50
176
target_ulong pte;
51
- if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
177
- if (riscv_cpu_is_32bit(env)) {
52
- access_type != MMU_INST_FETCH &&
178
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
53
- get_field(env->mstatus, MSTATUS_MPRV) &&
179
pte = address_space_ldl(cs->as, pte_addr, attrs, &res);
54
- get_field(env->mstatus, MSTATUS_MPV)) {
180
} else {
55
- two_stage_lookup = true;
181
pte = address_space_ldq(cs->as, pte_addr, attrs, &res);
56
- }
182
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
57
-
183
int page_fault_exceptions, vm;
58
if (riscv_cpu_virt_enabled(env) ||
184
uint64_t stap_mode;
59
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
185
60
access_type != MMU_INST_FETCH)) {
186
- if (riscv_cpu_is_32bit(env)) {
187
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
188
stap_mode = SATP32_MODE;
189
} else {
190
stap_mode = SATP64_MODE;
191
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
192
index XXXXXXX..XXXXXXX 100644
193
--- a/target/riscv/csr.c
194
+++ b/target/riscv/csr.c
195
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
196
}
197
break;
198
}
199
- if (riscv_cpu_is_32bit(env)) {
200
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
201
switch (csrno) {
202
case CSR_CYCLEH:
203
if (!get_field(env->hcounteren, COUNTEREN_CY) &&
204
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
205
206
static RISCVException ctr32(CPURISCVState *env, int csrno)
207
{
208
- if (!riscv_cpu_is_32bit(env)) {
209
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
210
return RISCV_EXCP_ILLEGAL_INST;
211
}
212
213
@@ -XXX,XX +XXX,XX @@ static RISCVException any(CPURISCVState *env, int csrno)
214
215
static RISCVException any32(CPURISCVState *env, int csrno)
216
{
217
- if (!riscv_cpu_is_32bit(env)) {
218
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
219
return RISCV_EXCP_ILLEGAL_INST;
220
}
221
222
@@ -XXX,XX +XXX,XX @@ static RISCVException hmode(CPURISCVState *env, int csrno)
223
224
static RISCVException hmode32(CPURISCVState *env, int csrno)
225
{
226
- if (!riscv_cpu_is_32bit(env)) {
227
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
228
if (riscv_cpu_virt_enabled(env)) {
229
return RISCV_EXCP_ILLEGAL_INST;
230
} else {
231
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mstatus(CPURISCVState *env, int csrno,
232
233
static int validate_vm(CPURISCVState *env, target_ulong vm)
234
{
235
- if (riscv_cpu_is_32bit(env)) {
236
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
237
return valid_vm_1_10_32[vm & 0xf];
238
} else {
239
return valid_vm_1_10_64[vm & 0xf];
240
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
241
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
242
MSTATUS_TW;
243
244
- if (!riscv_cpu_is_32bit(env)) {
245
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
246
/*
247
* RV32: MPV and GVA are not in mstatus. The current plan is to
248
* add them to mstatush. For now, we just don't support it.
249
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
250
251
dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
252
((mstatus & MSTATUS_XS) == MSTATUS_XS);
253
- if (riscv_cpu_is_32bit(env)) {
254
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
255
mstatus = set_field(mstatus, MSTATUS32_SD, dirty);
256
} else {
257
mstatus = set_field(mstatus, MSTATUS64_SD, dirty);
258
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
259
{
260
target_ulong mask = (sstatus_v1_10_mask);
261
262
- if (riscv_cpu_is_32bit(env)) {
263
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
264
mask |= SSTATUS32_SD;
265
} else {
266
mask |= SSTATUS64_SD;
267
@@ -XXX,XX +XXX,XX @@ static RISCVException write_satp(CPURISCVState *env, int csrno,
268
return RISCV_EXCP_NONE;
269
}
270
271
- if (riscv_cpu_is_32bit(env)) {
272
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
273
vm = validate_vm(env, get_field(val, SATP32_MODE));
274
mask = (val ^ env->satp) & (SATP32_MODE | SATP32_ASID | SATP32_PPN);
275
asid = (val ^ env->satp) & SATP32_ASID;
276
@@ -XXX,XX +XXX,XX @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
277
target_ulong *val)
278
{
279
*val = env->hstatus;
280
- if (!riscv_cpu_is_32bit(env)) {
281
+ if (riscv_cpu_mxl(env) != MXL_RV32) {
282
/* We only support 64-bit VSXL */
283
*val = set_field(*val, HSTATUS_VSXL, 2);
284
}
285
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstatus(CPURISCVState *env, int csrno,
286
target_ulong val)
287
{
288
env->hstatus = val;
289
- if (!riscv_cpu_is_32bit(env) && get_field(val, HSTATUS_VSXL) != 2) {
290
+ if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
291
qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
292
}
293
if (get_field(val, HSTATUS_VSBE) != 0) {
294
@@ -XXX,XX +XXX,XX @@ static RISCVException write_htimedelta(CPURISCVState *env, int csrno,
295
return RISCV_EXCP_ILLEGAL_INST;
296
}
297
298
- if (riscv_cpu_is_32bit(env)) {
299
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
300
env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
301
} else {
302
env->htimedelta = val;
303
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
304
index XXXXXXX..XXXXXXX 100644
305
--- a/target/riscv/gdbstub.c
306
+++ b/target/riscv/gdbstub.c
307
@@ -XXX,XX +XXX,XX @@ static int riscv_gen_dynamic_csr_xml(CPUState *cs, int base_reg)
308
CPURISCVState *env = &cpu->env;
309
GString *s = g_string_new(NULL);
310
riscv_csr_predicate_fn predicate;
311
- int bitsize = riscv_cpu_is_32bit(env) ? 32 : 64;
312
+ int bitsize = 16 << env->misa_mxl_max;
313
int i;
314
315
g_string_printf(s, "<?xml version=\"1.0\"?>");
316
diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c
317
index XXXXXXX..XXXXXXX 100644
318
--- a/target/riscv/monitor.c
319
+++ b/target/riscv/monitor.c
320
@@ -XXX,XX +XXX,XX @@ static void mem_info_svxx(Monitor *mon, CPUArchState *env)
321
target_ulong last_size;
322
int last_attr;
323
324
- if (riscv_cpu_is_32bit(env)) {
325
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
326
base = (hwaddr)get_field(env->satp, SATP32_PPN) << PGSHIFT;
327
vm = get_field(env->satp, SATP32_MODE);
328
} else {
329
@@ -XXX,XX +XXX,XX @@ void hmp_info_mem(Monitor *mon, const QDict *qdict)
330
return;
331
}
332
333
- if (riscv_cpu_is_32bit(env)) {
334
+ if (riscv_cpu_mxl(env) == MXL_RV32) {
335
if (!(env->satp & SATP32_MODE)) {
336
monitor_printf(mon, "No translation or protection\n");
337
return;
61
--
338
--
62
2.30.1
339
2.31.1
63
340
64
341
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The current two-stage lookup detection in riscv_cpu_do_interrupt falls
3
Begin adding support for switching XLEN at runtime. Extract the
4
short of its purpose, as all it checks is whether two-stage address
4
effective XLEN from MISA and MSTATUS and store for use during translation.
5
translation either via the hypervisor-load store instructions or the
6
MPRV feature would be allowed.
7
5
8
What we really need instead is whether two-stage address translation was
6
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
9
active when the exception was raised. However, in riscv_cpu_do_interrupt
10
we do not have the information to reliably detect this. Therefore, when
11
we raise a memory fault exception we have to record whether two-stage
12
address translation is active.
13
14
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20210319141459.1196741-1-georg.kotheimer@kernkonzept.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211020031709.359469-6-richard.henderson@linaro.org
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 | 4 ++++
12
target/riscv/cpu.h | 2 ++
20
target/riscv/cpu.c | 1 +
13
target/riscv/cpu.c | 8 ++++++++
21
target/riscv/cpu_helper.c | 21 ++++++++-------------
14
target/riscv/cpu_helper.c | 33 +++++++++++++++++++++++++++++++++
22
3 files changed, 13 insertions(+), 13 deletions(-)
15
target/riscv/csr.c | 3 +++
16
target/riscv/translate.c | 2 +-
17
5 files changed, 47 insertions(+), 1 deletion(-)
23
18
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
21
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
23
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, VILL, 9, 1)
29
target_ulong satp_hs;
24
/* Is a Hypervisor instruction load/store allowed? */
30
uint64_t mstatus_hs;
25
FIELD(TB_FLAGS, HLSX, 10, 1)
31
26
FIELD(TB_FLAGS, MSTATUS_HS_FS, 11, 2)
32
+ /* Signals whether the current exception occurred with two-stage address
27
+/* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
33
+ translation active. */
28
+FIELD(TB_FLAGS, XL, 13, 2)
34
+ bool two_stage_lookup;
29
35
+
30
#ifdef TARGET_RISCV32
36
target_ulong scounteren;
31
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
37
target_ulong mcounteren;
38
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
32
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/cpu.c
34
--- a/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
35
+++ b/target/riscv/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
36
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
37
env->misa_mxl = env->misa_mxl_max;
38
env->priv = PRV_M;
44
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
39
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
40
+ if (env->misa_mxl > MXL_RV32) {
41
+ /*
42
+ * The reset status of SXL/UXL is undefined, but mstatus is WARL
43
+ * and we must ensure that the value after init is valid for read.
44
+ */
45
+ env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl);
46
+ env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl);
47
+ }
45
env->mcause = 0;
48
env->mcause = 0;
46
env->pc = env->resetvec;
49
env->pc = env->resetvec;
47
+ env->two_stage_lookup = false;
50
env->two_stage_lookup = false;
48
#endif
49
cs->exception_index = EXCP_NONE;
50
env->load_res = -1;
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
52
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu_helper.c
53
--- a/target/riscv/cpu_helper.c
54
+++ b/target/riscv/cpu_helper.c
54
+++ b/target/riscv/cpu_helper.c
55
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
55
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
56
g_assert_not_reached();
56
#endif
57
}
58
59
+static RISCVMXL cpu_get_xl(CPURISCVState *env)
60
+{
61
+#if defined(TARGET_RISCV32)
62
+ return MXL_RV32;
63
+#elif defined(CONFIG_USER_ONLY)
64
+ return MXL_RV64;
65
+#else
66
+ RISCVMXL xl = riscv_cpu_mxl(env);
67
+
68
+ /*
69
+ * When emulating a 32-bit-only cpu, use RV32.
70
+ * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
71
+ * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
72
+ * back to RV64 for lower privs.
73
+ */
74
+ if (xl != MXL_RV32) {
75
+ switch (env->priv) {
76
+ case PRV_M:
77
+ break;
78
+ case PRV_U:
79
+ xl = get_field(env->mstatus, MSTATUS64_UXL);
80
+ break;
81
+ default: /* PRV_S | PRV_H */
82
+ xl = get_field(env->mstatus, MSTATUS64_SXL);
83
+ break;
84
+ }
85
+ }
86
+ return xl;
87
+#endif
88
+}
89
+
90
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
91
target_ulong *cs_base, uint32_t *pflags)
92
{
93
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
57
}
94
}
58
env->badaddr = address;
95
#endif
59
+ env->two_stage_lookup = two_stage;
96
97
+ flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
98
+
99
*pflags = flags;
60
}
100
}
61
101
62
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
102
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/riscv/csr.c
105
+++ b/target/riscv/csr.c
106
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
107
mstatus = set_field(mstatus, MSTATUS32_SD, dirty);
108
} else {
109
mstatus = set_field(mstatus, MSTATUS64_SD, dirty);
110
+ /* SXL and UXL fields are for now read only */
111
+ mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
112
+ mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
64
}
113
}
65
114
env->mstatus = mstatus;
66
env->badaddr = addr;
115
67
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
116
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
68
+ riscv_cpu_two_stage_lookup(mmu_idx);
117
index XXXXXXX..XXXXXXX 100644
69
riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
118
--- a/target/riscv/translate.c
70
}
119
+++ b/target/riscv/translate.c
71
120
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
72
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
121
#else
73
g_assert_not_reached();
122
ctx->virt_enabled = false;
74
}
75
env->badaddr = addr;
76
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
77
+ riscv_cpu_two_stage_lookup(mmu_idx);
78
riscv_raise_exception(env, cs->exception_index, retaddr);
79
}
80
#endif /* !CONFIG_USER_ONLY */
81
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
82
/* handle the trap in S-mode */
83
if (riscv_has_ext(env, RVH)) {
84
target_ulong hdeleg = async ? env->hideleg : env->hedeleg;
85
- bool two_stage_lookup = false;
86
87
- if (env->priv == PRV_M ||
88
- (env->priv == PRV_S && !riscv_cpu_virt_enabled(env)) ||
89
- (env->priv == PRV_U && !riscv_cpu_virt_enabled(env) &&
90
- get_field(env->hstatus, HSTATUS_HU))) {
91
- two_stage_lookup = true;
92
- }
93
-
94
- if ((riscv_cpu_virt_enabled(env) || two_stage_lookup) && write_tval) {
95
+ if (env->two_stage_lookup && write_tval) {
96
/*
97
* If we are writing a guest virtual address to stval, set
98
* this to 1. If we are trapping to VS we will set this to 0
99
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
100
riscv_cpu_set_force_hs_excep(env, 0);
101
} else {
102
/* Trap into HS mode */
103
- if (!two_stage_lookup) {
104
- env->hstatus = set_field(env->hstatus, HSTATUS_SPV,
105
- riscv_cpu_virt_enabled(env));
106
- }
107
+ env->hstatus = set_field(env->hstatus, HSTATUS_SPV, false);
108
htval = env->guest_phys_fault_addr;
109
}
110
}
111
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs)
112
* RISC-V ISA Specification.
113
*/
114
115
+ env->two_stage_lookup = false;
116
#endif
123
#endif
117
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
124
- ctx->xl = env->misa_mxl;
118
}
125
ctx->misa_ext = env->misa_ext;
126
ctx->frm = -1; /* unknown rounding mode */
127
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
128
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
129
ctx->lmul = FIELD_EX32(tb_flags, TB_FLAGS, LMUL);
130
ctx->mlen = 1 << (ctx->sew + 3 - ctx->lmul);
131
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
132
+ ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
133
ctx->cs = cs;
134
ctx->w = false;
135
ctx->ntemp = 0;
119
--
136
--
120
2.30.1
137
2.31.1
121
138
122
139
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Use the same REQUIRE_64BIT check that we use elsewhere,
4
rather than open-coding the use of is_32bit.
5
6
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211020031709.359469-7-richard.henderson@linaro.org
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 3 ++-
13
1 file changed, 2 insertions(+), 1 deletion(-)
14
15
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static bool amo_check(DisasContext *s, arg_rwdvm* a)
20
21
static bool amo_check64(DisasContext *s, arg_rwdvm* a)
22
{
23
- return !is_32bit(s) && amo_check(s, a);
24
+ REQUIRE_64BIT(s);
25
+ return amo_check(s, a);
26
}
27
28
GEN_VEXT_TRANS(vamoswapw_v, 0, rwdvm, amo_op, amo_check)
29
--
30
2.31.1
31
32
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The current condition for the use of background registers only
3
We're currently assuming SEW <= 3, and the "else" from
4
considers the hypervisor load and store instructions,
4
the SEW == 3 must be less. Use a switch and explicitly
5
but not accesses from M mode via MSTATUS_MPRV+MPV.
5
bound both SEW and SEQ for all cases.
6
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
7
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103036.1401073-1-georg.kotheimer@kernkonzept.com
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20211020031709.359469-8-richard.henderson@linaro.org
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/cpu_helper.c | 2 +-
13
target/riscv/insn_trans/trans_rvv.c.inc | 26 +++++++++++++------------
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 14 insertions(+), 12 deletions(-)
14
15
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
18
+++ b/target/riscv/cpu_helper.c
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
@@ -XXX,XX +XXX,XX @@ static bool amo_op(DisasContext *s, arg_rwdvm *a, uint8_t seq)
20
* was called. Background registers will be used if the guest has
21
gen_helper_exit_atomic(cpu_env);
21
* forced a two stage translation to be on (in HS or M mode).
22
s->base.is_jmp = DISAS_NORETURN;
22
*/
23
return true;
23
- if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
24
- } else {
24
+ if (!riscv_cpu_virt_enabled(env) && two_stage) {
25
- if (s->sew == 3) {
25
use_background = true;
26
- if (!is_32bit(s)) {
27
- fn = fnsd[seq];
28
- } else {
29
- /* Check done in amo_check(). */
30
- g_assert_not_reached();
31
- }
32
- } else {
33
- assert(seq < ARRAY_SIZE(fnsw));
34
- fn = fnsw[seq];
35
- }
36
+ }
37
+
38
+ switch (s->sew) {
39
+ case 0 ... 2:
40
+ assert(seq < ARRAY_SIZE(fnsw));
41
+ fn = fnsw[seq];
42
+ break;
43
+ case 3:
44
+ /* XLEN check done in amo_check(). */
45
+ assert(seq < ARRAY_SIZE(fnsd));
46
+ fn = fnsd[seq];
47
+ break;
48
+ default:
49
+ g_assert_not_reached();
26
}
50
}
27
51
52
data = FIELD_DP32(data, VDATA, MLEN, s->mlen);
28
--
53
--
29
2.30.1
54
2.31.1
30
55
31
56
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
In preparation for RV128, replace a simple predicate
4
with a more versatile test.
5
6
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211020031709.359469-9-richard.henderson@linaro.org
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/translate.c | 31 +++++++++++++++++--------------
13
1 file changed, 17 insertions(+), 14 deletions(-)
14
15
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/translate.c
18
+++ b/target/riscv/translate.c
19
@@ -XXX,XX +XXX,XX @@ static inline bool has_ext(DisasContext *ctx, uint32_t ext)
20
}
21
22
#ifdef TARGET_RISCV32
23
-# define is_32bit(ctx) true
24
+#define get_xl(ctx) MXL_RV32
25
#elif defined(CONFIG_USER_ONLY)
26
-# define is_32bit(ctx) false
27
+#define get_xl(ctx) MXL_RV64
28
#else
29
-static inline bool is_32bit(DisasContext *ctx)
30
+#define get_xl(ctx) ((ctx)->xl)
31
+#endif
32
+
33
+/* The word size for this machine mode. */
34
+static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
35
{
36
- return ctx->xl == MXL_RV32;
37
+ return 16 << get_xl(ctx);
38
}
39
-#endif
40
41
/* The word size for this operation. */
42
static inline int oper_len(DisasContext *ctx)
43
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
44
static void mark_fs_dirty(DisasContext *ctx)
45
{
46
TCGv tmp;
47
- target_ulong sd = is_32bit(ctx) ? MSTATUS32_SD : MSTATUS64_SD;
48
+ target_ulong sd = get_xl(ctx) == MXL_RV32 ? MSTATUS32_SD : MSTATUS64_SD;
49
50
if (ctx->mstatus_fs != MSTATUS_FS) {
51
/* Remember the state change for the rest of the TB. */
52
@@ -XXX,XX +XXX,XX @@ EX_SH(12)
53
} \
54
} while (0)
55
56
-#define REQUIRE_32BIT(ctx) do { \
57
- if (!is_32bit(ctx)) { \
58
- return false; \
59
- } \
60
+#define REQUIRE_32BIT(ctx) do { \
61
+ if (get_xl(ctx) != MXL_RV32) { \
62
+ return false; \
63
+ } \
64
} while (0)
65
66
-#define REQUIRE_64BIT(ctx) do { \
67
- if (is_32bit(ctx)) { \
68
- return false; \
69
- } \
70
+#define REQUIRE_64BIT(ctx) do { \
71
+ if (get_xl(ctx) < MXL_RV64) { \
72
+ return false; \
73
+ } \
74
} while (0)
75
76
static int ex_rvc_register(DisasContext *ctx, int reg)
77
--
78
2.31.1
79
80
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
In preparation for RV128, consider more than just "w" for
4
operand size modification. This will be used for the "d"
5
insns from RV128 as well.
6
7
Rename oper_len to get_olen to better match get_xlen.
8
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20211020031709.359469-10-richard.henderson@linaro.org
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/translate.c | 69 ++++++++++++++++---------
16
target/riscv/insn_trans/trans_rvb.c.inc | 8 +--
17
target/riscv/insn_trans/trans_rvi.c.inc | 18 +++----
18
target/riscv/insn_trans/trans_rvm.c.inc | 10 ++--
19
4 files changed, 62 insertions(+), 43 deletions(-)
20
21
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/translate.c
24
+++ b/target/riscv/translate.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
26
to any system register, which includes CSR_FRM, so we do not have
27
to reset this known value. */
28
int frm;
29
- bool w;
30
+ RISCVMXL ol;
31
bool virt_enabled;
32
bool ext_ifencei;
33
bool hlsx;
34
@@ -XXX,XX +XXX,XX @@ static inline int __attribute__((unused)) get_xlen(DisasContext *ctx)
35
return 16 << get_xl(ctx);
36
}
37
38
-/* The word size for this operation. */
39
-static inline int oper_len(DisasContext *ctx)
40
+/* The operation length, as opposed to the xlen. */
41
+#ifdef TARGET_RISCV32
42
+#define get_ol(ctx) MXL_RV32
43
+#else
44
+#define get_ol(ctx) ((ctx)->ol)
45
+#endif
46
+
47
+static inline int get_olen(DisasContext *ctx)
48
{
49
- return ctx->w ? 32 : TARGET_LONG_BITS;
50
+ return 16 << get_ol(ctx);
51
}
52
53
-
54
/*
55
* RISC-V requires NaN-boxing of narrower width floating point values.
56
* This applies when a 32-bit value is assigned to a 64-bit FP register.
57
@@ -XXX,XX +XXX,XX @@ static TCGv get_gpr(DisasContext *ctx, int reg_num, DisasExtend ext)
58
return ctx->zero;
59
}
60
61
- switch (ctx->w ? ext : EXT_NONE) {
62
- case EXT_NONE:
63
- return cpu_gpr[reg_num];
64
- case EXT_SIGN:
65
- t = temp_new(ctx);
66
- tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
67
- return t;
68
- case EXT_ZERO:
69
- t = temp_new(ctx);
70
- tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
71
- return t;
72
+ switch (get_ol(ctx)) {
73
+ case MXL_RV32:
74
+ switch (ext) {
75
+ case EXT_NONE:
76
+ break;
77
+ case EXT_SIGN:
78
+ t = temp_new(ctx);
79
+ tcg_gen_ext32s_tl(t, cpu_gpr[reg_num]);
80
+ return t;
81
+ case EXT_ZERO:
82
+ t = temp_new(ctx);
83
+ tcg_gen_ext32u_tl(t, cpu_gpr[reg_num]);
84
+ return t;
85
+ default:
86
+ g_assert_not_reached();
87
+ }
88
+ break;
89
+ case MXL_RV64:
90
+ break;
91
+ default:
92
+ g_assert_not_reached();
93
}
94
- g_assert_not_reached();
95
+ return cpu_gpr[reg_num];
96
}
97
98
static TCGv dest_gpr(DisasContext *ctx, int reg_num)
99
{
100
- if (reg_num == 0 || ctx->w) {
101
+ if (reg_num == 0 || get_olen(ctx) < TARGET_LONG_BITS) {
102
return temp_new(ctx);
103
}
104
return cpu_gpr[reg_num];
105
@@ -XXX,XX +XXX,XX @@ static TCGv dest_gpr(DisasContext *ctx, int reg_num)
106
static void gen_set_gpr(DisasContext *ctx, int reg_num, TCGv t)
107
{
108
if (reg_num != 0) {
109
- if (ctx->w) {
110
+ switch (get_ol(ctx)) {
111
+ case MXL_RV32:
112
tcg_gen_ext32s_tl(cpu_gpr[reg_num], t);
113
- } else {
114
+ break;
115
+ case MXL_RV64:
116
tcg_gen_mov_tl(cpu_gpr[reg_num], t);
117
+ break;
118
+ default:
119
+ g_assert_not_reached();
120
}
121
}
122
}
123
@@ -XXX,XX +XXX,XX @@ static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
124
void (*func)(TCGv, TCGv, target_long))
125
{
126
TCGv dest, src1;
127
- int max_len = oper_len(ctx);
128
+ int max_len = get_olen(ctx);
129
130
if (a->shamt >= max_len) {
131
return false;
132
@@ -XXX,XX +XXX,XX @@ static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext,
133
void (*func)(TCGv, TCGv, TCGv))
134
{
135
TCGv dest, src1, src2;
136
- int max_len = oper_len(ctx);
137
+ int max_len = get_olen(ctx);
138
139
if (a->shamt >= max_len) {
140
return false;
141
@@ -XXX,XX +XXX,XX @@ static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext,
142
TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
143
TCGv ext2 = tcg_temp_new();
144
145
- tcg_gen_andi_tl(ext2, src2, oper_len(ctx) - 1);
146
+ tcg_gen_andi_tl(ext2, src2, get_olen(ctx) - 1);
147
func(dest, src1, ext2);
148
149
gen_set_gpr(ctx, a->rd, dest);
150
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
151
ctx->vl_eq_vlmax = FIELD_EX32(tb_flags, TB_FLAGS, VL_EQ_VLMAX);
152
ctx->xl = FIELD_EX32(tb_flags, TB_FLAGS, XL);
153
ctx->cs = cs;
154
- ctx->w = false;
155
ctx->ntemp = 0;
156
memset(ctx->temp, 0, sizeof(ctx->temp));
157
158
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
159
CPURISCVState *env = cpu->env_ptr;
160
uint16_t opcode16 = translator_lduw(env, &ctx->base, ctx->base.pc_next);
161
162
+ ctx->ol = ctx->xl;
163
decode_opc(env, ctx, opcode16);
164
ctx->base.pc_next = ctx->pc_succ_insn;
165
- ctx->w = false;
166
167
for (int i = ctx->ntemp - 1; i >= 0; --i) {
168
tcg_temp_free(ctx->temp[i]);
169
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
170
index XXXXXXX..XXXXXXX 100644
171
--- a/target/riscv/insn_trans/trans_rvb.c.inc
172
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
173
@@ -XXX,XX +XXX,XX @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
174
{
175
REQUIRE_64BIT(ctx);
176
REQUIRE_ZBB(ctx);
177
- ctx->w = true;
178
+ ctx->ol = MXL_RV32;
179
return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
180
}
181
182
@@ -XXX,XX +XXX,XX @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
183
{
184
REQUIRE_64BIT(ctx);
185
REQUIRE_ZBB(ctx);
186
- ctx->w = true;
187
+ ctx->ol = MXL_RV32;
188
return gen_shift(ctx, a, EXT_NONE, gen_rorw);
189
}
190
191
@@ -XXX,XX +XXX,XX @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
192
{
193
REQUIRE_64BIT(ctx);
194
REQUIRE_ZBB(ctx);
195
- ctx->w = true;
196
+ ctx->ol = MXL_RV32;
197
return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_rorw);
198
}
199
200
@@ -XXX,XX +XXX,XX @@ static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
201
{
202
REQUIRE_64BIT(ctx);
203
REQUIRE_ZBB(ctx);
204
- ctx->w = true;
205
+ ctx->ol = MXL_RV32;
206
return gen_shift(ctx, a, EXT_NONE, gen_rolw);
207
}
208
209
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
210
index XXXXXXX..XXXXXXX 100644
211
--- a/target/riscv/insn_trans/trans_rvi.c.inc
212
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
213
@@ -XXX,XX +XXX,XX @@ static bool trans_and(DisasContext *ctx, arg_and *a)
214
static bool trans_addiw(DisasContext *ctx, arg_addiw *a)
215
{
216
REQUIRE_64BIT(ctx);
217
- ctx->w = true;
218
+ ctx->ol = MXL_RV32;
219
return gen_arith_imm_fn(ctx, a, EXT_NONE, tcg_gen_addi_tl);
220
}
221
222
static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
223
{
224
REQUIRE_64BIT(ctx);
225
- ctx->w = true;
226
+ ctx->ol = MXL_RV32;
227
return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl);
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static void gen_srliw(TCGv dst, TCGv src, target_long shamt)
231
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
232
{
233
REQUIRE_64BIT(ctx);
234
- ctx->w = true;
235
+ ctx->ol = MXL_RV32;
236
return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_srliw);
237
}
238
239
@@ -XXX,XX +XXX,XX @@ static void gen_sraiw(TCGv dst, TCGv src, target_long shamt)
240
static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
241
{
242
REQUIRE_64BIT(ctx);
243
- ctx->w = true;
244
+ ctx->ol = MXL_RV32;
245
return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_sraiw);
246
}
247
248
static bool trans_addw(DisasContext *ctx, arg_addw *a)
249
{
250
REQUIRE_64BIT(ctx);
251
- ctx->w = true;
252
+ ctx->ol = MXL_RV32;
253
return gen_arith(ctx, a, EXT_NONE, tcg_gen_add_tl);
254
}
255
256
static bool trans_subw(DisasContext *ctx, arg_subw *a)
257
{
258
REQUIRE_64BIT(ctx);
259
- ctx->w = true;
260
+ ctx->ol = MXL_RV32;
261
return gen_arith(ctx, a, EXT_NONE, tcg_gen_sub_tl);
262
}
263
264
static bool trans_sllw(DisasContext *ctx, arg_sllw *a)
265
{
266
REQUIRE_64BIT(ctx);
267
- ctx->w = true;
268
+ ctx->ol = MXL_RV32;
269
return gen_shift(ctx, a, EXT_NONE, tcg_gen_shl_tl);
270
}
271
272
static bool trans_srlw(DisasContext *ctx, arg_srlw *a)
273
{
274
REQUIRE_64BIT(ctx);
275
- ctx->w = true;
276
+ ctx->ol = MXL_RV32;
277
return gen_shift(ctx, a, EXT_ZERO, tcg_gen_shr_tl);
278
}
279
280
static bool trans_sraw(DisasContext *ctx, arg_sraw *a)
281
{
282
REQUIRE_64BIT(ctx);
283
- ctx->w = true;
284
+ ctx->ol = MXL_RV32;
285
return gen_shift(ctx, a, EXT_SIGN, tcg_gen_sar_tl);
286
}
287
288
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
289
index XXXXXXX..XXXXXXX 100644
290
--- a/target/riscv/insn_trans/trans_rvm.c.inc
291
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
292
@@ -XXX,XX +XXX,XX @@ static bool trans_mulw(DisasContext *ctx, arg_mulw *a)
293
{
294
REQUIRE_64BIT(ctx);
295
REQUIRE_EXT(ctx, RVM);
296
- ctx->w = true;
297
+ ctx->ol = MXL_RV32;
298
return gen_arith(ctx, a, EXT_NONE, tcg_gen_mul_tl);
299
}
300
301
@@ -XXX,XX +XXX,XX @@ static bool trans_divw(DisasContext *ctx, arg_divw *a)
302
{
303
REQUIRE_64BIT(ctx);
304
REQUIRE_EXT(ctx, RVM);
305
- ctx->w = true;
306
+ ctx->ol = MXL_RV32;
307
return gen_arith(ctx, a, EXT_SIGN, gen_div);
308
}
309
310
@@ -XXX,XX +XXX,XX @@ static bool trans_divuw(DisasContext *ctx, arg_divuw *a)
311
{
312
REQUIRE_64BIT(ctx);
313
REQUIRE_EXT(ctx, RVM);
314
- ctx->w = true;
315
+ ctx->ol = MXL_RV32;
316
return gen_arith(ctx, a, EXT_ZERO, gen_divu);
317
}
318
319
@@ -XXX,XX +XXX,XX @@ static bool trans_remw(DisasContext *ctx, arg_remw *a)
320
{
321
REQUIRE_64BIT(ctx);
322
REQUIRE_EXT(ctx, RVM);
323
- ctx->w = true;
324
+ ctx->ol = MXL_RV32;
325
return gen_arith(ctx, a, EXT_SIGN, gen_rem);
326
}
327
328
@@ -XXX,XX +XXX,XX @@ static bool trans_remuw(DisasContext *ctx, arg_remuw *a)
329
{
330
REQUIRE_64BIT(ctx);
331
REQUIRE_EXT(ctx, RVM);
332
- ctx->w = true;
333
+ ctx->ol = MXL_RV32;
334
return gen_arith(ctx, a, EXT_ZERO, gen_remu);
335
}
336
--
337
2.31.1
338
339
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
When decode_insn16() fails, we fall back to decode_RV32_64C() for
3
The multiply high-part instructions require a separate
4
further compressed instruction decoding. However, prior to this change,
4
implementation for RV32 when TARGET_LONG_BITS == 64.
5
we did not raise an illegal instruction exception, if decode_RV32_64C()
6
fails to decode the instruction. This means that we skipped illegal
7
compressed instructions instead of raising an illegal instruction
8
exception.
9
5
10
Instead of patching decode_RV32_64C(), we can just remove it,
6
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
11
as it is dead code since f330433b363 anyway.
12
13
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20210322121609.3097928-1-georg.kotheimer@kernkonzept.com
9
Message-id: 20211020031709.359469-11-richard.henderson@linaro.org
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/translate.c | 179 +--------------------------------------
12
target/riscv/translate.c | 16 +++++++++++++++
20
1 file changed, 1 insertion(+), 178 deletions(-)
13
target/riscv/insn_trans/trans_rvm.c.inc | 26 ++++++++++++++++++++++---
14
2 files changed, 39 insertions(+), 3 deletions(-)
21
15
22
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
16
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
23
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/translate.c
18
--- a/target/riscv/translate.c
25
+++ b/target/riscv/translate.c
19
+++ b/target/riscv/translate.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
20
@@ -XXX,XX +XXX,XX @@ static bool gen_arith(DisasContext *ctx, arg_r *a, DisasExtend ext,
27
CPUState *cs;
21
return true;
28
} DisasContext;
29
30
-#ifdef TARGET_RISCV64
31
-/* convert riscv funct3 to qemu memop for load/store */
32
-static const int tcg_memop_lookup[8] = {
33
- [0 ... 7] = -1,
34
- [0] = MO_SB,
35
- [1] = MO_TESW,
36
- [2] = MO_TESL,
37
- [3] = MO_TEQ,
38
- [4] = MO_UB,
39
- [5] = MO_TEUW,
40
- [6] = MO_TEUL,
41
-};
42
-#endif
43
-
44
#ifdef TARGET_RISCV64
45
#define CASE_OP_32_64(X) case X: case glue(X, W)
46
#else
47
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
48
ctx->base.is_jmp = DISAS_NORETURN;
49
}
22
}
50
23
51
-#ifdef TARGET_RISCV64
24
+static bool gen_arith_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext,
52
-static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
25
+ void (*f_tl)(TCGv, TCGv, TCGv),
53
- target_long imm)
26
+ void (*f_32)(TCGv, TCGv, TCGv))
54
-{
27
+{
55
- TCGv t0 = tcg_temp_new();
28
+ int olen = get_olen(ctx);
56
- TCGv t1 = tcg_temp_new();
29
+
57
- gen_get_gpr(t0, rs1);
30
+ if (olen != TARGET_LONG_BITS) {
58
- tcg_gen_addi_tl(t0, t0, imm);
31
+ if (olen == 32) {
59
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
32
+ f_tl = f_32;
60
-
33
+ } else {
61
- if (memop < 0) {
34
+ g_assert_not_reached();
62
- gen_exception_illegal(ctx);
35
+ }
63
- return;
36
+ }
64
- }
37
+ return gen_arith(ctx, a, ext, f_tl);
65
-
38
+}
66
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
39
+
67
- gen_set_gpr(rd, t1);
40
static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
68
- tcg_temp_free(t0);
41
void (*func)(TCGv, TCGv, target_long))
69
- tcg_temp_free(t1);
70
-}
71
-
72
-static void gen_store_c(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
73
- target_long imm)
74
-{
75
- TCGv t0 = tcg_temp_new();
76
- TCGv dat = tcg_temp_new();
77
- gen_get_gpr(t0, rs1);
78
- tcg_gen_addi_tl(t0, t0, imm);
79
- gen_get_gpr(dat, rs2);
80
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
81
-
82
- if (memop < 0) {
83
- gen_exception_illegal(ctx);
84
- return;
85
- }
86
-
87
- tcg_gen_qemu_st_tl(dat, t0, ctx->mem_idx, memop);
88
- tcg_temp_free(t0);
89
- tcg_temp_free(dat);
90
-}
91
-#endif
92
-
93
#ifndef CONFIG_USER_ONLY
94
/* The states of mstatus_fs are:
95
* 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
96
@@ -XXX,XX +XXX,XX @@ static void mark_fs_dirty(DisasContext *ctx)
97
static inline void mark_fs_dirty(DisasContext *ctx) { }
98
#endif
99
100
-#if !defined(TARGET_RISCV64)
101
-static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
102
- int rs1, target_long imm)
103
-{
104
- TCGv t0;
105
-
106
- if (ctx->mstatus_fs == 0) {
107
- gen_exception_illegal(ctx);
108
- return;
109
- }
110
-
111
- t0 = tcg_temp_new();
112
- gen_get_gpr(t0, rs1);
113
- tcg_gen_addi_tl(t0, t0, imm);
114
-
115
- switch (opc) {
116
- case OPC_RISC_FLW:
117
- if (!has_ext(ctx, RVF)) {
118
- goto do_illegal;
119
- }
120
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
121
- /* RISC-V requires NaN-boxing of narrower width floating point values */
122
- tcg_gen_ori_i64(cpu_fpr[rd], cpu_fpr[rd], 0xffffffff00000000ULL);
123
- break;
124
- case OPC_RISC_FLD:
125
- if (!has_ext(ctx, RVD)) {
126
- goto do_illegal;
127
- }
128
- tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
129
- break;
130
- do_illegal:
131
- default:
132
- gen_exception_illegal(ctx);
133
- break;
134
- }
135
- tcg_temp_free(t0);
136
-
137
- mark_fs_dirty(ctx);
138
-}
139
-
140
-static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
141
- int rs2, target_long imm)
142
-{
143
- TCGv t0;
144
-
145
- if (ctx->mstatus_fs == 0) {
146
- gen_exception_illegal(ctx);
147
- return;
148
- }
149
-
150
- t0 = tcg_temp_new();
151
- gen_get_gpr(t0, rs1);
152
- tcg_gen_addi_tl(t0, t0, imm);
153
-
154
- switch (opc) {
155
- case OPC_RISC_FSW:
156
- if (!has_ext(ctx, RVF)) {
157
- goto do_illegal;
158
- }
159
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEUL);
160
- break;
161
- case OPC_RISC_FSD:
162
- if (!has_ext(ctx, RVD)) {
163
- goto do_illegal;
164
- }
165
- tcg_gen_qemu_st_i64(cpu_fpr[rs2], t0, ctx->mem_idx, MO_TEQ);
166
- break;
167
- do_illegal:
168
- default:
169
- gen_exception_illegal(ctx);
170
- break;
171
- }
172
-
173
- tcg_temp_free(t0);
174
-}
175
-#endif
176
-
177
static void gen_set_rm(DisasContext *ctx, int rm)
178
{
42
{
179
TCGv_i32 t0;
43
diff --git a/target/riscv/insn_trans/trans_rvm.c.inc b/target/riscv/insn_trans/trans_rvm.c.inc
180
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
44
index XXXXXXX..XXXXXXX 100644
181
tcg_temp_free_i32(t0);
45
--- a/target/riscv/insn_trans/trans_rvm.c.inc
46
+++ b/target/riscv/insn_trans/trans_rvm.c.inc
47
@@ -XXX,XX +XXX,XX @@ static void gen_mulh(TCGv ret, TCGv s1, TCGv s2)
48
tcg_temp_free(discard);
182
}
49
}
183
50
184
-static void decode_RV32_64C0(DisasContext *ctx, uint16_t opcode)
51
+static void gen_mulh_w(TCGv ret, TCGv s1, TCGv s2)
185
-{
52
+{
186
- uint8_t funct3 = extract16(opcode, 13, 3);
53
+ tcg_gen_mul_tl(ret, s1, s2);
187
- uint8_t rd_rs2 = GET_C_RS2S(opcode);
54
+ tcg_gen_sari_tl(ret, ret, 32);
188
- uint8_t rs1s = GET_C_RS1S(opcode);
55
+}
189
-
56
+
190
- switch (funct3) {
57
static bool trans_mulh(DisasContext *ctx, arg_mulh *a)
191
- case 3:
192
-#if defined(TARGET_RISCV64)
193
- /* C.LD(RV64/128) -> ld rd', offset[7:3](rs1')*/
194
- gen_load_c(ctx, OPC_RISC_LD, rd_rs2, rs1s,
195
- GET_C_LD_IMM(opcode));
196
-#else
197
- /* C.FLW (RV32) -> flw rd', offset[6:2](rs1')*/
198
- gen_fp_load(ctx, OPC_RISC_FLW, rd_rs2, rs1s,
199
- GET_C_LW_IMM(opcode));
200
-#endif
201
- break;
202
- case 7:
203
-#if defined(TARGET_RISCV64)
204
- /* C.SD (RV64/128) -> sd rs2', offset[7:3](rs1')*/
205
- gen_store_c(ctx, OPC_RISC_SD, rs1s, rd_rs2,
206
- GET_C_LD_IMM(opcode));
207
-#else
208
- /* C.FSW (RV32) -> fsw rs2', offset[6:2](rs1')*/
209
- gen_fp_store(ctx, OPC_RISC_FSW, rs1s, rd_rs2,
210
- GET_C_LW_IMM(opcode));
211
-#endif
212
- break;
213
- }
214
-}
215
-
216
-static void decode_RV32_64C(DisasContext *ctx, uint16_t opcode)
217
-{
218
- uint8_t op = extract16(opcode, 0, 2);
219
-
220
- switch (op) {
221
- case 0:
222
- decode_RV32_64C0(ctx, opcode);
223
- break;
224
- }
225
-}
226
-
227
static int ex_plus_1(DisasContext *ctx, int nf)
228
{
58
{
229
return nf + 1;
59
REQUIRE_EXT(ctx, RVM);
230
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
60
- return gen_arith(ctx, a, EXT_NONE, gen_mulh);
231
} else {
61
+ return gen_arith_per_ol(ctx, a, EXT_SIGN, gen_mulh, gen_mulh_w);
232
ctx->pc_succ_insn = ctx->base.pc_next + 2;
62
}
233
if (!decode_insn16(ctx, opcode)) {
63
234
- /* fall back to old decoder */
64
static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
235
- decode_RV32_64C(ctx, opcode);
65
@@ -XXX,XX +XXX,XX @@ static void gen_mulhsu(TCGv ret, TCGv arg1, TCGv arg2)
236
+ gen_exception_illegal(ctx);
66
tcg_temp_free(rh);
237
}
67
}
238
}
68
239
} else {
69
+static void gen_mulhsu_w(TCGv ret, TCGv arg1, TCGv arg2)
70
+{
71
+ TCGv t1 = tcg_temp_new();
72
+ TCGv t2 = tcg_temp_new();
73
+
74
+ tcg_gen_ext32s_tl(t1, arg1);
75
+ tcg_gen_ext32u_tl(t2, arg2);
76
+ tcg_gen_mul_tl(ret, t1, t2);
77
+ tcg_temp_free(t1);
78
+ tcg_temp_free(t2);
79
+ tcg_gen_sari_tl(ret, ret, 32);
80
+}
81
+
82
static bool trans_mulhsu(DisasContext *ctx, arg_mulhsu *a)
83
{
84
REQUIRE_EXT(ctx, RVM);
85
- return gen_arith(ctx, a, EXT_NONE, gen_mulhsu);
86
+ return gen_arith_per_ol(ctx, a, EXT_NONE, gen_mulhsu, gen_mulhsu_w);
87
}
88
89
static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
90
@@ -XXX,XX +XXX,XX @@ static void gen_mulhu(TCGv ret, TCGv s1, TCGv s2)
91
static bool trans_mulhu(DisasContext *ctx, arg_mulhu *a)
92
{
93
REQUIRE_EXT(ctx, RVM);
94
- return gen_arith(ctx, a, EXT_NONE, gen_mulhu);
95
+ /* gen_mulh_w works for either sign as input. */
96
+ return gen_arith_per_ol(ctx, a, EXT_ZERO, gen_mulhu, gen_mulh_w);
97
}
98
99
static void gen_div(TCGv ret, TCGv source1, TCGv source2)
240
--
100
--
241
2.30.1
101
2.31.1
242
102
243
103
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Provides fw_cfg for the virt machine on riscv. This enables
3
When target_long is 64-bit, we still want a 32-bit bswap for rev8.
4
using e.g. ramfb later.
4
Since this opcode is specific to RV32, we need not conditionalize.
5
5
6
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210318235041.17175-2-ashe@kivikakk.ee
9
Message-id: 20211020031709.359469-12-richard.henderson@linaro.org
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
include/hw/riscv/virt.h | 2 ++
12
target/riscv/insn_trans/trans_rvb.c.inc | 7 ++++++-
13
hw/riscv/virt.c | 30 ++++++++++++++++++++++++++++++
13
1 file changed, 6 insertions(+), 1 deletion(-)
14
hw/riscv/Kconfig | 1 +
15
3 files changed, 33 insertions(+)
16
14
17
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
15
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/virt.h
17
--- a/target/riscv/insn_trans/trans_rvb.c.inc
20
+++ b/include/hw/riscv/virt.h
18
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
21
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
19
@@ -XXX,XX +XXX,XX @@ static bool trans_rol(DisasContext *ctx, arg_rol *a)
22
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
20
return gen_shift(ctx, a, EXT_NONE, tcg_gen_rotl_tl);
23
DeviceState *plic[VIRT_SOCKETS_MAX];
24
PFlashCFI01 *flash[2];
25
+ FWCfgState *fw_cfg;
26
27
int fdt_size;
28
};
29
@@ -XXX,XX +XXX,XX @@ enum {
30
VIRT_PLIC,
31
VIRT_UART0,
32
VIRT_VIRTIO,
33
+ VIRT_FW_CFG,
34
VIRT_FLASH,
35
VIRT_DRAM,
36
VIRT_PCIE_MMIO,
37
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/riscv/virt.c
40
+++ b/hw/riscv/virt.c
41
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
42
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
43
[VIRT_UART0] = { 0x10000000, 0x100 },
44
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
45
+ [VIRT_FW_CFG] = { 0x10100000, 0x18 },
46
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
47
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
48
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
49
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
50
return dev;
51
}
21
}
52
22
53
+static FWCfgState *create_fw_cfg(const MachineState *mc)
23
+static void gen_rev8_32(TCGv ret, TCGv src1)
54
+{
24
+{
55
+ hwaddr base = virt_memmap[VIRT_FW_CFG].base;
25
+ tcg_gen_bswap32_tl(ret, src1, TCG_BSWAP_OS);
56
+ hwaddr size = virt_memmap[VIRT_FW_CFG].size;
57
+ FWCfgState *fw_cfg;
58
+ char *nodename;
59
+
60
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
61
+ &address_space_memory);
62
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
63
+
64
+ nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
65
+ qemu_fdt_add_subnode(mc->fdt, nodename);
66
+ qemu_fdt_setprop_string(mc->fdt, nodename,
67
+ "compatible", "qemu,fw-cfg-mmio");
68
+ qemu_fdt_setprop_sized_cells(mc->fdt, nodename, "reg",
69
+ 2, base, 2, size);
70
+ qemu_fdt_setprop(mc->fdt, nodename, "dma-coherent", NULL, 0);
71
+ g_free(nodename);
72
+ return fw_cfg;
73
+}
26
+}
74
+
27
+
75
static void virt_machine_init(MachineState *machine)
28
static bool trans_rev8_32(DisasContext *ctx, arg_rev8_32 *a)
76
{
29
{
77
const MemMapEntry *memmap = virt_memmap;
30
REQUIRE_32BIT(ctx);
78
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
31
REQUIRE_ZBB(ctx);
79
start_addr = virt_memmap[VIRT_FLASH].base;
32
- return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl);
80
}
33
+ return gen_unary(ctx, a, EXT_NONE, gen_rev8_32);
81
34
}
82
+ /*
35
83
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
36
static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 *a)
84
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
85
+ */
86
+ s->fw_cfg = create_fw_cfg(machine);
87
+ rom_set_fw(s->fw_cfg);
88
+
89
/* Compute the fdt load address in dram */
90
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
91
machine->ram_size, machine->fdt);
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/Kconfig
95
+++ b/hw/riscv/Kconfig
96
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
97
select SIFIVE_PLIC
98
select SIFIVE_TEST
99
select VIRTIO_MMIO
100
+ select FW_CFG_DMA
101
102
config SIFIVE_E
103
bool
104
--
37
--
105
2.30.1
38
2.31.1
106
39
107
40
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
The previous implementation was broken in many ways:
3
The count zeros instructions require a separate implementation
4
- Used mideleg instead of hideleg to mask accesses
4
for RV32 when TARGET_LONG_BITS == 64.
5
- Used MIP_VSSIP instead of VS_MODE_INTERRUPTS to mask writes to vsie
6
- Did not shift between S bits and VS bits (VSEIP <-> SEIP, ...)
7
5
8
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
6
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210311094738.1376795-1-georg.kotheimer@kernkonzept.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211020031709.359469-13-richard.henderson@linaro.org
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
11
---
13
target/riscv/csr.c | 68 +++++++++++++++++++++++-----------------------
12
target/riscv/translate.c | 16 ++++++++++++
14
1 file changed, 34 insertions(+), 34 deletions(-)
13
target/riscv/insn_trans/trans_rvb.c.inc | 33 ++++++++++++-------------
14
2 files changed, 32 insertions(+), 17 deletions(-)
15
15
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
18
--- a/target/riscv/translate.c
19
+++ b/target/riscv/csr.c
19
+++ b/target/riscv/translate.c
20
@@ -XXX,XX +XXX,XX @@ static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
20
@@ -XXX,XX +XXX,XX @@ static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
21
return write_mstatus(env, CSR_MSTATUS, newval);
21
return true;
22
}
22
}
23
23
24
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
24
+static bool gen_unary_per_ol(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
25
+ void (*f_tl)(TCGv, TCGv),
26
+ void (*f_32)(TCGv, TCGv))
25
+{
27
+{
26
+ /* Shift the VS bits to their S bit location in vsie */
28
+ int olen = get_olen(ctx);
27
+ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
29
+
28
+ return 0;
30
+ if (olen != TARGET_LONG_BITS) {
31
+ if (olen == 32) {
32
+ f_tl = f_32;
33
+ } else {
34
+ g_assert_not_reached();
35
+ }
36
+ }
37
+ return gen_unary(ctx, a, ext, f_tl);
29
+}
38
+}
30
+
39
+
31
static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
40
static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
32
{
41
{
33
if (riscv_cpu_virt_enabled(env)) {
42
DisasContext *ctx = container_of(dcbase, DisasContext, base);
34
- /* Tell the guest the VS bits, shifted to the S bit locations */
43
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
35
- *val = (env->mie & env->mideleg & VS_MODE_INTERRUPTS) >> 1;
44
index XXXXXXX..XXXXXXX 100644
36
+ read_vsie(env, CSR_VSIE, val);
45
--- a/target/riscv/insn_trans/trans_rvb.c.inc
37
} else {
46
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
38
*val = env->mie & env->mideleg;
47
@@ -XXX,XX +XXX,XX @@ static void gen_clz(TCGv ret, TCGv arg1)
39
}
48
tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS);
40
return 0;
41
}
49
}
42
50
43
-static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
51
+static void gen_clzw(TCGv ret, TCGv arg1)
44
+static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
45
{
46
- target_ulong newval;
47
+ /* Shift the S bits to their VS bit location in mie */
48
+ target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) |
49
+ ((val << 1) & env->hideleg & VS_MODE_INTERRUPTS);
50
+ return write_mie(env, CSR_MIE, newval);
51
+}
52
53
+static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
54
+{
52
+{
55
if (riscv_cpu_virt_enabled(env)) {
53
+ TCGv t = tcg_temp_new();
56
- /* Shift the guests S bits to VS */
54
+ tcg_gen_shli_tl(t, arg1, 32);
57
- newval = (env->mie & ~VS_MODE_INTERRUPTS) |
55
+ tcg_gen_clzi_tl(ret, t, 32);
58
- ((val << 1) & VS_MODE_INTERRUPTS);
56
+ tcg_temp_free(t);
59
+ write_vsie(env, CSR_VSIE, val);
60
} else {
61
- newval = (env->mie & ~S_MODE_INTERRUPTS) | (val & S_MODE_INTERRUPTS);
62
+ target_ulong newval = (env->mie & ~S_MODE_INTERRUPTS) |
63
+ (val & S_MODE_INTERRUPTS);
64
+ write_mie(env, CSR_MIE, newval);
65
}
66
67
- return write_mie(env, CSR_MIE, newval);
68
+ return 0;
69
}
70
71
static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
72
@@ -XXX,XX +XXX,XX @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
73
return 0;
74
}
75
76
+static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
77
+ target_ulong new_value, target_ulong write_mask)
78
+{
79
+ /* Shift the S bits to their VS bit location in mip */
80
+ int ret = rmw_mip(env, 0, ret_value, new_value << 1,
81
+ (write_mask << 1) & vsip_writable_mask & env->hideleg);
82
+ *ret_value &= VS_MODE_INTERRUPTS;
83
+ /* Shift the VS bits to their S bit location in vsip */
84
+ *ret_value >>= 1;
85
+ return ret;
86
+}
57
+}
87
+
58
+
88
static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
59
static bool trans_clz(DisasContext *ctx, arg_clz *a)
89
target_ulong new_value, target_ulong write_mask)
90
{
60
{
91
int ret;
61
REQUIRE_ZBB(ctx);
92
62
- return gen_unary(ctx, a, EXT_ZERO, gen_clz);
93
if (riscv_cpu_virt_enabled(env)) {
63
+ return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw);
94
- /* Shift the new values to line up with the VS bits */
95
- ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value << 1,
96
- (write_mask & sip_writable_mask) << 1 & env->mideleg);
97
- ret &= vsip_writable_mask;
98
- ret >>= 1;
99
+ ret = rmw_vsip(env, CSR_VSIP, ret_value, new_value, write_mask);
100
} else {
101
ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
102
write_mask & env->mideleg & sip_writable_mask);
103
@@ -XXX,XX +XXX,XX @@ static int write_vsstatus(CPURISCVState *env, int csrno, target_ulong val)
104
return 0;
105
}
64
}
106
65
107
-static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
66
static void gen_ctz(TCGv ret, TCGv arg1)
108
- target_ulong new_value, target_ulong write_mask)
67
@@ -XXX,XX +XXX,XX @@ static void gen_ctz(TCGv ret, TCGv arg1)
68
tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS);
69
}
70
71
+static void gen_ctzw(TCGv ret, TCGv arg1)
72
+{
73
+ tcg_gen_ctzi_tl(ret, arg1, 32);
74
+}
75
+
76
static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
77
{
78
REQUIRE_ZBB(ctx);
79
- return gen_unary(ctx, a, EXT_ZERO, gen_ctz);
80
+ return gen_unary_per_ol(ctx, a, EXT_ZERO, gen_ctz, gen_ctzw);
81
}
82
83
static bool trans_cpop(DisasContext *ctx, arg_cpop *a)
84
@@ -XXX,XX +XXX,XX @@ static bool trans_zext_h_64(DisasContext *ctx, arg_zext_h_64 *a)
85
return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
86
}
87
88
-static void gen_clzw(TCGv ret, TCGv arg1)
109
-{
89
-{
110
- int ret = rmw_mip(env, 0, ret_value, new_value,
90
- TCGv t = tcg_temp_new();
111
- write_mask & env->mideleg & vsip_writable_mask);
91
- tcg_gen_shli_tl(t, arg1, 32);
112
- return ret;
92
- tcg_gen_clzi_tl(ret, t, 32);
93
- tcg_temp_free(t);
113
-}
94
-}
114
-
95
-
115
-static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
96
static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
97
{
98
REQUIRE_64BIT(ctx);
99
@@ -XXX,XX +XXX,XX @@ static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
100
return gen_unary(ctx, a, EXT_NONE, gen_clzw);
101
}
102
103
-static void gen_ctzw(TCGv ret, TCGv arg1)
116
-{
104
-{
117
- *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
105
- tcg_gen_ori_tl(ret, arg1, (target_ulong)MAKE_64BIT_MASK(32, 32));
118
- return 0;
106
- tcg_gen_ctzi_tl(ret, ret, 64);
119
-}
107
-}
120
-
108
-
121
-static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
109
static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
122
-{
123
- target_ulong newval = (env->mie & ~env->mideleg) | (val & env->mideleg & MIP_VSSIP);
124
- return write_mie(env, CSR_MIE, newval);
125
-}
126
-
127
static int read_vstvec(CPURISCVState *env, int csrno, target_ulong *val)
128
{
110
{
129
*val = env->vstvec;
111
REQUIRE_64BIT(ctx);
112
REQUIRE_ZBB(ctx);
113
- return gen_unary(ctx, a, EXT_NONE, gen_ctzw);
114
+ return gen_unary(ctx, a, EXT_ZERO, gen_ctzw);
115
}
116
117
static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
130
--
118
--
131
2.30.1
119
2.31.1
132
120
133
121
diff view generated by jsdifflib
New patch
1
1
From: Richard Henderson <richard.henderson@linaro.org>
2
3
Most shift instructions require a separate implementation
4
for RV32 when TARGET_LONG_BITS == 64.
5
6
Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211020031709.359469-14-richard.henderson@linaro.org
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/translate.c | 31 +++++++++
13
target/riscv/insn_trans/trans_rvb.c.inc | 92 ++++++++++++++-----------
14
target/riscv/insn_trans/trans_rvi.c.inc | 26 +++----
15
3 files changed, 97 insertions(+), 52 deletions(-)
16
17
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/translate.c
20
+++ b/target/riscv/translate.c
21
@@ -XXX,XX +XXX,XX @@ static bool gen_shift_imm_fn(DisasContext *ctx, arg_shift *a, DisasExtend ext,
22
return true;
23
}
24
25
+static bool gen_shift_imm_fn_per_ol(DisasContext *ctx, arg_shift *a,
26
+ DisasExtend ext,
27
+ void (*f_tl)(TCGv, TCGv, target_long),
28
+ void (*f_32)(TCGv, TCGv, target_long))
29
+{
30
+ int olen = get_olen(ctx);
31
+ if (olen != TARGET_LONG_BITS) {
32
+ if (olen == 32) {
33
+ f_tl = f_32;
34
+ } else {
35
+ g_assert_not_reached();
36
+ }
37
+ }
38
+ return gen_shift_imm_fn(ctx, a, ext, f_tl);
39
+}
40
+
41
static bool gen_shift_imm_tl(DisasContext *ctx, arg_shift *a, DisasExtend ext,
42
void (*func)(TCGv, TCGv, TCGv))
43
{
44
@@ -XXX,XX +XXX,XX @@ static bool gen_shift(DisasContext *ctx, arg_r *a, DisasExtend ext,
45
return true;
46
}
47
48
+static bool gen_shift_per_ol(DisasContext *ctx, arg_r *a, DisasExtend ext,
49
+ void (*f_tl)(TCGv, TCGv, TCGv),
50
+ void (*f_32)(TCGv, TCGv, TCGv))
51
+{
52
+ int olen = get_olen(ctx);
53
+ if (olen != TARGET_LONG_BITS) {
54
+ if (olen == 32) {
55
+ f_tl = f_32;
56
+ } else {
57
+ g_assert_not_reached();
58
+ }
59
+ }
60
+ return gen_shift(ctx, a, ext, f_tl);
61
+}
62
+
63
static bool gen_unary(DisasContext *ctx, arg_r2 *a, DisasExtend ext,
64
void (*func)(TCGv, TCGv))
65
{
66
diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/insn_trans/trans_rvb.c.inc
69
+++ b/target/riscv/insn_trans/trans_rvb.c.inc
70
@@ -XXX,XX +XXX,XX @@ static bool trans_bexti(DisasContext *ctx, arg_bexti *a)
71
return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
72
}
73
74
+static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
75
+{
76
+ TCGv_i32 t1 = tcg_temp_new_i32();
77
+ TCGv_i32 t2 = tcg_temp_new_i32();
78
+
79
+ /* truncate to 32-bits */
80
+ tcg_gen_trunc_tl_i32(t1, arg1);
81
+ tcg_gen_trunc_tl_i32(t2, arg2);
82
+
83
+ tcg_gen_rotr_i32(t1, t1, t2);
84
+
85
+ /* sign-extend 64-bits */
86
+ tcg_gen_ext_i32_tl(ret, t1);
87
+
88
+ tcg_temp_free_i32(t1);
89
+ tcg_temp_free_i32(t2);
90
+}
91
+
92
static bool trans_ror(DisasContext *ctx, arg_ror *a)
93
{
94
REQUIRE_ZBB(ctx);
95
- return gen_shift(ctx, a, EXT_NONE, tcg_gen_rotr_tl);
96
+ return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw);
97
+}
98
+
99
+static void gen_roriw(TCGv ret, TCGv arg1, target_long shamt)
100
+{
101
+ TCGv_i32 t1 = tcg_temp_new_i32();
102
+
103
+ tcg_gen_trunc_tl_i32(t1, arg1);
104
+ tcg_gen_rotri_i32(t1, t1, shamt);
105
+ tcg_gen_ext_i32_tl(ret, t1);
106
+
107
+ tcg_temp_free_i32(t1);
108
}
109
110
static bool trans_rori(DisasContext *ctx, arg_rori *a)
111
{
112
REQUIRE_ZBB(ctx);
113
- return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_rotri_tl);
114
+ return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
115
+ tcg_gen_rotri_tl, gen_roriw);
116
+}
117
+
118
+static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
119
+{
120
+ TCGv_i32 t1 = tcg_temp_new_i32();
121
+ TCGv_i32 t2 = tcg_temp_new_i32();
122
+
123
+ /* truncate to 32-bits */
124
+ tcg_gen_trunc_tl_i32(t1, arg1);
125
+ tcg_gen_trunc_tl_i32(t2, arg2);
126
+
127
+ tcg_gen_rotl_i32(t1, t1, t2);
128
+
129
+ /* sign-extend 64-bits */
130
+ tcg_gen_ext_i32_tl(ret, t1);
131
+
132
+ tcg_temp_free_i32(t1);
133
+ tcg_temp_free_i32(t2);
134
}
135
136
static bool trans_rol(DisasContext *ctx, arg_rol *a)
137
{
138
REQUIRE_ZBB(ctx);
139
- return gen_shift(ctx, a, EXT_NONE, tcg_gen_rotl_tl);
140
+ return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw);
141
}
142
143
static void gen_rev8_32(TCGv ret, TCGv src1)
144
@@ -XXX,XX +XXX,XX @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
145
return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
146
}
147
148
-static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
149
-{
150
- TCGv_i32 t1 = tcg_temp_new_i32();
151
- TCGv_i32 t2 = tcg_temp_new_i32();
152
-
153
- /* truncate to 32-bits */
154
- tcg_gen_trunc_tl_i32(t1, arg1);
155
- tcg_gen_trunc_tl_i32(t2, arg2);
156
-
157
- tcg_gen_rotr_i32(t1, t1, t2);
158
-
159
- /* sign-extend 64-bits */
160
- tcg_gen_ext_i32_tl(ret, t1);
161
-
162
- tcg_temp_free_i32(t1);
163
- tcg_temp_free_i32(t2);
164
-}
165
-
166
static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
167
{
168
REQUIRE_64BIT(ctx);
169
@@ -XXX,XX +XXX,XX @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
170
REQUIRE_64BIT(ctx);
171
REQUIRE_ZBB(ctx);
172
ctx->ol = MXL_RV32;
173
- return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_rorw);
174
-}
175
-
176
-static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
177
-{
178
- TCGv_i32 t1 = tcg_temp_new_i32();
179
- TCGv_i32 t2 = tcg_temp_new_i32();
180
-
181
- /* truncate to 32-bits */
182
- tcg_gen_trunc_tl_i32(t1, arg1);
183
- tcg_gen_trunc_tl_i32(t2, arg2);
184
-
185
- tcg_gen_rotl_i32(t1, t1, t2);
186
-
187
- /* sign-extend 64-bits */
188
- tcg_gen_ext_i32_tl(ret, t1);
189
-
190
- tcg_temp_free_i32(t1);
191
- tcg_temp_free_i32(t2);
192
+ return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw);
193
}
194
195
static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
196
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
197
index XXXXXXX..XXXXXXX 100644
198
--- a/target/riscv/insn_trans/trans_rvi.c.inc
199
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
200
@@ -XXX,XX +XXX,XX @@ static bool trans_slli(DisasContext *ctx, arg_slli *a)
201
return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl);
202
}
203
204
+static void gen_srliw(TCGv dst, TCGv src, target_long shamt)
205
+{
206
+ tcg_gen_extract_tl(dst, src, shamt, 32 - shamt);
207
+}
208
+
209
static bool trans_srli(DisasContext *ctx, arg_srli *a)
210
{
211
- return gen_shift_imm_fn(ctx, a, EXT_ZERO, tcg_gen_shri_tl);
212
+ return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
213
+ tcg_gen_shri_tl, gen_srliw);
214
+}
215
+
216
+static void gen_sraiw(TCGv dst, TCGv src, target_long shamt)
217
+{
218
+ tcg_gen_sextract_tl(dst, src, shamt, 32 - shamt);
219
}
220
221
static bool trans_srai(DisasContext *ctx, arg_srai *a)
222
{
223
- return gen_shift_imm_fn(ctx, a, EXT_SIGN, tcg_gen_sari_tl);
224
+ return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
225
+ tcg_gen_sari_tl, gen_sraiw);
226
}
227
228
static bool trans_add(DisasContext *ctx, arg_add *a)
229
@@ -XXX,XX +XXX,XX @@ static bool trans_slliw(DisasContext *ctx, arg_slliw *a)
230
return gen_shift_imm_fn(ctx, a, EXT_NONE, tcg_gen_shli_tl);
231
}
232
233
-static void gen_srliw(TCGv dst, TCGv src, target_long shamt)
234
-{
235
- tcg_gen_extract_tl(dst, src, shamt, 32 - shamt);
236
-}
237
-
238
static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
239
{
240
REQUIRE_64BIT(ctx);
241
@@ -XXX,XX +XXX,XX @@ static bool trans_srliw(DisasContext *ctx, arg_srliw *a)
242
return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_srliw);
243
}
244
245
-static void gen_sraiw(TCGv dst, TCGv src, target_long shamt)
246
-{
247
- tcg_gen_sextract_tl(dst, src, shamt, 32 - shamt);
248
-}
249
-
250
static bool trans_sraiw(DisasContext *ctx, arg_sraiw *a)
251
{
252
REQUIRE_64BIT(ctx);
253
--
254
2.31.1
255
256
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Use the official debug read interface to the csrs,
4
rather than referencing the env slots directly.
5
Put the list of csrs to dump into a table.
6
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211020031709.359469-15-richard.henderson@linaro.org
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.c | 89 +++++++++++++++++++++++-----------------------
13
1 file changed, 45 insertions(+), 44 deletions(-)
14
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
20
#endif
21
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc ", env->pc);
22
#ifndef CONFIG_USER_ONLY
23
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
24
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
25
- if (riscv_cpu_mxl(env) == MXL_RV32) {
26
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
27
- (target_ulong)(env->mstatus >> 32));
28
- }
29
- if (riscv_has_ext(env, RVH)) {
30
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
31
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus",
32
- (target_ulong)env->vsstatus);
33
- }
34
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mip ", env->mip);
35
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mie ", env->mie);
36
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mideleg ", env->mideleg);
37
- if (riscv_has_ext(env, RVH)) {
38
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hideleg ", env->hideleg);
39
- }
40
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "medeleg ", env->medeleg);
41
- if (riscv_has_ext(env, RVH)) {
42
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hedeleg ", env->hedeleg);
43
- }
44
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtvec ", env->mtvec);
45
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stvec ", env->stvec);
46
- if (riscv_has_ext(env, RVH)) {
47
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vstvec ", env->vstvec);
48
- }
49
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mepc ", env->mepc);
50
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "sepc ", env->sepc);
51
- if (riscv_has_ext(env, RVH)) {
52
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsepc ", env->vsepc);
53
- }
54
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mcause ", env->mcause);
55
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "scause ", env->scause);
56
- if (riscv_has_ext(env, RVH)) {
57
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vscause ", env->vscause);
58
- }
59
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval ", env->mtval);
60
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "stval ", env->stval);
61
- if (riscv_has_ext(env, RVH)) {
62
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "htval ", env->htval);
63
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mtval2 ", env->mtval2);
64
+ {
65
+ static const int dump_csrs[] = {
66
+ CSR_MHARTID,
67
+ CSR_MSTATUS,
68
+ CSR_MSTATUSH,
69
+ CSR_HSTATUS,
70
+ CSR_VSSTATUS,
71
+ CSR_MIP,
72
+ CSR_MIE,
73
+ CSR_MIDELEG,
74
+ CSR_HIDELEG,
75
+ CSR_MEDELEG,
76
+ CSR_HEDELEG,
77
+ CSR_MTVEC,
78
+ CSR_STVEC,
79
+ CSR_VSTVEC,
80
+ CSR_MEPC,
81
+ CSR_SEPC,
82
+ CSR_VSEPC,
83
+ CSR_MCAUSE,
84
+ CSR_SCAUSE,
85
+ CSR_VSCAUSE,
86
+ CSR_MTVAL,
87
+ CSR_STVAL,
88
+ CSR_HTVAL,
89
+ CSR_MTVAL2,
90
+ CSR_MSCRATCH,
91
+ CSR_SSCRATCH,
92
+ CSR_SATP,
93
+ };
94
+
95
+ for (int i = 0; i < ARRAY_SIZE(dump_csrs); ++i) {
96
+ int csrno = dump_csrs[i];
97
+ target_ulong val = 0;
98
+ RISCVException res = riscv_csrrw_debug(env, csrno, &val, 0, 0);
99
+
100
+ /*
101
+ * Rely on the smode, hmode, etc, predicates within csr.c
102
+ * to do the filtering of the registers that are present.
103
+ */
104
+ if (res == RISCV_EXCP_NONE) {
105
+ qemu_fprintf(f, " %-8s " TARGET_FMT_lx "\n",
106
+ csr_ops[csrno].name, val);
107
+ }
108
+ }
109
}
110
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mscratch", env->mscratch);
111
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "sscratch", env->sscratch);
112
- qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "satp ", env->satp);
113
#endif
114
115
for (i = 0; i < 32; i++) {
116
--
117
2.31.1
118
119
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Like MMU translation, add qemu log of PMP permission checking for
3
The position of this read-only field is dependent on the current xlen.
4
debugging.
4
Rather than having to compute that difference in many places, compute
5
it only on read.
5
6
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-3-git-send-email-cwshu@andestech.com
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20211020031709.359469-16-richard.henderson@linaro.org
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
target/riscv/cpu_helper.c | 12 ++++++++++++
12
target/riscv/cpu_helper.c | 3 +--
12
1 file changed, 12 insertions(+)
13
target/riscv/csr.c | 37 ++++++++++++++++++++++---------------
14
target/riscv/translate.c | 5 ++---
15
3 files changed, 25 insertions(+), 20 deletions(-)
13
16
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
17
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu_helper.c
19
--- a/target/riscv/cpu_helper.c
17
+++ b/target/riscv/cpu_helper.c
20
+++ b/target/riscv/cpu_helper.c
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
21
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_fp_enabled(CPURISCVState *env)
19
if (ret == TRANSLATE_SUCCESS) {
22
20
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
23
void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env)
21
size, access_type, mode);
24
{
25
- uint64_t sd = riscv_cpu_mxl(env) == MXL_RV32 ? MSTATUS32_SD : MSTATUS64_SD;
26
uint64_t mstatus_mask = MSTATUS_MXR | MSTATUS_SUM | MSTATUS_FS |
27
MSTATUS_SPP | MSTATUS_SPIE | MSTATUS_SIE |
28
- MSTATUS64_UXL | sd;
29
+ MSTATUS64_UXL;
30
bool current_virt = riscv_cpu_virt_enabled(env);
31
32
g_assert(riscv_has_ext(env, RVH));
33
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/csr.c
36
+++ b/target/riscv/csr.c
37
@@ -XXX,XX +XXX,XX @@ static RISCVException read_mhartid(CPURISCVState *env, int csrno,
38
}
39
40
/* Machine Trap Setup */
22
+
41
+
23
+ qemu_log_mask(CPU_LOG_MMU,
42
+/* We do not store SD explicitly, only compute it on demand. */
24
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
43
+static uint64_t add_status_sd(RISCVMXL xl, uint64_t status)
25
+ " %d tlb_size " TARGET_FMT_lu "\n",
44
+{
26
+ __func__, pa, ret, prot_pmp, tlb_size);
45
+ if ((status & MSTATUS_FS) == MSTATUS_FS ||
46
+ (status & MSTATUS_XS) == MSTATUS_XS) {
47
+ switch (xl) {
48
+ case MXL_RV32:
49
+ return status | MSTATUS32_SD;
50
+ case MXL_RV64:
51
+ return status | MSTATUS64_SD;
52
+ default:
53
+ g_assert_not_reached();
54
+ }
55
+ }
56
+ return status;
57
+}
27
+
58
+
28
prot &= prot_pmp;
59
static RISCVException read_mstatus(CPURISCVState *env, int csrno,
29
}
60
target_ulong *val)
30
61
{
31
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
62
- *val = env->mstatus;
32
if (ret == TRANSLATE_SUCCESS) {
63
+ *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus);
33
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
64
return RISCV_EXCP_NONE;
34
size, access_type, mode);
65
}
35
+
66
36
+ qemu_log_mask(CPU_LOG_MMU,
67
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
37
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
68
{
38
+ " %d tlb_size " TARGET_FMT_lu "\n",
69
uint64_t mstatus = env->mstatus;
39
+ __func__, pa, ret, prot_pmp, tlb_size);
70
uint64_t mask = 0;
40
+
71
- int dirty;
41
prot &= prot_pmp;
72
42
}
73
/* flush tlb on mstatus fields that affect VM */
74
if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
75
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
76
77
mstatus = (mstatus & ~mask) | (val & mask);
78
79
- dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
80
- ((mstatus & MSTATUS_XS) == MSTATUS_XS);
81
- if (riscv_cpu_mxl(env) == MXL_RV32) {
82
- mstatus = set_field(mstatus, MSTATUS32_SD, dirty);
83
- } else {
84
- mstatus = set_field(mstatus, MSTATUS64_SD, dirty);
85
+ if (riscv_cpu_mxl(env) == MXL_RV64) {
86
/* SXL and UXL fields are for now read only */
87
mstatus = set_field(mstatus, MSTATUS64_SXL, MXL_RV64);
88
mstatus = set_field(mstatus, MSTATUS64_UXL, MXL_RV64);
89
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
90
{
91
target_ulong mask = (sstatus_v1_10_mask);
92
93
- if (riscv_cpu_mxl(env) == MXL_RV32) {
94
- mask |= SSTATUS32_SD;
95
- } else {
96
- mask |= SSTATUS64_SD;
97
- }
98
-
99
- *val = env->mstatus & mask;
100
+ /* TODO: Use SXL not MXL. */
101
+ *val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
102
return RISCV_EXCP_NONE;
103
}
104
105
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/translate.c
108
+++ b/target/riscv/translate.c
109
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
110
static void mark_fs_dirty(DisasContext *ctx)
111
{
112
TCGv tmp;
113
- target_ulong sd = get_xl(ctx) == MXL_RV32 ? MSTATUS32_SD : MSTATUS64_SD;
114
115
if (ctx->mstatus_fs != MSTATUS_FS) {
116
/* Remember the state change for the rest of the TB. */
117
@@ -XXX,XX +XXX,XX @@ static void mark_fs_dirty(DisasContext *ctx)
118
119
tmp = tcg_temp_new();
120
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
121
- tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
122
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
123
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
124
tcg_temp_free(tmp);
125
}
126
@@ -XXX,XX +XXX,XX @@ static void mark_fs_dirty(DisasContext *ctx)
127
128
tmp = tcg_temp_new();
129
tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
130
- tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS | sd);
131
+ tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
132
tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus_hs));
133
tcg_temp_free(tmp);
43
}
134
}
44
--
135
--
45
2.30.1
136
2.31.1
46
137
47
138
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
Update the OpenTitan machine model to match the latest OpenTitan FPGA
4
design.
5
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-id: 18b1b681b0f8dd2461e819d1217bf0b530812680.1634524691.git.alistair.francis@wdc.com
9
---
10
include/hw/riscv/opentitan.h | 6 +++---
11
hw/riscv/opentitan.c | 22 +++++++++++++++++-----
12
2 files changed, 20 insertions(+), 8 deletions(-)
13
14
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/riscv/opentitan.h
17
+++ b/include/hw/riscv/opentitan.h
18
@@ -XXX,XX +XXX,XX @@
19
#define HW_OPENTITAN_H
20
21
#include "hw/riscv/riscv_hart.h"
22
-#include "hw/intc/ibex_plic.h"
23
+#include "hw/intc/sifive_plic.h"
24
#include "hw/char/ibex_uart.h"
25
#include "hw/timer/ibex_timer.h"
26
#include "qom/object.h"
27
@@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState {
28
29
/*< public >*/
30
RISCVHartArrayState cpus;
31
- IbexPlicState plic;
32
+ SiFivePLICState plic;
33
IbexUartState uart;
34
IbexTimerState timer;
35
36
@@ -XXX,XX +XXX,XX @@ enum {
37
};
38
39
enum {
40
- IBEX_TIMER_TIMEREXPIRED0_0 = 125,
41
+ IBEX_TIMER_TIMEREXPIRED0_0 = 126,
42
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
43
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
44
IBEX_UART0_RX_BREAK_ERR_IRQ = 6,
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 const MemMapEntry ibex_memmap[] = {
50
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
51
[IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
52
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
53
- [IBEX_DEV_PLIC] = { 0x41010000, 0x1000 },
54
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
55
[IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
56
[IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
57
- [IBEX_DEV_KEYMGR] = { 0x41130000, 0x1000 },
58
+ [IBEX_DEV_OTBN] = { 0x41130000, 0x10000 },
59
+ [IBEX_DEV_KEYMGR] = { 0x41140000, 0x1000 },
60
[IBEX_DEV_CSRNG] = { 0x41150000, 0x1000 },
61
[IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
62
[IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
63
[IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
64
[IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
65
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
66
- [IBEX_DEV_OTBN] = { 0x411d0000, 0x10000 },
67
[IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
68
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
69
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
70
};
71
72
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_init(Object *obj)
73
74
object_initialize_child(obj, "cpus", &s->cpus, TYPE_RISCV_HART_ARRAY);
75
76
- object_initialize_child(obj, "plic", &s->plic, TYPE_IBEX_PLIC);
77
+ object_initialize_child(obj, "plic", &s->plic, TYPE_SIFIVE_PLIC);
78
79
object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART);
80
81
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
82
&s->flash_alias);
83
84
/* PLIC */
85
+ qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
86
+ qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
87
+ qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
88
+ qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
89
+ qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
90
+ qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
91
+ qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
92
+ qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 0x18);
93
+ qdev_prop_set_uint32(DEVICE(&s->plic), "context-base", 0x200004);
94
+ qdev_prop_set_uint32(DEVICE(&s->plic), "context-stride", 4);
95
+ qdev_prop_set_uint32(DEVICE(&s->plic), "aperture-size", memmap[IBEX_DEV_PLIC].size);
96
+
97
if (!sysbus_realize(SYS_BUS_DEVICE(&s->plic), errp)) {
98
return;
99
}
100
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
101
for (i = 0; i < ms->smp.cpus; i++) {
102
CPUState *cpu = qemu_get_cpu(i);
103
104
- qdev_connect_gpio_out(DEVICE(&s->plic), i,
105
+ qdev_connect_gpio_out(DEVICE(&s->plic), ms->smp.cpus + i,
106
qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
107
}
108
109
--
110
2.31.1
111
112
diff view generated by jsdifflib
New patch
1
1
From: Alistair Francis <alistair.francis@wdc.com>
2
3
The Ibex PLIC is now spec compliant. Let's remove the Ibex PLIC and
4
instead use the SiFive PLIC.
5
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-id: 5557935c2660c5e6281b6d21e6514e019593662e.1634524691.git.alistair.francis@wdc.com
9
---
10
hw/intc/ibex_plic.c | 307 --------------------------------------------
11
hw/intc/meson.build | 1 -
12
2 files changed, 308 deletions(-)
13
delete mode 100644 hw/intc/ibex_plic.c
14
15
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
16
deleted file mode 100644
17
index XXXXXXX..XXXXXXX
18
--- a/hw/intc/ibex_plic.c
19
+++ /dev/null
20
@@ -XXX,XX +XXX,XX @@
21
-/*
22
- * QEMU RISC-V lowRISC Ibex PLIC
23
- *
24
- * Copyright (c) 2020 Western Digital
25
- *
26
- * Documentation avaliable: https://docs.opentitan.org/hw/ip/rv_plic/doc/
27
- *
28
- * This program is free software; you can redistribute it and/or modify it
29
- * under the terms and conditions of the GNU General Public License,
30
- * version 2 or later, as published by the Free Software Foundation.
31
- *
32
- * This program is distributed in the hope it will be useful, but WITHOUT
33
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
34
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
35
- * more details.
36
- *
37
- * You should have received a copy of the GNU General Public License along with
38
- * this program. If not, see <http://www.gnu.org/licenses/>.
39
- */
40
-
41
-#include "qemu/osdep.h"
42
-#include "qemu/log.h"
43
-#include "hw/qdev-properties.h"
44
-#include "hw/core/cpu.h"
45
-#include "hw/boards.h"
46
-#include "hw/pci/msi.h"
47
-#include "target/riscv/cpu_bits.h"
48
-#include "target/riscv/cpu.h"
49
-#include "hw/intc/ibex_plic.h"
50
-#include "hw/irq.h"
51
-
52
-static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
53
-{
54
- uint32_t end = base + (num * 0x04);
55
-
56
- if (addr >= base && addr < end) {
57
- return true;
58
- }
59
-
60
- return false;
61
-}
62
-
63
-static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
64
-{
65
- int pending_num = irq / 32;
66
-
67
- if (!level) {
68
- /*
69
- * If the level is low make sure we clear the hidden_pending.
70
- */
71
- s->hidden_pending[pending_num] &= ~(1 << (irq % 32));
72
- }
73
-
74
- if (s->claimed[pending_num] & 1 << (irq % 32)) {
75
- /*
76
- * The interrupt has been claimed, but not completed.
77
- * The pending bit can't be set.
78
- * Save the pending level for after the interrupt is completed.
79
- */
80
- s->hidden_pending[pending_num] |= level << (irq % 32);
81
- } else {
82
- s->pending[pending_num] |= level << (irq % 32);
83
- }
84
-}
85
-
86
-static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
87
-{
88
- int i;
89
- uint32_t max_irq = 0;
90
- uint32_t max_prio = s->threshold;
91
-
92
- for (i = 0; i < s->pending_num; i++) {
93
- uint32_t irq_num = ctz64(s->pending[i]) + (i * 32);
94
-
95
- if (!(s->pending[i] & s->enable[i])) {
96
- /* No pending and enabled IRQ */
97
- continue;
98
- }
99
-
100
- if (s->priority[irq_num] > max_prio) {
101
- max_irq = irq_num;
102
- max_prio = s->priority[irq_num];
103
- }
104
- }
105
-
106
- if (max_irq) {
107
- s->claim = max_irq;
108
- return true;
109
- }
110
-
111
- return false;
112
-}
113
-
114
-static void ibex_plic_update(IbexPlicState *s)
115
-{
116
- int i;
117
-
118
- for (i = 0; i < s->num_cpus; i++) {
119
- qemu_set_irq(s->external_irqs[i], ibex_plic_irqs_pending(s, 0));
120
- }
121
-}
122
-
123
-static void ibex_plic_reset(DeviceState *dev)
124
-{
125
- IbexPlicState *s = IBEX_PLIC(dev);
126
-
127
- s->threshold = 0x00000000;
128
- s->claim = 0x00000000;
129
-}
130
-
131
-static uint64_t ibex_plic_read(void *opaque, hwaddr addr,
132
- unsigned int size)
133
-{
134
- IbexPlicState *s = opaque;
135
- int offset;
136
- uint32_t ret = 0;
137
-
138
- if (addr_between(addr, s->pending_base, s->pending_num)) {
139
- offset = (addr - s->pending_base) / 4;
140
- ret = s->pending[offset];
141
- } else if (addr_between(addr, s->source_base, s->source_num)) {
142
- qemu_log_mask(LOG_UNIMP,
143
- "%s: Interrupt source mode not supported\n", __func__);
144
- } else if (addr_between(addr, s->priority_base, s->priority_num)) {
145
- offset = (addr - s->priority_base) / 4;
146
- ret = s->priority[offset];
147
- } else if (addr_between(addr, s->enable_base, s->enable_num)) {
148
- offset = (addr - s->enable_base) / 4;
149
- ret = s->enable[offset];
150
- } else if (addr_between(addr, s->threshold_base, 1)) {
151
- ret = s->threshold;
152
- } else if (addr_between(addr, s->claim_base, 1)) {
153
- int pending_num = s->claim / 32;
154
- s->pending[pending_num] &= ~(1 << (s->claim % 32));
155
-
156
- /* Set the interrupt as claimed, but not completed */
157
- s->claimed[pending_num] |= 1 << (s->claim % 32);
158
-
159
- /* Return the current claimed interrupt */
160
- ret = s->claim;
161
-
162
- /* Clear the claimed interrupt */
163
- s->claim = 0x00000000;
164
-
165
- /* Update the interrupt status after the claim */
166
- ibex_plic_update(s);
167
- }
168
-
169
- return ret;
170
-}
171
-
172
-static void ibex_plic_write(void *opaque, hwaddr addr,
173
- uint64_t value, unsigned int size)
174
-{
175
- IbexPlicState *s = opaque;
176
-
177
- if (addr_between(addr, s->pending_base, s->pending_num)) {
178
- qemu_log_mask(LOG_GUEST_ERROR,
179
- "%s: Pending registers are read only\n", __func__);
180
- } else if (addr_between(addr, s->source_base, s->source_num)) {
181
- qemu_log_mask(LOG_UNIMP,
182
- "%s: Interrupt source mode not supported\n", __func__);
183
- } else if (addr_between(addr, s->priority_base, s->priority_num)) {
184
- uint32_t irq = ((addr - s->priority_base) >> 2) + 1;
185
- s->priority[irq] = value & 7;
186
- ibex_plic_update(s);
187
- } else if (addr_between(addr, s->enable_base, s->enable_num)) {
188
- uint32_t enable_reg = (addr - s->enable_base) / 4;
189
-
190
- s->enable[enable_reg] = value;
191
- } else if (addr_between(addr, s->threshold_base, 1)) {
192
- s->threshold = value & 3;
193
- } else if (addr_between(addr, s->claim_base, 1)) {
194
- if (s->claim == value) {
195
- /* Interrupt was completed */
196
- s->claim = 0;
197
- }
198
- if (s->claimed[value / 32] & 1 << (value % 32)) {
199
- int pending_num = value / 32;
200
-
201
- /* This value was already claimed, clear it. */
202
- s->claimed[pending_num] &= ~(1 << (value % 32));
203
-
204
- if (s->hidden_pending[pending_num] & (1 << (value % 32))) {
205
- /*
206
- * If the bit in hidden_pending is set then that means we
207
- * received an interrupt between claiming and completing
208
- * the interrupt that hasn't since been de-asserted.
209
- * On hardware this would trigger an interrupt, so let's
210
- * trigger one here as well.
211
- */
212
- s->pending[pending_num] |= 1 << (value % 32);
213
- }
214
- }
215
- }
216
-
217
- ibex_plic_update(s);
218
-}
219
-
220
-static const MemoryRegionOps ibex_plic_ops = {
221
- .read = ibex_plic_read,
222
- .write = ibex_plic_write,
223
- .endianness = DEVICE_NATIVE_ENDIAN,
224
- .valid = {
225
- .min_access_size = 4,
226
- .max_access_size = 4
227
- }
228
-};
229
-
230
-static void ibex_plic_irq_request(void *opaque, int irq, int level)
231
-{
232
- IbexPlicState *s = opaque;
233
-
234
- ibex_plic_irqs_set_pending(s, irq, level > 0);
235
- ibex_plic_update(s);
236
-}
237
-
238
-static Property ibex_plic_properties[] = {
239
- DEFINE_PROP_UINT32("num-cpus", IbexPlicState, num_cpus, 1),
240
- DEFINE_PROP_UINT32("num-sources", IbexPlicState, num_sources, 176),
241
-
242
- DEFINE_PROP_UINT32("pending-base", IbexPlicState, pending_base, 0),
243
- DEFINE_PROP_UINT32("pending-num", IbexPlicState, pending_num, 6),
244
-
245
- DEFINE_PROP_UINT32("source-base", IbexPlicState, source_base, 0x18),
246
- DEFINE_PROP_UINT32("source-num", IbexPlicState, source_num, 6),
247
-
248
- DEFINE_PROP_UINT32("priority-base", IbexPlicState, priority_base, 0x30),
249
- DEFINE_PROP_UINT32("priority-num", IbexPlicState, priority_num, 177),
250
-
251
- DEFINE_PROP_UINT32("enable-base", IbexPlicState, enable_base, 0x300),
252
- DEFINE_PROP_UINT32("enable-num", IbexPlicState, enable_num, 6),
253
-
254
- DEFINE_PROP_UINT32("threshold-base", IbexPlicState, threshold_base, 0x318),
255
-
256
- DEFINE_PROP_UINT32("claim-base", IbexPlicState, claim_base, 0x31c),
257
- DEFINE_PROP_END_OF_LIST(),
258
-};
259
-
260
-static void ibex_plic_init(Object *obj)
261
-{
262
- IbexPlicState *s = IBEX_PLIC(obj);
263
-
264
- memory_region_init_io(&s->mmio, obj, &ibex_plic_ops, s,
265
- TYPE_IBEX_PLIC, 0x400);
266
- sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
267
-}
268
-
269
-static void ibex_plic_realize(DeviceState *dev, Error **errp)
270
-{
271
- IbexPlicState *s = IBEX_PLIC(dev);
272
- int i;
273
-
274
- s->pending = g_new0(uint32_t, s->pending_num);
275
- s->hidden_pending = g_new0(uint32_t, s->pending_num);
276
- s->claimed = g_new0(uint32_t, s->pending_num);
277
- s->source = g_new0(uint32_t, s->source_num);
278
- s->priority = g_new0(uint32_t, s->priority_num);
279
- s->enable = g_new0(uint32_t, s->enable_num);
280
-
281
- qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
282
-
283
- s->external_irqs = g_malloc(sizeof(qemu_irq) * s->num_cpus);
284
- qdev_init_gpio_out(dev, s->external_irqs, s->num_cpus);
285
-
286
- /*
287
- * We can't allow the supervisor to control SEIP as this would allow the
288
- * supervisor to clear a pending external interrupt which will result in
289
- * a lost interrupt in the case a PLIC is attached. The SEIP bit must be
290
- * hardware controlled when a PLIC is attached.
291
- */
292
- MachineState *ms = MACHINE(qdev_get_machine());
293
- unsigned int smp_cpus = ms->smp.cpus;
294
- for (i = 0; i < smp_cpus; i++) {
295
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
296
- if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
297
- error_report("SEIP already claimed");
298
- exit(1);
299
- }
300
- }
301
-
302
- msi_nonbroken = true;
303
-}
304
-
305
-static void ibex_plic_class_init(ObjectClass *klass, void *data)
306
-{
307
- DeviceClass *dc = DEVICE_CLASS(klass);
308
-
309
- dc->reset = ibex_plic_reset;
310
- device_class_set_props(dc, ibex_plic_properties);
311
- dc->realize = ibex_plic_realize;
312
-}
313
-
314
-static const TypeInfo ibex_plic_info = {
315
- .name = TYPE_IBEX_PLIC,
316
- .parent = TYPE_SYS_BUS_DEVICE,
317
- .instance_size = sizeof(IbexPlicState),
318
- .instance_init = ibex_plic_init,
319
- .class_init = ibex_plic_class_init,
320
-};
321
-
322
-static void ibex_plic_register_types(void)
323
-{
324
- type_register_static(&ibex_plic_info);
325
-}
326
-
327
-type_init(ibex_plic_register_types)
328
diff --git a/hw/intc/meson.build b/hw/intc/meson.build
329
index XXXXXXX..XXXXXXX 100644
330
--- a/hw/intc/meson.build
331
+++ b/hw/intc/meson.build
332
@@ -XXX,XX +XXX,XX @@ specific_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m_nvic.c'))
333
specific_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_vic.c'))
334
specific_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210_gic.c', 'exynos4210_combiner.c'))
335
specific_ss.add(when: 'CONFIG_GRLIB', if_true: files('grlib_irqmp.c'))
336
-specific_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_plic.c'))
337
specific_ss.add(when: 'CONFIG_IOAPIC', if_true: files('ioapic.c'))
338
specific_ss.add(when: 'CONFIG_LOONGSON_LIOINTC', if_true: files('loongson_liointc.c'))
339
specific_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('mips_gic.c'))
340
--
341
2.31.1
342
343
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
5
Message-id: 3c125e27c49a4969df82bf8b197535ccd1996939.1634524691.git.alistair.francis@wdc.com
6
---
7
hw/intc/sifive_plic.c | 30 +++++++++++++++---------------
8
1 file changed, 15 insertions(+), 15 deletions(-)
9
10
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/intc/sifive_plic.c
13
+++ b/hw/intc/sifive_plic.c
14
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps sifive_plic_ops = {
15
}
16
};
17
18
-static Property sifive_plic_properties[] = {
19
- DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
20
- DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
21
- DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
22
- DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
23
- DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
24
- DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
25
- DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
26
- DEFINE_PROP_UINT32("enable-stride", SiFivePLICState, enable_stride, 0),
27
- DEFINE_PROP_UINT32("context-base", SiFivePLICState, context_base, 0),
28
- DEFINE_PROP_UINT32("context-stride", SiFivePLICState, context_stride, 0),
29
- DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0),
30
- DEFINE_PROP_END_OF_LIST(),
31
-};
32
-
33
/*
34
* parse PLIC hart/mode address offset config
35
*
36
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_plic = {
37
}
38
};
39
40
+static Property sifive_plic_properties[] = {
41
+ DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
42
+ DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
43
+ DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
44
+ DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
45
+ DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
46
+ DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
47
+ DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
48
+ DEFINE_PROP_UINT32("enable-stride", SiFivePLICState, enable_stride, 0),
49
+ DEFINE_PROP_UINT32("context-base", SiFivePLICState, context_base, 0),
50
+ DEFINE_PROP_UINT32("context-stride", SiFivePLICState, context_stride, 0),
51
+ DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0),
52
+ DEFINE_PROP_END_OF_LIST(),
53
+};
54
+
55
static void sifive_plic_class_init(ObjectClass *klass, void *data)
56
{
57
DeviceClass *dc = DEVICE_CLASS(klass);
58
--
59
2.31.1
60
61
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
5
Message-id: b94c098cb221e744683349b1ac794c23102ef471.1634524691.git.alistair.francis@wdc.com
6
---
7
hw/intc/sifive_plic.c | 45 +++++++++++++++++++++++--------------------
8
1 file changed, 24 insertions(+), 21 deletions(-)
9
10
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/intc/sifive_plic.c
13
+++ b/hw/intc/sifive_plic.c
14
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_irq_request(void *opaque, int irq, int level)
15
16
static void sifive_plic_realize(DeviceState *dev, Error **errp)
17
{
18
- SiFivePLICState *plic = SIFIVE_PLIC(dev);
19
+ SiFivePLICState *s = SIFIVE_PLIC(dev);
20
int i;
21
22
- memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic,
23
- TYPE_SIFIVE_PLIC, plic->aperture_size);
24
- parse_hart_config(plic);
25
- plic->bitfield_words = (plic->num_sources + 31) >> 5;
26
- plic->num_enables = plic->bitfield_words * plic->num_addrs;
27
- plic->source_priority = g_new0(uint32_t, plic->num_sources);
28
- plic->target_priority = g_new(uint32_t, plic->num_addrs);
29
- plic->pending = g_new0(uint32_t, plic->bitfield_words);
30
- plic->claimed = g_new0(uint32_t, plic->bitfield_words);
31
- plic->enable = g_new0(uint32_t, plic->num_enables);
32
- sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
33
- qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
34
-
35
- plic->s_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
36
- qdev_init_gpio_out(dev, plic->s_external_irqs, plic->num_harts);
37
-
38
- plic->m_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
39
- qdev_init_gpio_out(dev, plic->m_external_irqs, plic->num_harts);
40
+ memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_plic_ops, s,
41
+ TYPE_SIFIVE_PLIC, s->aperture_size);
42
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
43
+
44
+ parse_hart_config(s);
45
+
46
+ s->bitfield_words = (s->num_sources + 31) >> 5;
47
+ s->num_enables = s->bitfield_words * s->num_addrs;
48
+ s->source_priority = g_new0(uint32_t, s->num_sources);
49
+ s->target_priority = g_new(uint32_t, s->num_addrs);
50
+ s->pending = g_new0(uint32_t, s->bitfield_words);
51
+ s->claimed = g_new0(uint32_t, s->bitfield_words);
52
+ s->enable = g_new0(uint32_t, s->num_enables);
53
+
54
+ qdev_init_gpio_in(dev, sifive_plic_irq_request, s->num_sources);
55
+
56
+ s->s_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
57
+ qdev_init_gpio_out(dev, s->s_external_irqs, s->num_harts);
58
+
59
+ s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
60
+ qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
61
62
/* We can't allow the supervisor to control SEIP as this would allow the
63
* supervisor to clear a pending external interrupt which will result in
64
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
65
* hardware controlled when a PLIC is attached.
66
*/
67
- for (i = 0; i < plic->num_harts; i++) {
68
- RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(plic->hartid_base + i));
69
+ for (i = 0; i < s->num_harts; i++) {
70
+ RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
71
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
72
error_report("SEIP already claimed");
73
exit(1);
74
--
75
2.31.1
76
77
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
5
Message-id: 4200da222a65c89ed1ba35f754dcca7fdd9f08d6.1634524691.git.alistair.francis@wdc.com
6
---
7
hw/intc/sifive_plic.c | 10 ++++------
8
1 file changed, 4 insertions(+), 6 deletions(-)
9
10
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
11
index XXXXXXX..XXXXXXX 100644
12
--- a/hw/intc/sifive_plic.c
13
+++ b/hw/intc/sifive_plic.c
14
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
15
16
static void sifive_plic_irq_request(void *opaque, int irq, int level)
17
{
18
- SiFivePLICState *plic = opaque;
19
- if (RISCV_DEBUG_PLIC) {
20
- qemu_log("sifive_plic_irq_request: irq=%d level=%d\n", irq, level);
21
- }
22
- sifive_plic_set_pending(plic, irq, level > 0);
23
- sifive_plic_update(plic);
24
+ SiFivePLICState *s = opaque;
25
+
26
+ sifive_plic_set_pending(s, irq, level > 0);
27
+ sifive_plic_update(s);
28
}
29
30
static void sifive_plic_realize(DeviceState *dev, Error **errp)
31
--
32
2.31.1
33
34
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bmeng.cn@gmail.com>
2
2
3
Since HSS commit c20a89f8dcac, the Icicle Kit reference design has
3
Using memory_region_init_ram(), which can't possibly handle vhost-user,
4
been updated to use a register mapped at 0x4f000000 instead of a
4
and can't work as expected with '-numa node,memdev' options.
5
GPIO to control whether eMMC or SD card is to be used. With this
6
support the same HSS image can be used for both eMMC and SD card
7
boot flow, while previously two different board configurations were
8
used. This is undocumented but one can take a look at the HSS code
9
HSS_MMCInit() in services/mmc/mmc_api.c.
10
5
11
With this commit, HSS image built from 2020.12 release boots again.
6
Use MachineState::ram instead of manually initializing RAM memory
7
region, as well as by providing MachineClass::default_ram_id to
8
opt in to memdev scheme.
12
9
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20210322075248.136255-1-bmeng.cn@gmail.com
12
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
13
Message-id: 20211020014112.7336-2-bmeng.cn@gmail.com
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
15
---
18
include/hw/riscv/microchip_pfsoc.h | 1 +
16
hw/riscv/microchip_pfsoc.c | 36 ++++++++++++++++++++----------------
19
hw/riscv/microchip_pfsoc.c | 6 ++++++
17
1 file changed, 20 insertions(+), 16 deletions(-)
20
2 files changed, 7 insertions(+)
21
18
22
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/microchip_pfsoc.h
25
+++ b/include/hw/riscv/microchip_pfsoc.h
26
@@ -XXX,XX +XXX,XX @@ enum {
27
MICROCHIP_PFSOC_ENVM_DATA,
28
MICROCHIP_PFSOC_QSPI_XIP,
29
MICROCHIP_PFSOC_IOSCB,
30
+ MICROCHIP_PFSOC_EMMC_SD_MUX,
31
MICROCHIP_PFSOC_DRAM_LO,
32
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
33
MICROCHIP_PFSOC_DRAM_HI,
34
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
19
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
35
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/riscv/microchip_pfsoc.c
21
--- a/hw/riscv/microchip_pfsoc.c
37
+++ b/hw/riscv/microchip_pfsoc.c
22
+++ b/hw/riscv/microchip_pfsoc.c
38
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
23
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
39
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
24
MemoryRegion *mem_low_alias = g_new(MemoryRegion, 1);
40
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
25
MemoryRegion *mem_high = g_new(MemoryRegion, 1);
41
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
26
MemoryRegion *mem_high_alias = g_new(MemoryRegion, 1);
42
+ [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
27
- uint64_t mem_high_size;
43
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
28
+ uint64_t mem_low_size, mem_high_size;
44
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
29
hwaddr firmware_load_addr;
45
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
30
const char *firmware_name;
46
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
31
bool kernel_as_payload = false;
47
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
32
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
48
memmap[MICROCHIP_PFSOC_IOSCB].base);
33
TYPE_MICROCHIP_PFSOC);
49
34
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
50
+ /* eMMC/SD mux */
35
51
+ create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
36
+ /* Split RAM into low and high regions using aliases to machine->ram */
52
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
37
+ mem_low_size = memmap[MICROCHIP_PFSOC_DRAM_LO].size;
53
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
38
+ mem_high_size = machine->ram_size - mem_low_size;
39
+ memory_region_init_alias(mem_low, NULL,
40
+ "microchip.icicle.kit.ram_low", machine->ram,
41
+ 0, mem_low_size);
42
+ memory_region_init_alias(mem_high, NULL,
43
+ "microchip.icicle.kit.ram_high", machine->ram,
44
+ mem_low_size, mem_high_size);
54
+
45
+
55
/* QSPI Flash */
46
/* Register RAM */
56
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
47
- memory_region_init_ram(mem_low, NULL, "microchip.icicle.kit.ram_low",
57
"microchip.pfsoc.qspi_xip",
48
- memmap[MICROCHIP_PFSOC_DRAM_LO].size,
49
- &error_fatal);
50
- memory_region_init_alias(mem_low_alias, NULL,
51
- "microchip.icicle.kit.ram_low.alias",
52
- mem_low, 0,
53
- memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].size);
54
memory_region_add_subregion(system_memory,
55
memmap[MICROCHIP_PFSOC_DRAM_LO].base,
56
mem_low);
57
+ memory_region_add_subregion(system_memory,
58
+ memmap[MICROCHIP_PFSOC_DRAM_HI].base,
59
+ mem_high);
60
+
61
+ /* Create aliases for the low and high RAM regions */
62
+ memory_region_init_alias(mem_low_alias, NULL,
63
+ "microchip.icicle.kit.ram_low.alias",
64
+ mem_low, 0, mem_low_size);
65
memory_region_add_subregion(system_memory,
66
memmap[MICROCHIP_PFSOC_DRAM_LO_ALIAS].base,
67
mem_low_alias);
68
-
69
- mem_high_size = machine->ram_size - 1 * GiB;
70
-
71
- memory_region_init_ram(mem_high, NULL, "microchip.icicle.kit.ram_high",
72
- mem_high_size, &error_fatal);
73
memory_region_init_alias(mem_high_alias, NULL,
74
"microchip.icicle.kit.ram_high.alias",
75
mem_high, 0, mem_high_size);
76
- memory_region_add_subregion(system_memory,
77
- memmap[MICROCHIP_PFSOC_DRAM_HI].base,
78
- mem_high);
79
memory_region_add_subregion(system_memory,
80
memmap[MICROCHIP_PFSOC_DRAM_HI_ALIAS].base,
81
mem_high_alias);
82
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void *data)
83
MICROCHIP_PFSOC_COMPUTE_CPU_COUNT;
84
mc->min_cpus = MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT + 1;
85
mc->default_cpus = mc->min_cpus;
86
+ mc->default_ram_id = "microchip.icicle.kit.ram";
87
88
/*
89
* Map 513 MiB high memory, the mimimum required high memory size, because
58
--
90
--
59
2.30.1
91
2.31.1
60
92
61
93
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng.cn@gmail.com>
1
2
3
Using memory_region_init_ram(), which can't possibly handle vhost-user,
4
and can't work as expected with '-numa node,memdev' options.
5
6
Use MachineState::ram instead of manually initializing RAM memory
7
region, as well as by providing MachineClass::default_ram_id to
8
opt in to memdev scheme.
9
10
While at it add check for user supplied RAM size and error out if it
11
mismatches board expected value.
12
13
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
17
Message-id: 20211020014112.7336-3-bmeng.cn@gmail.com
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
20
hw/riscv/opentitan.c | 16 ++++++++++++----
21
1 file changed, 12 insertions(+), 4 deletions(-)
22
23
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/riscv/opentitan.c
26
+++ b/hw/riscv/opentitan.c
27
@@ -XXX,XX +XXX,XX @@
28
*/
29
30
#include "qemu/osdep.h"
31
+#include "qemu/cutils.h"
32
#include "hw/riscv/opentitan.h"
33
#include "qapi/error.h"
34
#include "hw/boards.h"
35
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
36
37
static void opentitan_board_init(MachineState *machine)
38
{
39
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
40
const MemMapEntry *memmap = ibex_memmap;
41
OpenTitanState *s = g_new0(OpenTitanState, 1);
42
MemoryRegion *sys_mem = get_system_memory();
43
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
44
+
45
+ if (machine->ram_size != mc->default_ram_size) {
46
+ char *sz = size_to_str(mc->default_ram_size);
47
+ error_report("Invalid RAM size, should be %s", sz);
48
+ g_free(sz);
49
+ exit(EXIT_FAILURE);
50
+ }
51
52
/* Initialize SoC */
53
object_initialize_child(OBJECT(machine), "soc", &s->soc,
54
TYPE_RISCV_IBEX_SOC);
55
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
56
57
- memory_region_init_ram(main_mem, NULL, "riscv.lowrisc.ibex.ram",
58
- memmap[IBEX_DEV_RAM].size, &error_fatal);
59
memory_region_add_subregion(sys_mem,
60
- memmap[IBEX_DEV_RAM].base, main_mem);
61
+ memmap[IBEX_DEV_RAM].base, machine->ram);
62
63
if (machine->firmware) {
64
riscv_load_firmware(machine->firmware, memmap[IBEX_DEV_RAM].base, NULL);
65
@@ -XXX,XX +XXX,XX @@ static void opentitan_machine_init(MachineClass *mc)
66
mc->init = opentitan_board_init;
67
mc->max_cpus = 1;
68
mc->default_cpu_type = TYPE_RISCV_CPU_IBEX;
69
+ mc->default_ram_id = "riscv.lowrisc.ibex.ram";
70
+ mc->default_ram_size = ibex_memmap[IBEX_DEV_RAM].size;
71
}
72
73
DEFINE_MACHINE("opentitan", opentitan_machine_init)
74
--
75
2.31.1
76
77
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Bin Meng <bmeng.cn@gmail.com>
2
2
3
If PMP permission of any address has been changed by updating PMP entry,
3
Using memory_region_init_ram(), which can't possibly handle vhost-user,
4
flush all TLB pages to prevent from getting old permission.
4
and can't work as expected with '-numa node,memdev' options.
5
5
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
6
Use MachineState::ram instead of manually initializing RAM memory
7
region, as well as by providing MachineClass::default_ram_id to
8
opt in to memdev scheme.
9
10
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-4-git-send-email-cwshu@andestech.com
14
Message-id: 20211020014112.7336-4-bmeng.cn@gmail.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
16
---
11
target/riscv/pmp.c | 4 ++++
17
hw/riscv/shakti_c.c | 6 ++----
12
1 file changed, 4 insertions(+)
18
1 file changed, 2 insertions(+), 4 deletions(-)
13
19
14
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
20
diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
15
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/pmp.c
22
--- a/hw/riscv/shakti_c.c
17
+++ b/target/riscv/pmp.c
23
+++ b/hw/riscv/shakti_c.c
18
@@ -XXX,XX +XXX,XX @@
24
@@ -XXX,XX +XXX,XX @@ static void shakti_c_machine_state_init(MachineState *mstate)
19
#include "qapi/error.h"
25
{
20
#include "cpu.h"
26
ShaktiCMachineState *sms = RISCV_SHAKTI_MACHINE(mstate);
21
#include "trace.h"
27
MemoryRegion *system_memory = get_system_memory();
22
+#include "exec/exec-all.h"
28
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
23
29
24
static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
30
/* Allow only Shakti C CPU for this platform */
25
uint8_t val);
31
if (strcmp(mstate->cpu_type, TYPE_RISCV_CPU_SHAKTI_C) != 0) {
26
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
32
@@ -XXX,XX +XXX,XX @@ static void shakti_c_machine_state_init(MachineState *mstate)
27
cfg_val = (val >> 8 * i) & 0xff;
33
qdev_realize(DEVICE(&sms->soc), NULL, &error_abort);
28
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
34
29
}
35
/* register RAM */
30
+
36
- memory_region_init_ram(main_mem, NULL, "riscv.shakti.c.ram",
31
+ /* If PMP permission of any addr has been changed, flush TLB pages. */
37
- mstate->ram_size, &error_fatal);
32
+ tlb_flush(env_cpu(env));
38
memory_region_add_subregion(system_memory,
39
shakti_c_memmap[SHAKTI_C_RAM].base,
40
- main_mem);
41
+ mstate->ram);
42
43
/* ROM reset vector */
44
riscv_setup_rom_reset_vec(mstate, &sms->soc.cpus,
45
@@ -XXX,XX +XXX,XX @@ static void shakti_c_machine_class_init(ObjectClass *klass, void *data)
46
mc->desc = "RISC-V Board compatible with Shakti SDK";
47
mc->init = shakti_c_machine_state_init;
48
mc->default_cpu_type = TYPE_RISCV_CPU_SHAKTI_C;
49
+ mc->default_ram_id = "riscv.shakti.c.ram";
33
}
50
}
34
51
35
52
static const TypeInfo shakti_c_machine_type_info = {
36
--
53
--
37
2.30.1
54
2.31.1
38
55
39
56
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bmeng.cn@gmail.com>
2
2
3
This adds the documentation to describe what is supported for the
3
Using memory_region_init_ram(), which can't possibly handle vhost-user,
4
'microchip-icicle-kit' machine, and how to boot the machine in QEMU.
4
and can't work as expected with '-numa node,memdev' options.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Use MachineState::ram instead of manually initializing RAM memory
7
region, as well as by providing MachineClass::default_ram_id to
8
opt in to memdev scheme.
9
10
While at it add check for user supplied RAM size and error out if it
11
mismatches board expected value.
12
13
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210322075248.136255-2-bmeng.cn@gmail.com
16
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
17
Message-id: 20211020014112.7336-5-bmeng.cn@gmail.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
19
---
11
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++++++++++
20
hw/riscv/sifive_e.c | 16 ++++++++++++----
12
docs/system/target-riscv.rst | 1 +
21
1 file changed, 12 insertions(+), 4 deletions(-)
13
2 files changed, 90 insertions(+)
14
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
15
22
16
diff --git a/docs/system/riscv/microchip-icicle-kit.rst b/docs/system/riscv/microchip-icicle-kit.rst
23
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
17
new file mode 100644
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX
25
--- a/hw/riscv/sifive_e.c
19
--- /dev/null
26
+++ b/hw/riscv/sifive_e.c
20
+++ b/docs/system/riscv/microchip-icicle-kit.rst
21
@@ -XXX,XX +XXX,XX @@
27
@@ -XXX,XX +XXX,XX @@
22
+Microchip PolarFire SoC Icicle Kit (``microchip-icicle-kit``)
28
*/
23
+=============================================================
29
30
#include "qemu/osdep.h"
31
+#include "qemu/cutils.h"
32
#include "qemu/error-report.h"
33
#include "qapi/error.h"
34
#include "hw/boards.h"
35
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry sifive_e_memmap[] = {
36
37
static void sifive_e_machine_init(MachineState *machine)
38
{
39
+ MachineClass *mc = MACHINE_GET_CLASS(machine);
40
const MemMapEntry *memmap = sifive_e_memmap;
41
42
SiFiveEState *s = RISCV_E_MACHINE(machine);
43
MemoryRegion *sys_mem = get_system_memory();
44
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
45
int i;
46
47
+ if (machine->ram_size != mc->default_ram_size) {
48
+ char *sz = size_to_str(mc->default_ram_size);
49
+ error_report("Invalid RAM size, should be %s", sz);
50
+ g_free(sz);
51
+ exit(EXIT_FAILURE);
52
+ }
24
+
53
+
25
+Microchip PolarFire SoC Icicle Kit integrates a PolarFire SoC, with one
54
/* Initialize SoC */
26
+SiFive's E51 plus four U54 cores and many on-chip peripherals and an FPGA.
55
object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_E_SOC);
27
+
56
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
28
+For more details about Microchip PolarFire SoC, please see:
57
29
+https://www.microsemi.com/product-directory/soc-fpgas/5498-polarfire-soc-fpga
58
/* Data Tightly Integrated Memory */
30
+
59
- memory_region_init_ram(main_mem, NULL, "riscv.sifive.e.ram",
31
+The Icicle Kit board information can be found here:
60
- memmap[SIFIVE_E_DEV_DTIM].size, &error_fatal);
32
+https://www.microsemi.com/existing-parts/parts/152514
61
memory_region_add_subregion(sys_mem,
33
+
62
- memmap[SIFIVE_E_DEV_DTIM].base, main_mem);
34
+Supported devices
63
+ memmap[SIFIVE_E_DEV_DTIM].base, machine->ram);
35
+-----------------
64
36
+
65
/* Mask ROM reset vector */
37
+The ``microchip-icicle-kit`` machine supports the following devices:
66
uint32_t reset_vec[4];
38
+
67
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_class_init(ObjectClass *oc, void *data)
39
+ * 1 E51 core
68
mc->init = sifive_e_machine_init;
40
+ * 4 U54 cores
69
mc->max_cpus = 1;
41
+ * Core Level Interruptor (CLINT)
70
mc->default_cpu_type = SIFIVE_E_CPU;
42
+ * Platform-Level Interrupt Controller (PLIC)
71
+ mc->default_ram_id = "riscv.sifive.e.ram";
43
+ * L2 Loosely Integrated Memory (L2-LIM)
72
+ mc->default_ram_size = sifive_e_memmap[SIFIVE_E_DEV_DTIM].size;
44
+ * DDR memory controller
73
45
+ * 5 MMUARTs
74
object_class_property_add_bool(oc, "revb", sifive_e_machine_get_revb,
46
+ * 1 DMA controller
75
sifive_e_machine_set_revb);
47
+ * 2 GEM Ethernet controllers
48
+ * 1 SDHC storage controller
49
+
50
+Boot options
51
+------------
52
+
53
+The ``microchip-icicle-kit`` machine can start using the standard -bios
54
+functionality for loading its BIOS image, aka Hart Software Services (HSS_).
55
+HSS loads the second stage bootloader U-Boot from an SD card. It does not
56
+support direct kernel loading via the -kernel option. One has to load kernel
57
+from U-Boot.
58
+
59
+The memory is set to 1537 MiB by default which is the minimum required high
60
+memory size by HSS. A sanity check on ram size is performed in the machine
61
+init routine to prompt user to increase the RAM size to > 1537 MiB when less
62
+than 1537 MiB ram is detected.
63
+
64
+Boot the machine
65
+----------------
66
+
67
+HSS 2020.12 release is tested at the time of writing. To build an HSS image
68
+that can be booted by the ``microchip-icicle-kit`` machine, type the following
69
+in the HSS source tree:
70
+
71
+.. code-block:: bash
72
+
73
+ $ export CROSS_COMPILE=riscv64-linux-
74
+ $ cp boards/mpfs-icicle-kit-es/def_config .config
75
+ $ make BOARD=mpfs-icicle-kit-es
76
+
77
+Download the official SD card image released by Microchip and prepare it for
78
+QEMU usage:
79
+
80
+.. code-block:: bash
81
+
82
+ $ wget ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
83
+ $ gunzip core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
84
+ $ qemu-img resize core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic 4G
85
+
86
+Then we can boot the machine by:
87
+
88
+.. code-block:: bash
89
+
90
+ $ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 \
91
+ -bios path/to/hss.bin -sd path/to/sdcard.img \
92
+ -nic user,model=cadence_gem \
93
+ -nic tap,ifname=tap,model=cadence_gem,script=no \
94
+ -display none -serial stdio \
95
+ -chardev socket,id=serial1,path=serial1.sock,server=on,wait=on \
96
+ -serial chardev:serial1
97
+
98
+With above command line, current terminal session will be used for the first
99
+serial port. Open another terminal window, and use `minicom` to connect the
100
+second serial port.
101
+
102
+.. code-block:: bash
103
+
104
+ $ minicom -D unix\#serial1.sock
105
+
106
+HSS output is on the first serial port (stdio) and U-Boot outputs on the
107
+second serial port. U-Boot will automatically load the Linux kernel from
108
+the SD card image.
109
+
110
+.. _HSS: https://github.com/polarfire-soc/hart-software-services
111
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
112
index XXXXXXX..XXXXXXX 100644
113
--- a/docs/system/target-riscv.rst
114
+++ b/docs/system/target-riscv.rst
115
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
116
.. toctree::
117
:maxdepth: 1
118
119
+ riscv/microchip-icicle-kit
120
riscv/sifive_u
121
122
RISC-V CPU features
123
--
76
--
124
2.30.1
77
2.31.1
125
78
126
79
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bin Meng <bmeng.cn@gmail.com>
2
2
3
Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
3
Using memory_region_init_ram(), which can't possibly handle vhost-user,
4
the address bytes. Note only SPI mode is supported by SST flashes.
4
and can't work as expected with '-numa node,memdev' options.
5
5
6
[1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
6
Use MachineState::ram instead of manually initializing RAM memory
7
region, as well as by providing MachineClass::default_ram_id to
8
opt in to memdev scheme.
7
9
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
10
Message-id: 20210306060152.7250-1-bmeng.cn@gmail.com
12
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 20211020014112.7336-6-bmeng.cn@gmail.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
16
---
13
hw/block/m25p80.c | 3 +++
17
hw/riscv/sifive_u.c | 6 ++----
14
1 file changed, 3 insertions(+)
18
1 file changed, 2 insertions(+), 4 deletions(-)
15
19
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
20
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
22
--- a/hw/riscv/sifive_u.c
19
+++ b/hw/block/m25p80.c
23
+++ b/hw/riscv/sifive_u.c
20
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
24
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
21
s->needed_bytes = get_addr_length(s);
25
const MemMapEntry *memmap = sifive_u_memmap;
22
switch (get_man(s)) {
26
SiFiveUState *s = RISCV_U_MACHINE(machine);
23
/* Dummy cycles - modeled with bytes writes instead of bits */
27
MemoryRegion *system_memory = get_system_memory();
24
+ case MAN_SST:
28
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
25
+ s->needed_bytes += 1;
29
MemoryRegion *flash0 = g_new(MemoryRegion, 1);
26
+ break;
30
target_ulong start_addr = memmap[SIFIVE_U_DEV_DRAM].base;
27
case MAN_WINBOND:
31
target_ulong firmware_end_addr, kernel_start_addr;
28
s->needed_bytes += 8;
32
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
29
break;
33
qdev_realize(DEVICE(&s->soc), NULL, &error_abort);
34
35
/* register RAM */
36
- memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram",
37
- machine->ram_size, &error_fatal);
38
memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DEV_DRAM].base,
39
- main_mem);
40
+ machine->ram);
41
42
/* register QSPI0 Flash */
43
memory_region_init_ram(flash0, NULL, "riscv.sifive.u.flash0",
44
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_class_init(ObjectClass *oc, void *data)
45
mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1;
46
mc->default_cpu_type = SIFIVE_U_CPU;
47
mc->default_cpus = mc->min_cpus;
48
+ mc->default_ram_id = "riscv.sifive.u.ram";
49
50
object_class_property_add_bool(oc, "start-in-flash",
51
sifive_u_machine_get_start_in_flash,
30
--
52
--
31
2.30.1
53
2.31.1
32
54
33
55
diff view generated by jsdifflib
1
From: Alexander Wagner <alexander.wagner@ulal.de>
1
From: Bin Meng <bmeng.cn@gmail.com>
2
2
3
Not disabling the UART leads to QEMU overwriting the UART receive buffer with
3
Using memory_region_init_ram(), which can't possibly handle vhost-user,
4
the newest received byte. The rx_level variable is added to allow the use of
4
and can't work as expected with '-numa node,memdev' options.
5
the existing OpenTitan driver libraries.
6
5
7
Signed-off-by: Alexander Wagner <alexander.wagner@ulal.de>
6
Use MachineState::ram instead of manually initializing RAM memory
7
region, as well as by providing MachineClass::default_ram_id to
8
opt in to memdev scheme.
9
10
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
12
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210309152130.13038-1-alexander.wagner@ulal.de
14
Message-id: 20211020014112.7336-7-bmeng.cn@gmail.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
16
---
12
include/hw/char/ibex_uart.h | 4 ++++
17
hw/riscv/spike.c | 6 ++----
13
hw/char/ibex_uart.c | 23 ++++++++++++++++++-----
18
1 file changed, 2 insertions(+), 4 deletions(-)
14
2 files changed, 22 insertions(+), 5 deletions(-)
15
19
16
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
20
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/char/ibex_uart.h
22
--- a/hw/riscv/spike.c
19
+++ b/include/hw/char/ibex_uart.h
23
+++ b/hw/riscv/spike.c
20
@@ -XXX,XX +XXX,XX @@ REG32(FIFO_CTRL, 0x1c)
24
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
21
FIELD(FIFO_CTRL, RXILVL, 2, 3)
25
const MemMapEntry *memmap = spike_memmap;
22
FIELD(FIFO_CTRL, TXILVL, 5, 2)
26
SpikeState *s = SPIKE_MACHINE(machine);
23
REG32(FIFO_STATUS, 0x20)
27
MemoryRegion *system_memory = get_system_memory();
24
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
28
- MemoryRegion *main_mem = g_new(MemoryRegion, 1);
25
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
29
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
26
REG32(OVRD, 0x24)
30
target_ulong firmware_end_addr, kernel_start_addr;
27
REG32(VAL, 0x28)
31
uint32_t fdt_load_addr;
28
REG32(TIMEOUT_CTRL, 0x2c)
32
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
29
@@ -XXX,XX +XXX,XX @@ struct IbexUartState {
30
uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
31
uint32_t tx_level;
32
33
+ uint32_t rx_level;
34
+
35
QEMUTimer *fifo_trigger_handle;
36
uint64_t char_tx_time;
37
38
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/char/ibex_uart.c
41
+++ b/hw/char/ibex_uart.c
42
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
43
{
44
IbexUartState *s = opaque;
45
46
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
47
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
48
+ && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
49
return 1;
50
}
33
}
51
34
52
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
35
/* register system main memory (actual RAM) */
53
36
- memory_region_init_ram(main_mem, NULL, "riscv.spike.ram",
54
s->uart_status &= ~R_STATUS_RXIDLE_MASK;
37
- machine->ram_size, &error_fatal);
55
s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
38
memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base,
56
+ /* The RXFULL is set after receiving a single byte
39
- main_mem);
57
+ * as the FIFO buffers are not yet implemented.
40
+ machine->ram);
58
+ */
41
59
+ s->uart_status |= R_STATUS_RXFULL_MASK;
42
/* create device tree */
60
+ s->rx_level += 1;
43
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
61
44
@@ -XXX,XX +XXX,XX @@ static void spike_machine_class_init(ObjectClass *oc, void *data)
62
if (size > rx_fifo_level) {
45
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
63
s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
46
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
64
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
47
mc->numa_mem_supported = true;
65
s->uart_timeout_ctrl = 0x00000000;
48
+ mc->default_ram_id = "riscv.spike.ram";
66
49
}
67
s->tx_level = 0;
50
68
+ s->rx_level = 0;
51
static const TypeInfo spike_machine_typeinfo = {
69
70
s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
71
72
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
73
74
case R_RDATA:
75
retvalue = s->uart_rdata;
76
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
77
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) && (s->rx_level > 0)) {
78
qemu_chr_fe_accept_input(&s->chr);
79
80
- s->uart_status |= R_STATUS_RXIDLE_MASK;
81
- s->uart_status |= R_STATUS_RXEMPTY_MASK;
82
+ s->rx_level -= 1;
83
+ s->uart_status &= ~R_STATUS_RXFULL_MASK;
84
+ if (s->rx_level == 0) {
85
+ s->uart_status |= R_STATUS_RXIDLE_MASK;
86
+ s->uart_status |= R_STATUS_RXEMPTY_MASK;
87
+ }
88
}
89
break;
90
case R_WDATA:
91
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
92
case R_FIFO_STATUS:
93
retvalue = s->uart_fifo_status;
94
95
- retvalue |= s->tx_level & 0x1F;
96
+ retvalue |= (s->rx_level & 0x1F) << R_FIFO_STATUS_RXLVL_SHIFT;
97
+ retvalue |= (s->tx_level & 0x1F) << R_FIFO_STATUS_TXLVL_SHIFT;
98
99
qemu_log_mask(LOG_UNIMP,
100
"%s: RX fifos are not supported\n", __func__);
101
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
102
s->uart_fifo_ctrl = value;
103
104
if (value & R_FIFO_CTRL_RXRST_MASK) {
105
+ s->rx_level = 0;
106
qemu_log_mask(LOG_UNIMP,
107
"%s: RX fifos are not supported\n", __func__);
108
}
109
--
52
--
110
2.30.1
53
2.31.1
111
54
112
55
diff view generated by jsdifflib