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 2c89b5af5e72ab8c9d544c6e30399528b2238827:
4
5
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20220120-1' into staging (2022-01-20 16:13:17 +0000)
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-20220121-1
8
10
9
for you to fetch changes up to 9a27f69bd668d9d71674407badc412ce1231c7d5:
11
for you to fetch changes up to f297245f6a780f496fb171af6fcd21ff3e6783c3:
10
12
11
target/riscv: Prevent lost illegal instruction exceptions (2021-03-22 21:54:40 -0400)
13
target/riscv: Relax UXL field for debugging (2022-01-21 15:52:57 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
RISC-V PR for 6.0
16
Third RISC-V PR for QEMU 7.0
15
17
16
This PR includes:
18
* Fixes for OpenTitan timer
17
- Fix for vector CSR access
19
* Correction of OpenTitan PLIC stride length
18
- Improvements to the Ibex UART device
20
* RISC-V KVM support
19
- PMP improvements and bug fixes
21
* Device tree code cleanup
20
- Hypervisor extension bug fixes
22
* Support for the Zve64f and Zve32f extensions
21
- ramfb support for the virt machine
23
* OpenSBI binary loading support for the Spike machine
22
- Fast read support for SST flash
24
* Removal of OpenSBI ELFs
23
- Improvements to the microchip_pfsoc machine
25
* Support for the UXL field in xstatus
24
26
25
----------------------------------------------------------------
27
----------------------------------------------------------------
26
Alexander Wagner (1):
28
Anup Patel (3):
27
hw/char: disable ibex uart receive if the buffer is full
29
hw/riscv: spike: Allow using binary firmware as bios
30
hw/riscv: Remove macros for ELF BIOS image names
31
roms/opensbi: Remove ELF images
28
32
29
Asherah Connor (2):
33
Frank Chang (17):
30
hw/riscv: Add fw_cfg support to virt
34
target/riscv: rvv-1.0: Add Zve64f extension into RISC-V
31
hw/riscv: allow ramfb on virt
35
target/riscv: rvv-1.0: Add Zve64f support for configuration insns
36
target/riscv: rvv-1.0: Add Zve64f support for load and store insns
37
target/riscv: rvv-1.0: Add Zve64f support for vmulh variant insns
38
target/riscv: rvv-1.0: Add Zve64f support for vsmul.vv and vsmul.vx insns
39
target/riscv: rvv-1.0: Add Zve64f support for scalar fp insns
40
target/riscv: rvv-1.0: Add Zve64f support for single-width fp reduction insns
41
target/riscv: rvv-1.0: Add Zve64f support for widening type-convert insns
42
target/riscv: rvv-1.0: Add Zve64f support for narrowing type-convert insns
43
target/riscv: rvv-1.0: Allow Zve64f extension to be turned on
44
target/riscv: rvv-1.0: Add Zve32f extension into RISC-V
45
target/riscv: rvv-1.0: Add Zve32f support for configuration insns
46
target/riscv: rvv-1.0: Add Zve32f support for scalar fp insns
47
target/riscv: rvv-1.0: Add Zve32f support for single-width fp reduction insns
48
target/riscv: rvv-1.0: Add Zve32f support for widening type-convert insns
49
target/riscv: rvv-1.0: Add Zve32f support for narrowing type-convert insns
50
target/riscv: rvv-1.0: Allow Zve32f extension to be turned on
32
51
33
Bin Meng (3):
52
LIU Zhiwei (23):
34
hw/block: m25p80: Support fast read for SST flashes
53
target/riscv: Adjust pmpcfg access with mxl
35
hw/riscv: microchip_pfsoc: Map EMMC/SD mux register
54
target/riscv: Don't save pc when exception return
36
docs/system: riscv: Add documentation for 'microchip-icicle-kit' machine
55
target/riscv: Sign extend link reg for jal and jalr
56
target/riscv: Sign extend pc for different XLEN
57
target/riscv: Create xl field in env
58
target/riscv: Ignore the pc bits above XLEN
59
target/riscv: Extend pc for runtime pc write
60
target/riscv: Use gdb xml according to max mxlen
61
target/riscv: Relax debug check for pm write
62
target/riscv: Adjust csr write mask with XLEN
63
target/riscv: Create current pm fields in env
64
target/riscv: Alloc tcg global for cur_pm[mask|base]
65
target/riscv: Calculate address according to XLEN
66
target/riscv: Split pm_enabled into mask and base
67
target/riscv: Split out the vill from vtype
68
target/riscv: Adjust vsetvl according to XLEN
69
target/riscv: Remove VILL field in VTYPE
70
target/riscv: Fix check range for first fault only
71
target/riscv: Adjust vector address with mask
72
target/riscv: Adjust scalar reg in vector with XLEN
73
target/riscv: Set default XLEN for hypervisor
74
target/riscv: Enable uxl field write
75
target/riscv: Relax UXL field for debugging
37
76
38
Frank Chang (1):
77
Thomas Huth (1):
39
target/riscv: fix vs() to return proper error code
78
softmmu/device_tree: Silence compiler warning with --enable-sanitizers
40
79
41
Georg Kotheimer (6):
80
Wilfred Mallawa (3):
42
target/riscv: Adjust privilege level for HLV(X)/HSV instructions
81
hw: timer: ibex_timer: Fixup reading w/o register
43
target/riscv: Make VSTIP and VSEIP read-only in hip
82
riscv: opentitan: fixup plic stride len
44
target/riscv: Use background registers also for MSTATUS_MPV
83
hw: timer: ibex_timer: update/add reg address
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
84
49
Jim Shu (3):
85
Yanan Wang (1):
50
target/riscv: propagate PMP permission to TLB page
86
softmmu/device_tree: Remove redundant pointer assignment
51
target/riscv: add log of PMP permission checking
52
target/riscv: flush TLB pages if PMP permission has been changed
53
87
54
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++
88
Yifei Jiang (13):
55
docs/system/target-riscv.rst | 1 +
89
update-linux-headers: Add asm-riscv/kvm.h
56
include/hw/char/ibex_uart.h | 4 +
90
target/riscv: Add target/riscv/kvm.c to place the public kvm interface
57
include/hw/riscv/microchip_pfsoc.h | 1 +
91
target/riscv: Implement function kvm_arch_init_vcpu
58
include/hw/riscv/virt.h | 2 +
92
target/riscv: Implement kvm_arch_get_registers
59
target/riscv/cpu.h | 4 +
93
target/riscv: Implement kvm_arch_put_registers
60
target/riscv/pmp.h | 4 +-
94
target/riscv: Support start kernel directly by KVM
61
hw/block/m25p80.c | 3 +
95
target/riscv: Support setting external interrupt by KVM
62
hw/char/ibex_uart.c | 23 +++-
96
target/riscv: Handle KVM_EXIT_RISCV_SBI exit
63
hw/riscv/microchip_pfsoc.c | 6 +
97
target/riscv: Add host cpu type
64
hw/riscv/virt.c | 33 ++++++
98
target/riscv: Add kvm_riscv_get/put_regs_timer
65
target/riscv/cpu.c | 1 +
99
target/riscv: Implement virtual time adjusting with vm state changing
66
target/riscv/cpu_helper.c | 144 +++++++++++++++--------
100
target/riscv: Support virtual time context synchronization
67
target/riscv/csr.c | 77 +++++++------
101
target/riscv: enable riscv kvm accel
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
102
103
meson.build | 2 +
104
include/hw/char/riscv_htif.h | 5 +-
105
include/hw/riscv/boot.h | 3 +-
106
include/hw/riscv/spike.h | 1 +
107
include/hw/timer/ibex_timer.h | 1 -
108
linux-headers/asm-riscv/kvm.h | 128 ++++++
109
target/riscv/cpu.h | 58 ++-
110
target/riscv/cpu_bits.h | 3 +
111
target/riscv/helper.h | 4 +-
112
target/riscv/kvm_riscv.h | 25 ++
113
target/riscv/sbi_ecall_interface.h | 72 ++++
114
hw/char/riscv_htif.c | 33 +-
115
hw/intc/sifive_plic.c | 20 +-
116
hw/riscv/boot.c | 16 +-
117
hw/riscv/opentitan.c | 2 +-
118
hw/riscv/spike.c | 45 ++-
119
hw/riscv/virt.c | 83 ++--
120
hw/timer/ibex_timer.c | 25 +-
121
softmmu/device_tree.c | 11 +-
122
target/riscv/cpu.c | 77 +++-
123
target/riscv/cpu_helper.c | 99 ++---
124
target/riscv/csr.c | 90 ++++-
125
target/riscv/gdbstub.c | 71 +++-
126
target/riscv/kvm-stub.c | 30 ++
127
target/riscv/kvm.c | 535 +++++++++++++++++++++++++
128
target/riscv/machine.c | 46 ++-
129
target/riscv/op_helper.c | 7 +-
130
target/riscv/pmp.c | 12 +-
131
target/riscv/translate.c | 94 +++--
132
target/riscv/vector_helper.c | 39 +-
133
target/riscv/insn_trans/trans_privileged.c.inc | 9 +-
134
target/riscv/insn_trans/trans_rva.c.inc | 9 +-
135
target/riscv/insn_trans/trans_rvd.c.inc | 19 +-
136
target/riscv/insn_trans/trans_rvf.c.inc | 19 +-
137
target/riscv/insn_trans/trans_rvi.c.inc | 39 +-
138
target/riscv/insn_trans/trans_rvv.c.inc | 225 +++++++++--
139
.gitlab-ci.d/opensbi.yml | 2 -
140
pc-bios/meson.build | 2 -
141
pc-bios/opensbi-riscv32-generic-fw_dynamic.elf | Bin 838904 -> 0 bytes
142
pc-bios/opensbi-riscv64-generic-fw_dynamic.elf | Bin 934696 -> 0 bytes
143
roms/Makefile | 2 -
144
target/riscv/meson.build | 1 +
145
42 files changed, 1608 insertions(+), 356 deletions(-)
146
create mode 100644 linux-headers/asm-riscv/kvm.h
147
create mode 100644 target/riscv/kvm_riscv.h
148
create mode 100644 target/riscv/sbi_ecall_interface.h
149
create mode 100644 target/riscv/kvm-stub.c
150
create mode 100644 target/riscv/kvm.c
151
delete mode 100644 pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
152
delete mode 100644 pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
153
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
This change fixes a bug where a write only register is read.
4
As per https://docs.opentitan.org/hw/ip/rv_timer/doc/#register-table
5
the 'INTR_TEST0' register is write only.
6
7
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
Message-id: 20220110051606.4031241-1-alistair.francis@opensource.wdc.com
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
include/hw/timer/ibex_timer.h | 1 -
15
hw/timer/ibex_timer.c | 14 +++++---------
16
2 files changed, 5 insertions(+), 10 deletions(-)
17
18
diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/timer/ibex_timer.h
21
+++ b/include/hw/timer/ibex_timer.h
22
@@ -XXX,XX +XXX,XX @@ struct IbexTimerState {
23
uint32_t timer_compare_upper0;
24
uint32_t timer_intr_enable;
25
uint32_t timer_intr_state;
26
- uint32_t timer_intr_test;
27
28
uint32_t timebase_freq;
29
30
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/timer/ibex_timer.c
33
+++ b/hw/timer/ibex_timer.c
34
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_reset(DeviceState *dev)
35
s->timer_compare_upper0 = 0xFFFFFFFF;
36
s->timer_intr_enable = 0x00000000;
37
s->timer_intr_state = 0x00000000;
38
- s->timer_intr_test = 0x00000000;
39
40
ibex_timer_update_irqs(s);
41
}
42
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_timer_read(void *opaque, hwaddr addr,
43
retvalue = s->timer_intr_state;
44
break;
45
case R_INTR_TEST:
46
- retvalue = s->timer_intr_test;
47
+ qemu_log_mask(LOG_GUEST_ERROR,
48
+ "Attempted to read INTR_TEST, a write only register");
49
break;
50
default:
51
qemu_log_mask(LOG_GUEST_ERROR,
52
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_write(void *opaque, hwaddr addr,
53
s->timer_intr_state &= ~val;
54
break;
55
case R_INTR_TEST:
56
- s->timer_intr_test = val;
57
- if (s->timer_intr_enable &
58
- s->timer_intr_test &
59
- R_INTR_ENABLE_IE_0_MASK) {
60
+ if (s->timer_intr_enable & val & R_INTR_ENABLE_IE_0_MASK) {
61
s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
62
qemu_set_irq(s->irq, true);
63
}
64
@@ -XXX,XX +XXX,XX @@ static int ibex_timer_post_load(void *opaque, int version_id)
65
66
static const VMStateDescription vmstate_ibex_timer = {
67
.name = TYPE_IBEX_TIMER,
68
- .version_id = 1,
69
- .minimum_version_id = 1,
70
+ .version_id = 2,
71
+ .minimum_version_id = 2,
72
.post_load = ibex_timer_post_load,
73
.fields = (VMStateField[]) {
74
VMSTATE_UINT32(timer_ctrl, IbexTimerState),
75
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_ibex_timer = {
76
VMSTATE_UINT32(timer_compare_upper0, IbexTimerState),
77
VMSTATE_UINT32(timer_intr_enable, IbexTimerState),
78
VMSTATE_UINT32(timer_intr_state, IbexTimerState),
79
- VMSTATE_UINT32(timer_intr_test, IbexTimerState),
80
VMSTATE_END_OF_LIST()
81
}
82
};
83
--
84
2.31.1
85
86
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
The following change was made to rectify incorrectly set stride length
4
on the PLIC [1]. Where it should be 32bit and not 24bit (0x18). This was
5
discovered whilst attempting to fix a bug where a timer_interrupt was
6
not serviced on TockOS-OpenTitan.
7
8
[1] https://docs.opentitan.org/hw/top_earlgrey/ip_autogen/rv_plic/doc/
9
10
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Tested-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
14
Message-id: 20220111071025.4169189-1-alistair.francis@opensource.wdc.com
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
hw/riscv/opentitan.c | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/riscv/opentitan.c
23
+++ b/hw/riscv/opentitan.c
24
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
25
qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
26
qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
27
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
28
- qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 0x18);
29
+ qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 32);
30
qdev_prop_set_uint32(DEVICE(&s->plic), "context-base", 0x200000);
31
qdev_prop_set_uint32(DEVICE(&s->plic), "context-stride", 8);
32
qdev_prop_set_uint32(DEVICE(&s->plic), "aperture-size", memmap[IBEX_DEV_PLIC].size);
33
--
34
2.31.1
35
36
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
The following changes:
4
1. Fixes the incorrectly set CTRL register address. As
5
per [1] https://docs.opentitan.org/hw/ip/rv_timer/doc/#register-table
6
7
The CTRL register is @ 0x04.
8
9
This was found when attempting to fixup a bug where a timer_interrupt
10
was not serviced on TockOS-OpenTitan.
11
12
2. Adds ALERT_TEST register as documented on [1], adding repective
13
switch cases to error handle and later implement functionality.
14
15
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Tested-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
19
Message-id: 20220111071025.4169189-2-alistair.francis@opensource.wdc.com
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
hw/timer/ibex_timer.c | 11 ++++++++++-
23
1 file changed, 10 insertions(+), 1 deletion(-)
24
25
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/timer/ibex_timer.c
28
+++ b/hw/timer/ibex_timer.c
29
@@ -XXX,XX +XXX,XX @@
30
#include "target/riscv/cpu.h"
31
#include "migration/vmstate.h"
32
33
-REG32(CTRL, 0x00)
34
+REG32(ALERT_TEST, 0x00)
35
+ FIELD(ALERT_TEST, FATAL_FAULT, 0, 1)
36
+REG32(CTRL, 0x04)
37
FIELD(CTRL, ACTIVE, 0, 1)
38
REG32(CFG0, 0x100)
39
FIELD(CFG0, PRESCALE, 0, 12)
40
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_timer_read(void *opaque, hwaddr addr,
41
uint64_t retvalue = 0;
42
43
switch (addr >> 2) {
44
+ case R_ALERT_TEST:
45
+ qemu_log_mask(LOG_GUEST_ERROR,
46
+ "Attempted to read ALERT_TEST, a write only register");
47
+ break;
48
case R_CTRL:
49
retvalue = s->timer_ctrl;
50
break;
51
@@ -XXX,XX +XXX,XX @@ static void ibex_timer_write(void *opaque, hwaddr addr,
52
uint32_t val = val64;
53
54
switch (addr >> 2) {
55
+ case R_ALERT_TEST:
56
+ qemu_log_mask(LOG_UNIMP, "Alert triggering not supported");
57
+ break;
58
case R_CTRL:
59
s->timer_ctrl = val;
60
break;
61
--
62
2.31.1
63
64
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
Add asm-riscv/kvm.h for RISC-V KVM.
4
5
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
6
Signed-off-by: Mingwang Li <limingwang@huawei.com>
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Anup Patel <anup.patel@wdc.com>
9
Message-id: 20220112081329.1835-2-jiangyifei@huawei.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
linux-headers/asm-riscv/kvm.h | 128 ++++++++++++++++++++++++++++++++++
13
1 file changed, 128 insertions(+)
14
create mode 100644 linux-headers/asm-riscv/kvm.h
15
16
diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h
17
new file mode 100644
18
index XXXXXXX..XXXXXXX
19
--- /dev/null
20
+++ b/linux-headers/asm-riscv/kvm.h
21
@@ -XXX,XX +XXX,XX @@
22
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
23
+/*
24
+ * Copyright (C) 2019 Western Digital Corporation or its affiliates.
25
+ *
26
+ * Authors:
27
+ * Anup Patel <anup.patel@wdc.com>
28
+ */
29
+
30
+#ifndef __LINUX_KVM_RISCV_H
31
+#define __LINUX_KVM_RISCV_H
32
+
33
+#ifndef __ASSEMBLY__
34
+
35
+#include <linux/types.h>
36
+#include <asm/ptrace.h>
37
+
38
+#define __KVM_HAVE_READONLY_MEM
39
+
40
+#define KVM_COALESCED_MMIO_PAGE_OFFSET 1
41
+
42
+#define KVM_INTERRUPT_SET    -1U
43
+#define KVM_INTERRUPT_UNSET    -2U
44
+
45
+/* for KVM_GET_REGS and KVM_SET_REGS */
46
+struct kvm_regs {
47
+};
48
+
49
+/* for KVM_GET_FPU and KVM_SET_FPU */
50
+struct kvm_fpu {
51
+};
52
+
53
+/* KVM Debug exit structure */
54
+struct kvm_debug_exit_arch {
55
+};
56
+
57
+/* for KVM_SET_GUEST_DEBUG */
58
+struct kvm_guest_debug_arch {
59
+};
60
+
61
+/* definition of registers in kvm_run */
62
+struct kvm_sync_regs {
63
+};
64
+
65
+/* for KVM_GET_SREGS and KVM_SET_SREGS */
66
+struct kvm_sregs {
67
+};
68
+
69
+/* CONFIG registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
70
+struct kvm_riscv_config {
71
+    unsigned long isa;
72
+};
73
+
74
+/* CORE registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
75
+struct kvm_riscv_core {
76
+    struct user_regs_struct regs;
77
+    unsigned long mode;
78
+};
79
+
80
+/* Possible privilege modes for kvm_riscv_core */
81
+#define KVM_RISCV_MODE_S    1
82
+#define KVM_RISCV_MODE_U    0
83
+
84
+/* CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
85
+struct kvm_riscv_csr {
86
+    unsigned long sstatus;
87
+    unsigned long sie;
88
+    unsigned long stvec;
89
+    unsigned long sscratch;
90
+    unsigned long sepc;
91
+    unsigned long scause;
92
+    unsigned long stval;
93
+    unsigned long sip;
94
+    unsigned long satp;
95
+    unsigned long scounteren;
96
+};
97
+
98
+/* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */
99
+struct kvm_riscv_timer {
100
+    __u64 frequency;
101
+    __u64 time;
102
+    __u64 compare;
103
+    __u64 state;
104
+};
105
+
106
+/* Possible states for kvm_riscv_timer */
107
+#define KVM_RISCV_TIMER_STATE_OFF    0
108
+#define KVM_RISCV_TIMER_STATE_ON    1
109
+
110
+#define KVM_REG_SIZE(id)        \
111
+    (1U << (((id) & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT))
112
+
113
+/* If you need to interpret the index values, here is the key: */
114
+#define KVM_REG_RISCV_TYPE_MASK        0x00000000FF000000
115
+#define KVM_REG_RISCV_TYPE_SHIFT    24
116
+
117
+/* Config registers are mapped as type 1 */
118
+#define KVM_REG_RISCV_CONFIG        (0x01 << KVM_REG_RISCV_TYPE_SHIFT)
119
+#define KVM_REG_RISCV_CONFIG_REG(name)    \
120
+    (offsetof(struct kvm_riscv_config, name) / sizeof(unsigned long))
121
+
122
+/* Core registers are mapped as type 2 */
123
+#define KVM_REG_RISCV_CORE        (0x02 << KVM_REG_RISCV_TYPE_SHIFT)
124
+#define KVM_REG_RISCV_CORE_REG(name)    \
125
+        (offsetof(struct kvm_riscv_core, name) / sizeof(unsigned long))
126
+
127
+/* Control and status registers are mapped as type 3 */
128
+#define KVM_REG_RISCV_CSR        (0x03 << KVM_REG_RISCV_TYPE_SHIFT)
129
+#define KVM_REG_RISCV_CSR_REG(name)    \
130
+        (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long))
131
+
132
+/* Timer registers are mapped as type 4 */
133
+#define KVM_REG_RISCV_TIMER        (0x04 << KVM_REG_RISCV_TYPE_SHIFT)
134
+#define KVM_REG_RISCV_TIMER_REG(name)    \
135
+        (offsetof(struct kvm_riscv_timer, name) / sizeof(__u64))
136
+
137
+/* F extension registers are mapped as type 5 */
138
+#define KVM_REG_RISCV_FP_F        (0x05 << KVM_REG_RISCV_TYPE_SHIFT)
139
+#define KVM_REG_RISCV_FP_F_REG(name)    \
140
+        (offsetof(struct __riscv_f_ext_state, name) / sizeof(__u32))
141
+
142
+/* D extension registers are mapped as type 6 */
143
+#define KVM_REG_RISCV_FP_D        (0x06 << KVM_REG_RISCV_TYPE_SHIFT)
144
+#define KVM_REG_RISCV_FP_D_REG(name)    \
145
+        (offsetof(struct __riscv_d_ext_state, name) / sizeof(__u64))
146
+
147
+#endif
148
+
149
+#endif /* __LINUX_KVM_RISCV_H */
150
--
151
2.31.1
152
153
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
Add target/riscv/kvm.c to place kvm_arch_* function needed by
4
kvm/kvm-all.c.
5
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Signed-off-by: Mingwang Li <limingwang@huawei.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Anup Patel <anup.patel@wdc.com>
10
Message-id: 20220112081329.1835-3-jiangyifei@huawei.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/kvm.c | 133 +++++++++++++++++++++++++++++++++++++++
14
target/riscv/meson.build | 1 +
15
2 files changed, 134 insertions(+)
16
create mode 100644 target/riscv/kvm.c
17
18
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/target/riscv/kvm.c
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * RISC-V implementation of KVM hooks
26
+ *
27
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
28
+ *
29
+ * This program is free software; you can redistribute it and/or modify it
30
+ * under the terms and conditions of the GNU General Public License,
31
+ * version 2 or later, as published by the Free Software Foundation.
32
+ *
33
+ * This program is distributed in the hope it will be useful, but WITHOUT
34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
35
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
36
+ * more details.
37
+ *
38
+ * You should have received a copy of the GNU General Public License along with
39
+ * this program. If not, see <http://www.gnu.org/licenses/>.
40
+ */
41
+
42
+#include "qemu/osdep.h"
43
+#include <sys/ioctl.h>
44
+
45
+#include <linux/kvm.h>
46
+
47
+#include "qemu-common.h"
48
+#include "qemu/timer.h"
49
+#include "qemu/error-report.h"
50
+#include "qemu/main-loop.h"
51
+#include "sysemu/sysemu.h"
52
+#include "sysemu/kvm.h"
53
+#include "sysemu/kvm_int.h"
54
+#include "cpu.h"
55
+#include "trace.h"
56
+#include "hw/pci/pci.h"
57
+#include "exec/memattrs.h"
58
+#include "exec/address-spaces.h"
59
+#include "hw/boards.h"
60
+#include "hw/irq.h"
61
+#include "qemu/log.h"
62
+#include "hw/loader.h"
63
+
64
+const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
65
+ KVM_CAP_LAST_INFO
66
+};
67
+
68
+int kvm_arch_get_registers(CPUState *cs)
69
+{
70
+ return 0;
71
+}
72
+
73
+int kvm_arch_put_registers(CPUState *cs, int level)
74
+{
75
+ return 0;
76
+}
77
+
78
+int kvm_arch_release_virq_post(int virq)
79
+{
80
+ return 0;
81
+}
82
+
83
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
84
+ uint64_t address, uint32_t data, PCIDevice *dev)
85
+{
86
+ return 0;
87
+}
88
+
89
+int kvm_arch_destroy_vcpu(CPUState *cs)
90
+{
91
+ return 0;
92
+}
93
+
94
+unsigned long kvm_arch_vcpu_id(CPUState *cpu)
95
+{
96
+ return cpu->cpu_index;
97
+}
98
+
99
+void kvm_arch_init_irq_routing(KVMState *s)
100
+{
101
+}
102
+
103
+int kvm_arch_init_vcpu(CPUState *cs)
104
+{
105
+ return 0;
106
+}
107
+
108
+int kvm_arch_msi_data_to_gsi(uint32_t data)
109
+{
110
+ abort();
111
+}
112
+
113
+int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
114
+ int vector, PCIDevice *dev)
115
+{
116
+ return 0;
117
+}
118
+
119
+int kvm_arch_init(MachineState *ms, KVMState *s)
120
+{
121
+ return 0;
122
+}
123
+
124
+int kvm_arch_irqchip_create(KVMState *s)
125
+{
126
+ return 0;
127
+}
128
+
129
+int kvm_arch_process_async_events(CPUState *cs)
130
+{
131
+ return 0;
132
+}
133
+
134
+void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
135
+{
136
+}
137
+
138
+MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
139
+{
140
+ return MEMTXATTRS_UNSPECIFIED;
141
+}
142
+
143
+bool kvm_arch_stop_on_emulation_error(CPUState *cs)
144
+{
145
+ return true;
146
+}
147
+
148
+int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
149
+{
150
+ return 0;
151
+}
152
+
153
+bool kvm_arch_cpu_check_are_resettable(void)
154
+{
155
+ return true;
156
+}
157
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
158
index XXXXXXX..XXXXXXX 100644
159
--- a/target/riscv/meson.build
160
+++ b/target/riscv/meson.build
161
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
162
'translate.c',
163
'm128_helper.c'
164
))
165
+riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
166
167
riscv_softmmu_ss = ss.source_set()
168
riscv_softmmu_ss.add(files(
169
--
170
2.31.1
171
172
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
Get isa info from kvm while kvm init.
4
5
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
6
Signed-off-by: Mingwang Li <limingwang@huawei.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Anup Patel <anup.patel@wdc.com>
9
Message-id: 20220112081329.1835-4-jiangyifei@huawei.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/kvm.c | 34 +++++++++++++++++++++++++++++++++-
13
1 file changed, 33 insertions(+), 1 deletion(-)
14
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/kvm.c
18
+++ b/target/riscv/kvm.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "qemu/log.h"
21
#include "hw/loader.h"
22
23
+static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
24
+ uint64_t idx)
25
+{
26
+ uint64_t id = KVM_REG_RISCV | type | idx;
27
+
28
+ switch (riscv_cpu_mxl(env)) {
29
+ case MXL_RV32:
30
+ id |= KVM_REG_SIZE_U32;
31
+ break;
32
+ case MXL_RV64:
33
+ id |= KVM_REG_SIZE_U64;
34
+ break;
35
+ default:
36
+ g_assert_not_reached();
37
+ }
38
+ return id;
39
+}
40
+
41
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
42
KVM_CAP_LAST_INFO
43
};
44
@@ -XXX,XX +XXX,XX @@ void kvm_arch_init_irq_routing(KVMState *s)
45
46
int kvm_arch_init_vcpu(CPUState *cs)
47
{
48
- return 0;
49
+ int ret = 0;
50
+ target_ulong isa;
51
+ RISCVCPU *cpu = RISCV_CPU(cs);
52
+ CPURISCVState *env = &cpu->env;
53
+ uint64_t id;
54
+
55
+ id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
56
+ KVM_REG_RISCV_CONFIG_REG(isa));
57
+ ret = kvm_get_one_reg(cs, id, &isa);
58
+ if (ret) {
59
+ return ret;
60
+ }
61
+ env->misa_ext = isa;
62
+
63
+ return ret;
64
}
65
66
int kvm_arch_msi_data_to_gsi(uint32_t data)
67
--
68
2.31.1
69
70
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
Get GPR CSR and FP registers from kvm by KVM_GET_ONE_REG ioctl.
4
5
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
6
Signed-off-by: Mingwang Li <limingwang@huawei.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Anup Patel <anup.patel@wdc.com>
9
Message-id: 20220112081329.1835-5-jiangyifei@huawei.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/kvm.c | 112 ++++++++++++++++++++++++++++++++++++++++++++-
13
1 file changed, 111 insertions(+), 1 deletion(-)
14
15
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/kvm.c
18
+++ b/target/riscv/kvm.c
19
@@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
20
return id;
21
}
22
23
+#define RISCV_CORE_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \
24
+ KVM_REG_RISCV_CORE_REG(name))
25
+
26
+#define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
27
+ KVM_REG_RISCV_CSR_REG(name))
28
+
29
+#define RISCV_FP_F_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, idx)
30
+
31
+#define RISCV_FP_D_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx)
32
+
33
+#define KVM_RISCV_GET_CSR(cs, env, csr, reg) \
34
+ do { \
35
+ int ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, csr), &reg); \
36
+ if (ret) { \
37
+ return ret; \
38
+ } \
39
+ } while (0)
40
+
41
+static int kvm_riscv_get_regs_core(CPUState *cs)
42
+{
43
+ int ret = 0;
44
+ int i;
45
+ target_ulong reg;
46
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
47
+
48
+ ret = kvm_get_one_reg(cs, RISCV_CORE_REG(env, regs.pc), &reg);
49
+ if (ret) {
50
+ return ret;
51
+ }
52
+ env->pc = reg;
53
+
54
+ for (i = 1; i < 32; i++) {
55
+ uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
56
+ ret = kvm_get_one_reg(cs, id, &reg);
57
+ if (ret) {
58
+ return ret;
59
+ }
60
+ env->gpr[i] = reg;
61
+ }
62
+
63
+ return ret;
64
+}
65
+
66
+static int kvm_riscv_get_regs_csr(CPUState *cs)
67
+{
68
+ int ret = 0;
69
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
70
+
71
+ KVM_RISCV_GET_CSR(cs, env, sstatus, env->mstatus);
72
+ KVM_RISCV_GET_CSR(cs, env, sie, env->mie);
73
+ KVM_RISCV_GET_CSR(cs, env, stvec, env->stvec);
74
+ KVM_RISCV_GET_CSR(cs, env, sscratch, env->sscratch);
75
+ KVM_RISCV_GET_CSR(cs, env, sepc, env->sepc);
76
+ KVM_RISCV_GET_CSR(cs, env, scause, env->scause);
77
+ KVM_RISCV_GET_CSR(cs, env, stval, env->stval);
78
+ KVM_RISCV_GET_CSR(cs, env, sip, env->mip);
79
+ KVM_RISCV_GET_CSR(cs, env, satp, env->satp);
80
+ return ret;
81
+}
82
+
83
+static int kvm_riscv_get_regs_fp(CPUState *cs)
84
+{
85
+ int ret = 0;
86
+ int i;
87
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
88
+
89
+ if (riscv_has_ext(env, RVD)) {
90
+ uint64_t reg;
91
+ for (i = 0; i < 32; i++) {
92
+ ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(env, i), &reg);
93
+ if (ret) {
94
+ return ret;
95
+ }
96
+ env->fpr[i] = reg;
97
+ }
98
+ return ret;
99
+ }
100
+
101
+ if (riscv_has_ext(env, RVF)) {
102
+ uint32_t reg;
103
+ for (i = 0; i < 32; i++) {
104
+ ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(env, i), &reg);
105
+ if (ret) {
106
+ return ret;
107
+ }
108
+ env->fpr[i] = reg;
109
+ }
110
+ return ret;
111
+ }
112
+
113
+ return ret;
114
+}
115
+
116
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
117
KVM_CAP_LAST_INFO
118
};
119
120
int kvm_arch_get_registers(CPUState *cs)
121
{
122
- return 0;
123
+ int ret = 0;
124
+
125
+ ret = kvm_riscv_get_regs_core(cs);
126
+ if (ret) {
127
+ return ret;
128
+ }
129
+
130
+ ret = kvm_riscv_get_regs_csr(cs);
131
+ if (ret) {
132
+ return ret;
133
+ }
134
+
135
+ ret = kvm_riscv_get_regs_fp(cs);
136
+ if (ret) {
137
+ return ret;
138
+ }
139
+
140
+ return ret;
141
}
142
143
int kvm_arch_put_registers(CPUState *cs, int level)
144
--
145
2.31.1
146
147
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
Currently, PMP permission checking of TLB page is bypassed if TLB hits
3
Put GPR CSR and FP registers to kvm by KVM_SET_ONE_REG ioctl
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
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
and size.
6
Signed-off-by: Mingwang Li <limingwang@huawei.com>
8
9
Signed-off-by: Jim Shu <cwshu@andestech.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-id: 1613916082-19528-2-git-send-email-cwshu@andestech.com
8
Reviewed-by: Anup Patel <anup.patel@wdc.com>
9
Message-id: 20220112081329.1835-6-jiangyifei@huawei.com
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
target/riscv/pmp.h | 4 +-
12
target/riscv/kvm.c | 104 ++++++++++++++++++++++++++++++++++++++++++++-
15
target/riscv/cpu_helper.c | 84 +++++++++++++++++++++++++++++----------
13
1 file changed, 103 insertions(+), 1 deletion(-)
16
target/riscv/pmp.c | 80 +++++++++++++++++++++++++++----------
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/kvm.c b/target/riscv/kvm.c
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.h
17
--- a/target/riscv/kvm.c
22
+++ b/target/riscv/pmp.h
18
+++ b/target/riscv/kvm.c
23
@@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
19
@@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
24
target_ulong val);
20
} \
25
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
21
} while (0)
26
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
22
27
- target_ulong size, pmp_priv_t priv, target_ulong mode);
23
+#define KVM_RISCV_SET_CSR(cs, env, csr, reg) \
28
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
24
+ do { \
29
+ target_ulong mode);
25
+ int ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, csr), &reg); \
30
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
26
+ if (ret) { \
31
target_ulong *tlb_size);
27
+ return ret; \
32
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
28
+ } \
33
void pmp_update_rule_nums(CPURISCVState *env);
29
+ } while (0)
34
uint32_t pmp_get_num_rules(CPURISCVState *env);
30
+
35
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
31
static int kvm_riscv_get_regs_core(CPUState *cs)
36
32
{
37
#endif
33
int ret = 0;
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
34
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_get_regs_core(CPUState *cs)
39
index XXXXXXX..XXXXXXX 100644
35
return ret;
40
--- a/target/riscv/cpu_helper.c
41
+++ b/target/riscv/cpu_helper.c
42
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
43
env->load_res = -1;
44
}
36
}
45
37
46
+/*
38
+static int kvm_riscv_put_regs_core(CPUState *cs)
47
+ * get_physical_address_pmp - check PMP permission for this physical address
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
+{
39
+{
65
+ pmp_priv_t pmp_priv;
40
+ int ret = 0;
66
+ target_ulong tlb_size_pmp = 0;
41
+ int i;
42
+ target_ulong reg;
43
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
67
+
44
+
68
+ if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
45
+ reg = env->pc;
69
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
46
+ ret = kvm_set_one_reg(cs, RISCV_CORE_REG(env, regs.pc), &reg);
70
+ return TRANSLATE_SUCCESS;
47
+ if (ret) {
48
+ return ret;
71
+ }
49
+ }
72
+
50
+
73
+ if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
51
+ for (i = 1; i < 32; i++) {
74
+ mode)) {
52
+ uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
75
+ *prot = 0;
53
+ reg = env->gpr[i];
76
+ return TRANSLATE_PMP_FAIL;
54
+ ret = kvm_set_one_reg(cs, id, &reg);
77
+ }
55
+ if (ret) {
78
+
56
+ return ret;
79
+ *prot = pmp_priv_to_page_prot(pmp_priv);
80
+ if (tlb_size != NULL) {
81
+ if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
82
+ *tlb_size = tlb_size_pmp;
83
+ }
57
+ }
84
+ }
85
+
86
+ return TRANSLATE_SUCCESS;
87
+}
88
+
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
109
vaddr im_address;
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
+ }
58
+ }
206
+
59
+
207
+ return ret;
60
+ return ret;
208
+}
61
+}
209
+
62
+
210
63
static int kvm_riscv_get_regs_csr(CPUState *cs)
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
{
64
{
221
int i = 0;
65
int ret = 0;
222
int ret = -1;
66
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_get_regs_csr(CPUState *cs)
223
int pmp_size = 0;
67
return ret;
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
}
68
}
275
69
276
-
70
+static int kvm_riscv_put_regs_csr(CPUState *cs)
277
/*
71
+{
278
* Handle a write to a pmpcfg CSP
72
+ int ret = 0;
279
*/
73
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
280
@@ -XXX,XX +XXX,XX @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
74
+
281
75
+ KVM_RISCV_SET_CSR(cs, env, sstatus, env->mstatus);
282
return false;
76
+ KVM_RISCV_SET_CSR(cs, env, sie, env->mie);
77
+ KVM_RISCV_SET_CSR(cs, env, stvec, env->stvec);
78
+ KVM_RISCV_SET_CSR(cs, env, sscratch, env->sscratch);
79
+ KVM_RISCV_SET_CSR(cs, env, sepc, env->sepc);
80
+ KVM_RISCV_SET_CSR(cs, env, scause, env->scause);
81
+ KVM_RISCV_SET_CSR(cs, env, stval, env->stval);
82
+ KVM_RISCV_SET_CSR(cs, env, sip, env->mip);
83
+ KVM_RISCV_SET_CSR(cs, env, satp, env->satp);
84
+
85
+ return ret;
86
+}
87
+
88
static int kvm_riscv_get_regs_fp(CPUState *cs)
89
{
90
int ret = 0;
91
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_get_regs_fp(CPUState *cs)
92
return ret;
283
}
93
}
94
95
+static int kvm_riscv_put_regs_fp(CPUState *cs)
96
+{
97
+ int ret = 0;
98
+ int i;
99
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
284
+
100
+
285
+/*
101
+ if (riscv_has_ext(env, RVD)) {
286
+ * Convert PMP privilege to TLB page privilege.
102
+ uint64_t reg;
287
+ */
103
+ for (i = 0; i < 32; i++) {
288
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
104
+ reg = env->fpr[i];
289
+{
105
+ ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(env, i), &reg);
290
+ int prot = 0;
106
+ if (ret) {
291
+
107
+ return ret;
292
+ if (pmp_priv & PMP_READ) {
108
+ }
293
+ prot |= PAGE_READ;
109
+ }
294
+ }
110
+ return ret;
295
+ if (pmp_priv & PMP_WRITE) {
296
+ prot |= PAGE_WRITE;
297
+ }
298
+ if (pmp_priv & PMP_EXEC) {
299
+ prot |= PAGE_EXEC;
300
+ }
111
+ }
301
+
112
+
302
+ return prot;
113
+ if (riscv_has_ext(env, RVF)) {
114
+ uint32_t reg;
115
+ for (i = 0; i < 32; i++) {
116
+ reg = env->fpr[i];
117
+ ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(env, i), &reg);
118
+ if (ret) {
119
+ return ret;
120
+ }
121
+ }
122
+ return ret;
123
+ }
124
+
125
+ return ret;
303
+}
126
+}
127
+
128
+
129
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
130
KVM_CAP_LAST_INFO
131
};
132
@@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs)
133
134
int kvm_arch_put_registers(CPUState *cs, int level)
135
{
136
- return 0;
137
+ int ret = 0;
138
+
139
+ ret = kvm_riscv_put_regs_core(cs);
140
+ if (ret) {
141
+ return ret;
142
+ }
143
+
144
+ ret = kvm_riscv_put_regs_csr(cs);
145
+ if (ret) {
146
+ return ret;
147
+ }
148
+
149
+ ret = kvm_riscv_put_regs_fp(cs);
150
+ if (ret) {
151
+ return ret;
152
+ }
153
+
154
+ return ret;
155
}
156
157
int kvm_arch_release_virq_post(int virq)
304
--
158
--
305
2.30.1
159
2.31.1
306
160
307
161
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
Allow ramfb on virt. This lets `-device ramfb' work.
3
Get kernel and fdt start address in virt.c, and pass them to KVM
4
4
when cpu reset. Add kvm_riscv.h to place riscv specific interface.
5
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
5
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
6
In addition, PLIC is created without M-mode PLIC contexts when KVM
7
is enabled.
8
9
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
10
Signed-off-by: Mingwang Li <limingwang@huawei.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210318235041.17175-3-ashe@kivikakk.ee
12
Reviewed-by: Anup Patel <anup@brainfault.org>
13
Message-id: 20220112081329.1835-7-jiangyifei@huawei.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
hw/riscv/virt.c | 3 +++
16
include/hw/riscv/boot.h | 1 +
12
1 file changed, 3 insertions(+)
17
target/riscv/cpu.h | 3 ++
13
18
target/riscv/kvm_riscv.h | 24 ++++++++++++
19
hw/intc/sifive_plic.c | 20 +++++++---
20
hw/riscv/boot.c | 16 +++++++-
21
hw/riscv/virt.c | 83 ++++++++++++++++++++++++++++------------
22
target/riscv/cpu.c | 8 ++++
23
target/riscv/kvm-stub.c | 25 ++++++++++++
24
target/riscv/kvm.c | 14 +++++++
25
target/riscv/meson.build | 2 +-
26
10 files changed, 164 insertions(+), 32 deletions(-)
27
create mode 100644 target/riscv/kvm_riscv.h
28
create mode 100644 target/riscv/kvm-stub.c
29
30
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/include/hw/riscv/boot.h
33
+++ b/include/hw/riscv/boot.h
34
@@ -XXX,XX +XXX,XX @@ void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
35
hwaddr rom_size,
36
uint32_t reset_vec_size,
37
uint64_t kernel_entry);
38
+void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr);
39
40
#endif /* RISCV_BOOT_H */
41
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/riscv/cpu.h
44
+++ b/target/riscv/cpu.h
45
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
46
47
/* Fields from here on are preserved across CPU reset. */
48
QEMUTimer *timer; /* Internal timer */
49
+
50
+ hwaddr kernel_addr;
51
+ hwaddr fdt_addr;
52
};
53
54
OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
55
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
56
new file mode 100644
57
index XXXXXXX..XXXXXXX
58
--- /dev/null
59
+++ b/target/riscv/kvm_riscv.h
60
@@ -XXX,XX +XXX,XX @@
61
+/*
62
+ * QEMU KVM support -- RISC-V specific functions.
63
+ *
64
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
65
+ *
66
+ * This program is free software; you can redistribute it and/or modify it
67
+ * under the terms and conditions of the GNU General Public License,
68
+ * version 2 or later, as published by the Free Software Foundation.
69
+ *
70
+ * This program is distributed in the hope it will be useful, but WITHOUT
71
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
72
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
73
+ * more details.
74
+ *
75
+ * You should have received a copy of the GNU General Public License along with
76
+ * this program. If not, see <http://www.gnu.org/licenses/>.
77
+ */
78
+
79
+#ifndef QEMU_KVM_RISCV_H
80
+#define QEMU_KVM_RISCV_H
81
+
82
+void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
83
+
84
+#endif
85
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
86
index XXXXXXX..XXXXXXX 100644
87
--- a/hw/intc/sifive_plic.c
88
+++ b/hw/intc/sifive_plic.c
89
@@ -XXX,XX +XXX,XX @@
90
#include "target/riscv/cpu.h"
91
#include "migration/vmstate.h"
92
#include "hw/irq.h"
93
+#include "sysemu/kvm.h"
94
95
static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
96
{
97
@@ -XXX,XX +XXX,XX @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
98
uint32_t context_stride, uint32_t aperture_size)
99
{
100
DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
101
- int i;
102
+ int i, j = 0;
103
+ SiFivePLICState *plic;
104
105
assert(enable_stride == (enable_stride & -enable_stride));
106
assert(context_stride == (context_stride & -context_stride));
107
@@ -XXX,XX +XXX,XX @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
108
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
109
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
110
111
+ plic = SIFIVE_PLIC(dev);
112
for (i = 0; i < num_harts; i++) {
113
CPUState *cpu = qemu_get_cpu(hartid_base + i);
114
115
- qdev_connect_gpio_out(dev, i,
116
- qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
117
- qdev_connect_gpio_out(dev, num_harts + i,
118
- qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
119
+ if (plic->addr_config[j].mode == PLICMode_M) {
120
+ j++;
121
+ qdev_connect_gpio_out(dev, num_harts + i,
122
+ qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
123
+ }
124
+
125
+ if (plic->addr_config[j].mode == PLICMode_S) {
126
+ j++;
127
+ qdev_connect_gpio_out(dev, i,
128
+ qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
129
+ }
130
}
131
132
return dev;
133
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/riscv/boot.c
136
+++ b/hw/riscv/boot.c
137
@@ -XXX,XX +XXX,XX @@
138
#include "elf.h"
139
#include "sysemu/device_tree.h"
140
#include "sysemu/qtest.h"
141
+#include "sysemu/kvm.h"
142
143
#include <libfdt.h>
144
145
@@ -XXX,XX +XXX,XX @@ char *riscv_plic_hart_config_string(int hart_count)
146
CPUState *cs = qemu_get_cpu(i);
147
CPURISCVState *env = &RISCV_CPU(cs)->env;
148
149
- if (riscv_has_ext(env, RVS)) {
150
+ if (kvm_enabled()) {
151
+ vals[i] = "S";
152
+ } else if (riscv_has_ext(env, RVS)) {
153
vals[i] = "MS";
154
} else {
155
vals[i] = "M";
156
@@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts
157
158
return;
159
}
160
+
161
+void riscv_setup_direct_kernel(hwaddr kernel_addr, hwaddr fdt_addr)
162
+{
163
+ CPUState *cs;
164
+
165
+ for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
166
+ RISCVCPU *riscv_cpu = RISCV_CPU(cs);
167
+ riscv_cpu->env.kernel_addr = kernel_addr;
168
+ riscv_cpu->env.fdt_addr = fdt_addr;
169
+ }
170
+}
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
171
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
172
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
173
--- a/hw/riscv/virt.c
17
+++ b/hw/riscv/virt.c
174
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@
175
@@ -XXX,XX +XXX,XX @@
176
#include "chardev/char.h"
177
#include "sysemu/device_tree.h"
19
#include "sysemu/sysemu.h"
178
#include "sysemu/sysemu.h"
179
+#include "sysemu/kvm.h"
20
#include "hw/pci/pci.h"
180
#include "hw/pci/pci.h"
21
#include "hw/pci-host/gpex.h"
181
#include "hw/pci-host/gpex.h"
22
+#include "hw/display/ramfb.h"
182
#include "hw/display/ramfb.h"
23
183
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
24
static const MemMapEntry virt_memmap[] = {
184
"sifive,plic-1.0.0", "riscv,plic0"
25
[VIRT_DEBUG] = { 0x0, 0x100 },
185
};
26
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
186
27
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
187
- plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
28
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
188
+ if (kvm_enabled()) {
29
mc->numa_mem_supported = true;
189
+ plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
30
+
190
+ } else {
31
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
191
+ plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4);
192
+ }
193
194
for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
195
- plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
196
- plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
197
- plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
198
- plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
199
+ if (kvm_enabled()) {
200
+ plic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
201
+ plic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT);
202
+ } else {
203
+ plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]);
204
+ plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT);
205
+ plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]);
206
+ plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT);
207
+ }
208
}
209
210
plic_phandles[socket] = (*phandle)++;
211
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
212
213
create_fdt_socket_memory(s, memmap, socket);
214
215
- if (s->have_aclint) {
216
- create_fdt_socket_aclint(s, memmap, socket, intc_phandles);
217
- } else {
218
- create_fdt_socket_clint(s, memmap, socket, intc_phandles);
219
+ if (!kvm_enabled()) {
220
+ if (s->have_aclint) {
221
+ create_fdt_socket_aclint(s, memmap, socket, intc_phandles);
222
+ } else {
223
+ create_fdt_socket_clint(s, memmap, socket, intc_phandles);
224
+ }
225
}
226
227
create_fdt_socket_plic(s, memmap, socket, phandle,
228
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
229
hart_count, &error_abort);
230
sysbus_realize(SYS_BUS_DEVICE(&s->soc[i]), &error_abort);
231
232
- /* Per-socket CLINT */
233
- riscv_aclint_swi_create(
234
- memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size,
235
- base_hartid, hart_count, false);
236
- riscv_aclint_mtimer_create(
237
- memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size +
238
- RISCV_ACLINT_SWI_SIZE,
239
- RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count,
240
- RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
241
- RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true);
242
-
243
- /* Per-socket ACLINT SSWI */
244
- if (s->have_aclint) {
245
+ if (!kvm_enabled()) {
246
+ /* Per-socket CLINT */
247
riscv_aclint_swi_create(
248
- memmap[VIRT_ACLINT_SSWI].base +
249
- i * memmap[VIRT_ACLINT_SSWI].size,
250
- base_hartid, hart_count, true);
251
+ memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size,
252
+ base_hartid, hart_count, false);
253
+ riscv_aclint_mtimer_create(
254
+ memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size +
255
+ RISCV_ACLINT_SWI_SIZE,
256
+ RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count,
257
+ RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME,
258
+ RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true);
259
+
260
+ /* Per-socket ACLINT SSWI */
261
+ if (s->have_aclint) {
262
+ riscv_aclint_swi_create(
263
+ memmap[VIRT_ACLINT_SSWI].base +
264
+ i * memmap[VIRT_ACLINT_SSWI].size,
265
+ base_hartid, hart_count, true);
266
+ }
267
}
268
269
/* Per-socket PLIC hart topology configuration string */
270
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
271
memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
272
mask_rom);
273
274
+ /*
275
+ * Only direct boot kernel is currently supported for KVM VM,
276
+ * so the "-bios" parameter is ignored and treated like "-bios none"
277
+ * when KVM is enabled.
278
+ */
279
+ if (kvm_enabled()) {
280
+ g_free(machine->firmware);
281
+ machine->firmware = g_strdup("none");
282
+ }
283
+
284
if (riscv_is_32bit(&s->soc[0])) {
285
firmware_end_addr = riscv_find_and_load_firmware(machine,
286
RISCV32_BIOS_BIN, start_addr, NULL);
287
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
288
virt_memmap[VIRT_MROM].size, kernel_entry,
289
fdt_load_addr, machine->fdt);
290
291
+ /*
292
+ * Only direct boot kernel is currently supported for KVM VM,
293
+ * So here setup kernel start address and fdt address.
294
+ * TODO:Support firmware loading and integrate to TCG start
295
+ */
296
+ if (kvm_enabled()) {
297
+ riscv_setup_direct_kernel(kernel_entry, fdt_load_addr);
298
+ }
299
+
300
/* SiFive Test MMIO device */
301
sifive_test_create(memmap[VIRT_TEST].base);
302
303
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
304
index XXXXXXX..XXXXXXX 100644
305
--- a/target/riscv/cpu.c
306
+++ b/target/riscv/cpu.c
307
@@ -XXX,XX +XXX,XX @@
308
#include "hw/qdev-properties.h"
309
#include "migration/vmstate.h"
310
#include "fpu/softfloat-helpers.h"
311
+#include "sysemu/kvm.h"
312
+#include "kvm_riscv.h"
313
314
/* RISC-V CPU definitions */
315
316
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
317
cs->exception_index = RISCV_EXCP_NONE;
318
env->load_res = -1;
319
set_default_nan_mode(1, &env->fp_status);
320
+
321
+#ifndef CONFIG_USER_ONLY
322
+ if (kvm_enabled()) {
323
+ kvm_riscv_reset_vcpu(cpu);
324
+ }
325
+#endif
32
}
326
}
33
327
34
static const TypeInfo virt_machine_typeinfo = {
328
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
329
diff --git a/target/riscv/kvm-stub.c b/target/riscv/kvm-stub.c
330
new file mode 100644
331
index XXXXXXX..XXXXXXX
332
--- /dev/null
333
+++ b/target/riscv/kvm-stub.c
334
@@ -XXX,XX +XXX,XX @@
335
+/*
336
+ * QEMU KVM RISC-V specific function stubs
337
+ *
338
+ * Copyright (c) 2020 Huawei Technologies Co., Ltd
339
+ *
340
+ * This program is free software; you can redistribute it and/or modify it
341
+ * under the terms and conditions of the GNU General Public License,
342
+ * version 2 or later, as published by the Free Software Foundation.
343
+ *
344
+ * This program is distributed in the hope it will be useful, but WITHOUT
345
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
346
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
347
+ * more details.
348
+ *
349
+ * You should have received a copy of the GNU General Public License along with
350
+ * this program. If not, see <http://www.gnu.org/licenses/>.
351
+ */
352
+#include "qemu/osdep.h"
353
+#include "cpu.h"
354
+#include "kvm_riscv.h"
355
+
356
+void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
357
+{
358
+ abort();
359
+}
360
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
361
index XXXXXXX..XXXXXXX 100644
362
--- a/target/riscv/kvm.c
363
+++ b/target/riscv/kvm.c
364
@@ -XXX,XX +XXX,XX @@
365
#include "hw/irq.h"
366
#include "qemu/log.h"
367
#include "hw/loader.h"
368
+#include "kvm_riscv.h"
369
370
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
371
uint64_t idx)
372
@@ -XXX,XX +XXX,XX @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
373
return 0;
374
}
375
376
+void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
377
+{
378
+ CPURISCVState *env = &cpu->env;
379
+
380
+ if (!kvm_enabled()) {
381
+ return;
382
+ }
383
+ env->pc = cpu->env.kernel_addr;
384
+ env->gpr[10] = kvm_arch_vcpu_id(CPU(cpu)); /* a0 */
385
+ env->gpr[11] = cpu->env.fdt_addr; /* a1 */
386
+ env->satp = 0;
387
+}
388
+
389
bool kvm_arch_cpu_check_are_resettable(void)
390
{
391
return true;
392
diff --git a/target/riscv/meson.build b/target/riscv/meson.build
393
index XXXXXXX..XXXXXXX 100644
394
--- a/target/riscv/meson.build
395
+++ b/target/riscv/meson.build
396
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(files(
397
'translate.c',
398
'm128_helper.c'
399
))
400
-riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
401
+riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c'))
402
403
riscv_softmmu_ss = ss.source_set()
404
riscv_softmmu_ss.add(files(
35
--
405
--
36
2.30.1
406
2.31.1
37
407
38
408
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
When KVM is enabled, set the S-mode external interrupt through
4
kvm_riscv_set_irq function.
5
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Signed-off-by: Mingwang Li <limingwang@huawei.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Anup Patel <anup.patel@wdc.com>
10
Message-id: 20220112081329.1835-8-jiangyifei@huawei.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/kvm_riscv.h | 1 +
14
target/riscv/cpu.c | 6 +++++-
15
target/riscv/kvm-stub.c | 5 +++++
16
target/riscv/kvm.c | 17 +++++++++++++++++
17
4 files changed, 28 insertions(+), 1 deletion(-)
18
19
diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/kvm_riscv.h
22
+++ b/target/riscv/kvm_riscv.h
23
@@ -XXX,XX +XXX,XX @@
24
#define QEMU_KVM_RISCV_H
25
26
void kvm_riscv_reset_vcpu(RISCVCPU *cpu);
27
+void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);
28
29
#endif
30
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/cpu.c
33
+++ b/target/riscv/cpu.c
34
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
35
case IRQ_S_EXT:
36
case IRQ_VS_EXT:
37
case IRQ_M_EXT:
38
- riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
39
+ if (kvm_enabled()) {
40
+ kvm_riscv_set_irq(cpu, irq, level);
41
+ } else {
42
+ riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
43
+ }
44
break;
45
default:
46
g_assert_not_reached();
47
diff --git a/target/riscv/kvm-stub.c b/target/riscv/kvm-stub.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/kvm-stub.c
50
+++ b/target/riscv/kvm-stub.c
51
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
52
{
53
abort();
54
}
55
+
56
+void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level)
57
+{
58
+ abort();
59
+}
60
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/target/riscv/kvm.c
63
+++ b/target/riscv/kvm.c
64
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
65
env->satp = 0;
66
}
67
68
+void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level)
69
+{
70
+ int ret;
71
+ unsigned virq = level ? KVM_INTERRUPT_SET : KVM_INTERRUPT_UNSET;
72
+
73
+ if (irq != IRQ_S_EXT) {
74
+ perror("kvm riscv set irq != IRQ_S_EXT\n");
75
+ abort();
76
+ }
77
+
78
+ ret = kvm_vcpu_ioctl(CPU(cpu), KVM_INTERRUPT, &virq);
79
+ if (ret < 0) {
80
+ perror("Set irq failed");
81
+ abort();
82
+ }
83
+}
84
+
85
bool kvm_arch_cpu_check_are_resettable(void)
86
{
87
return true;
88
--
89
2.31.1
90
91
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Yifei Jiang <jiangyifei@huawei.com>
2
2
3
This adds the documentation to describe what is supported for the
3
Use char-fe to handle console sbi call, which implement early
4
'microchip-icicle-kit' machine, and how to boot the machine in QEMU.
4
console io while apply 'earlycon=sbi' into kernel parameters.
5
5
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Signed-off-by: Mingwang Li <limingwang@huawei.com>
8
Reviewed-by: Anup Patel <anup.patel@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210322075248.136255-2-bmeng.cn@gmail.com
10
Message-id: 20220112081329.1835-9-jiangyifei@huawei.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++++++++++
13
target/riscv/sbi_ecall_interface.h | 72 ++++++++++++++++++++++++++++++
12
docs/system/target-riscv.rst | 1 +
14
target/riscv/kvm.c | 42 ++++++++++++++++-
13
2 files changed, 90 insertions(+)
15
2 files changed, 113 insertions(+), 1 deletion(-)
14
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
16
create mode 100644 target/riscv/sbi_ecall_interface.h
15
17
16
diff --git a/docs/system/riscv/microchip-icicle-kit.rst b/docs/system/riscv/microchip-icicle-kit.rst
18
diff --git a/target/riscv/sbi_ecall_interface.h b/target/riscv/sbi_ecall_interface.h
17
new file mode 100644
19
new file mode 100644
18
index XXXXXXX..XXXXXXX
20
index XXXXXXX..XXXXXXX
19
--- /dev/null
21
--- /dev/null
20
+++ b/docs/system/riscv/microchip-icicle-kit.rst
22
+++ b/target/riscv/sbi_ecall_interface.h
21
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@
22
+Microchip PolarFire SoC Icicle Kit (``microchip-icicle-kit``)
24
+/*
23
+=============================================================
25
+ * SPDX-License-Identifier: BSD-2-Clause
26
+ *
27
+ * Copyright (c) 2019 Western Digital Corporation or its affiliates.
28
+ *
29
+ * Authors:
30
+ * Anup Patel <anup.patel@wdc.com>
31
+ */
24
+
32
+
25
+Microchip PolarFire SoC Icicle Kit integrates a PolarFire SoC, with one
33
+#ifndef __SBI_ECALL_INTERFACE_H__
26
+SiFive's E51 plus four U54 cores and many on-chip peripherals and an FPGA.
34
+#define __SBI_ECALL_INTERFACE_H__
27
+
35
+
28
+For more details about Microchip PolarFire SoC, please see:
36
+/* clang-format off */
29
+https://www.microsemi.com/product-directory/soc-fpgas/5498-polarfire-soc-fpga
30
+
37
+
31
+The Icicle Kit board information can be found here:
38
+/* SBI Extension IDs */
32
+https://www.microsemi.com/existing-parts/parts/152514
39
+#define SBI_EXT_0_1_SET_TIMER 0x0
40
+#define SBI_EXT_0_1_CONSOLE_PUTCHAR 0x1
41
+#define SBI_EXT_0_1_CONSOLE_GETCHAR 0x2
42
+#define SBI_EXT_0_1_CLEAR_IPI 0x3
43
+#define SBI_EXT_0_1_SEND_IPI 0x4
44
+#define SBI_EXT_0_1_REMOTE_FENCE_I 0x5
45
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA 0x6
46
+#define SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID 0x7
47
+#define SBI_EXT_0_1_SHUTDOWN 0x8
48
+#define SBI_EXT_BASE 0x10
49
+#define SBI_EXT_TIME 0x54494D45
50
+#define SBI_EXT_IPI 0x735049
51
+#define SBI_EXT_RFENCE 0x52464E43
52
+#define SBI_EXT_HSM 0x48534D
33
+
53
+
34
+Supported devices
54
+/* SBI function IDs for BASE extension*/
35
+-----------------
55
+#define SBI_EXT_BASE_GET_SPEC_VERSION 0x0
56
+#define SBI_EXT_BASE_GET_IMP_ID 0x1
57
+#define SBI_EXT_BASE_GET_IMP_VERSION 0x2
58
+#define SBI_EXT_BASE_PROBE_EXT 0x3
59
+#define SBI_EXT_BASE_GET_MVENDORID 0x4
60
+#define SBI_EXT_BASE_GET_MARCHID 0x5
61
+#define SBI_EXT_BASE_GET_MIMPID 0x6
36
+
62
+
37
+The ``microchip-icicle-kit`` machine supports the following devices:
63
+/* SBI function IDs for TIME extension*/
64
+#define SBI_EXT_TIME_SET_TIMER 0x0
38
+
65
+
39
+ * 1 E51 core
66
+/* SBI function IDs for IPI extension*/
40
+ * 4 U54 cores
67
+#define SBI_EXT_IPI_SEND_IPI 0x0
41
+ * Core Level Interruptor (CLINT)
42
+ * Platform-Level Interrupt Controller (PLIC)
43
+ * L2 Loosely Integrated Memory (L2-LIM)
44
+ * DDR memory controller
45
+ * 5 MMUARTs
46
+ * 1 DMA controller
47
+ * 2 GEM Ethernet controllers
48
+ * 1 SDHC storage controller
49
+
68
+
50
+Boot options
69
+/* SBI function IDs for RFENCE extension*/
51
+------------
70
+#define SBI_EXT_RFENCE_REMOTE_FENCE_I 0x0
71
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA 0x1
72
+#define SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID 0x2
73
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA 0x3
74
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID 0x4
75
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA 0x5
76
+#define SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID 0x6
52
+
77
+
53
+The ``microchip-icicle-kit`` machine can start using the standard -bios
78
+/* SBI function IDs for HSM extension */
54
+functionality for loading its BIOS image, aka Hart Software Services (HSS_).
79
+#define SBI_EXT_HSM_HART_START 0x0
55
+HSS loads the second stage bootloader U-Boot from an SD card. It does not
80
+#define SBI_EXT_HSM_HART_STOP 0x1
56
+support direct kernel loading via the -kernel option. One has to load kernel
81
+#define SBI_EXT_HSM_HART_GET_STATUS 0x2
57
+from U-Boot.
58
+
82
+
59
+The memory is set to 1537 MiB by default which is the minimum required high
83
+#define SBI_HSM_HART_STATUS_STARTED 0x0
60
+memory size by HSS. A sanity check on ram size is performed in the machine
84
+#define SBI_HSM_HART_STATUS_STOPPED 0x1
61
+init routine to prompt user to increase the RAM size to > 1537 MiB when less
85
+#define SBI_HSM_HART_STATUS_START_PENDING 0x2
62
+than 1537 MiB ram is detected.
86
+#define SBI_HSM_HART_STATUS_STOP_PENDING 0x3
63
+
87
+
64
+Boot the machine
88
+#define SBI_SPEC_VERSION_MAJOR_OFFSET 24
65
+----------------
89
+#define SBI_SPEC_VERSION_MAJOR_MASK 0x7f
90
+#define SBI_SPEC_VERSION_MINOR_MASK 0xffffff
91
+#define SBI_EXT_VENDOR_START 0x09000000
92
+#define SBI_EXT_VENDOR_END 0x09FFFFFF
93
+/* clang-format on */
66
+
94
+
67
+HSS 2020.12 release is tested at the time of writing. To build an HSS image
95
+#endif
68
+that can be booted by the ``microchip-icicle-kit`` machine, type the following
96
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
69
+in the HSS source tree:
97
index XXXXXXX..XXXXXXX 100644
98
--- a/target/riscv/kvm.c
99
+++ b/target/riscv/kvm.c
100
@@ -XXX,XX +XXX,XX @@
101
#include "qemu/log.h"
102
#include "hw/loader.h"
103
#include "kvm_riscv.h"
104
+#include "sbi_ecall_interface.h"
105
+#include "chardev/char-fe.h"
106
107
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
108
uint64_t idx)
109
@@ -XXX,XX +XXX,XX @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs)
110
return true;
111
}
112
113
+static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
114
+{
115
+ int ret = 0;
116
+ unsigned char ch;
117
+ switch (run->riscv_sbi.extension_id) {
118
+ case SBI_EXT_0_1_CONSOLE_PUTCHAR:
119
+ ch = run->riscv_sbi.args[0];
120
+ qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
121
+ break;
122
+ case SBI_EXT_0_1_CONSOLE_GETCHAR:
123
+ ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
124
+ if (ret == sizeof(ch)) {
125
+ run->riscv_sbi.args[0] = ch;
126
+ } else {
127
+ run->riscv_sbi.args[0] = -1;
128
+ }
129
+ break;
130
+ default:
131
+ qemu_log_mask(LOG_UNIMP,
132
+ "%s: un-handled SBI EXIT, specific reasons is %lu\n",
133
+ __func__, run->riscv_sbi.extension_id);
134
+ ret = -1;
135
+ break;
136
+ }
137
+ return ret;
138
+}
70
+
139
+
71
+.. code-block:: bash
140
int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
72
+
141
{
73
+ $ export CROSS_COMPILE=riscv64-linux-
142
- return 0;
74
+ $ cp boards/mpfs-icicle-kit-es/def_config .config
143
+ int ret = 0;
75
+ $ make BOARD=mpfs-icicle-kit-es
144
+ switch (run->exit_reason) {
76
+
145
+ case KVM_EXIT_RISCV_SBI:
77
+Download the official SD card image released by Microchip and prepare it for
146
+ ret = kvm_riscv_handle_sbi(cs, run);
78
+QEMU usage:
147
+ break;
79
+
148
+ default:
80
+.. code-block:: bash
149
+ qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
81
+
150
+ __func__, run->exit_reason);
82
+ $ wget ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
151
+ ret = -1;
83
+ $ gunzip core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
152
+ break;
84
+ $ qemu-img resize core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic 4G
153
+ }
85
+
154
+ return ret;
86
+Then we can boot the machine by:
155
}
87
+
156
88
+.. code-block:: bash
157
void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
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
--
158
--
124
2.30.1
159
2.31.1
125
160
126
161
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
'host' type cpu is set isa to RV32 or RV64 simply, more isa info
4
will obtain from KVM in kvm_arch_init_vcpu()
5
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Signed-off-by: Mingwang Li <limingwang@huawei.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Anup Patel <anup.patel@wdc.com>
10
Message-id: 20220112081329.1835-10-jiangyifei@huawei.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.h | 1 +
14
target/riscv/cpu.c | 15 +++++++++++++++
15
2 files changed, 16 insertions(+)
16
17
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.h
20
+++ b/target/riscv/cpu.h
21
@@ -XXX,XX +XXX,XX @@
22
#define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51")
23
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
24
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
25
+#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
26
27
#if defined(TARGET_RISCV32)
28
# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE32
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
34
}
35
#endif
36
37
+#if defined(CONFIG_KVM)
38
+static void riscv_host_cpu_init(Object *obj)
39
+{
40
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
41
+#if defined(TARGET_RISCV32)
42
+ set_misa(env, MXL_RV32, 0);
43
+#elif defined(TARGET_RISCV64)
44
+ set_misa(env, MXL_RV64, 0);
45
+#endif
46
+}
47
+#endif
48
+
49
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
50
{
51
ObjectClass *oc;
52
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
53
.class_init = riscv_cpu_class_init,
54
},
55
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
56
+#if defined(CONFIG_KVM)
57
+ DEFINE_CPU(TYPE_RISCV_CPU_HOST, riscv_host_cpu_init),
58
+#endif
59
#if defined(TARGET_RISCV32)
60
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init),
61
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
62
--
63
2.31.1
64
65
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
Add kvm_riscv_get/put_regs_timer to synchronize virtual time context
4
from KVM.
5
6
To set register of RISCV_TIMER_REG(state) will occur a error from KVM
7
on kvm_timer_state == 0. It's better to adapt in KVM, but it doesn't matter
8
that adaping in QEMU.
9
10
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
11
Signed-off-by: Mingwang Li <limingwang@huawei.com>
12
Reviewed-by: Anup Patel <anup.patel@wdc.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-id: 20220112081329.1835-11-jiangyifei@huawei.com
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/cpu.h | 7 +++++
18
target/riscv/kvm.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
19
2 files changed, 79 insertions(+)
20
21
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu.h
24
+++ b/target/riscv/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
26
27
hwaddr kernel_addr;
28
hwaddr fdt_addr;
29
+
30
+ /* kvm timer */
31
+ bool kvm_timer_dirty;
32
+ uint64_t kvm_timer_time;
33
+ uint64_t kvm_timer_compare;
34
+ uint64_t kvm_timer_state;
35
+ uint64_t kvm_timer_frequency;
36
};
37
38
OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass,
39
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/kvm.c
42
+++ b/target/riscv/kvm.c
43
@@ -XXX,XX +XXX,XX @@
44
#include "kvm_riscv.h"
45
#include "sbi_ecall_interface.h"
46
#include "chardev/char-fe.h"
47
+#include "migration/migration.h"
48
49
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
50
uint64_t idx)
51
@@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
52
#define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
53
KVM_REG_RISCV_CSR_REG(name))
54
55
+#define RISCV_TIMER_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_TIMER, \
56
+ KVM_REG_RISCV_TIMER_REG(name))
57
+
58
#define RISCV_FP_F_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, idx)
59
60
#define RISCV_FP_D_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx)
61
@@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
62
} \
63
} while (0)
64
65
+#define KVM_RISCV_GET_TIMER(cs, env, name, reg) \
66
+ do { \
67
+ int ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, name), &reg); \
68
+ if (ret) { \
69
+ abort(); \
70
+ } \
71
+ } while (0)
72
+
73
+#define KVM_RISCV_SET_TIMER(cs, env, name, reg) \
74
+ do { \
75
+ int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, time), &reg); \
76
+ if (ret) { \
77
+ abort(); \
78
+ } \
79
+ } while (0)
80
+
81
static int kvm_riscv_get_regs_core(CPUState *cs)
82
{
83
int ret = 0;
84
@@ -XXX,XX +XXX,XX @@ static int kvm_riscv_put_regs_fp(CPUState *cs)
85
return ret;
86
}
87
88
+static void kvm_riscv_get_regs_timer(CPUState *cs)
89
+{
90
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
91
+
92
+ if (env->kvm_timer_dirty) {
93
+ return;
94
+ }
95
+
96
+ KVM_RISCV_GET_TIMER(cs, env, time, env->kvm_timer_time);
97
+ KVM_RISCV_GET_TIMER(cs, env, compare, env->kvm_timer_compare);
98
+ KVM_RISCV_GET_TIMER(cs, env, state, env->kvm_timer_state);
99
+ KVM_RISCV_GET_TIMER(cs, env, frequency, env->kvm_timer_frequency);
100
+
101
+ env->kvm_timer_dirty = true;
102
+}
103
+
104
+static void kvm_riscv_put_regs_timer(CPUState *cs)
105
+{
106
+ uint64_t reg;
107
+ CPURISCVState *env = &RISCV_CPU(cs)->env;
108
+
109
+ if (!env->kvm_timer_dirty) {
110
+ return;
111
+ }
112
+
113
+ KVM_RISCV_SET_TIMER(cs, env, time, env->kvm_timer_time);
114
+ KVM_RISCV_SET_TIMER(cs, env, compare, env->kvm_timer_compare);
115
+
116
+ /*
117
+ * To set register of RISCV_TIMER_REG(state) will occur a error from KVM
118
+ * on env->kvm_timer_state == 0, It's better to adapt in KVM, but it
119
+ * doesn't matter that adaping in QEMU now.
120
+ * TODO If KVM changes, adapt here.
121
+ */
122
+ if (env->kvm_timer_state) {
123
+ KVM_RISCV_SET_TIMER(cs, env, state, env->kvm_timer_state);
124
+ }
125
+
126
+ /*
127
+ * For now, migration will not work between Hosts with different timer
128
+ * frequency. Therefore, we should check whether they are the same here
129
+ * during the migration.
130
+ */
131
+ if (migration_is_running(migrate_get_current()->state)) {
132
+ KVM_RISCV_GET_TIMER(cs, env, frequency, reg);
133
+ if (reg != env->kvm_timer_frequency) {
134
+ error_report("Dst Hosts timer frequency != Src Hosts");
135
+ }
136
+ }
137
+
138
+ env->kvm_timer_dirty = false;
139
+}
140
141
const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
142
KVM_CAP_LAST_INFO
143
--
144
2.31.1
145
146
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
We hope that virtual time adjusts with vm state changing. When a vm
4
is stopped, guest virtual time should stop counting and kvm_timer
5
should be stopped. When the vm is resumed, guest virtual time should
6
continue to count and kvm_timer should be restored.
7
8
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
9
Signed-off-by: Mingwang Li <limingwang@huawei.com>
10
Reviewed-by: Anup Patel <anup.patel@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-id: 20220112081329.1835-12-jiangyifei@huawei.com
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/kvm.c | 15 +++++++++++++++
16
1 file changed, 15 insertions(+)
17
18
diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/kvm.c
21
+++ b/target/riscv/kvm.c
22
@@ -XXX,XX +XXX,XX @@
23
#include "sbi_ecall_interface.h"
24
#include "chardev/char-fe.h"
25
#include "migration/migration.h"
26
+#include "sysemu/runstate.h"
27
28
static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
29
uint64_t idx)
30
@@ -XXX,XX +XXX,XX @@ unsigned long kvm_arch_vcpu_id(CPUState *cpu)
31
return cpu->cpu_index;
32
}
33
34
+static void kvm_riscv_vm_state_change(void *opaque, bool running,
35
+ RunState state)
36
+{
37
+ CPUState *cs = opaque;
38
+
39
+ if (running) {
40
+ kvm_riscv_put_regs_timer(cs);
41
+ } else {
42
+ kvm_riscv_get_regs_timer(cs);
43
+ }
44
+}
45
+
46
void kvm_arch_init_irq_routing(KVMState *s)
47
{
48
}
49
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init_vcpu(CPUState *cs)
50
CPURISCVState *env = &cpu->env;
51
uint64_t id;
52
53
+ qemu_add_vm_change_state_handler(kvm_riscv_vm_state_change, cs);
54
+
55
id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
56
KVM_REG_RISCV_CONFIG_REG(isa));
57
ret = kvm_get_one_reg(cs, id, &isa);
58
--
59
2.31.1
60
61
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
Add virtual time context description to vmstate_kvmtimer. After cpu being
4
loaded, virtual time context is updated to KVM.
5
6
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
7
Signed-off-by: Mingwang Li <limingwang@huawei.com>
8
Reviewed-by: Anup Patel <anup.patel@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20220112081329.1835-13-jiangyifei@huawei.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/machine.c | 30 ++++++++++++++++++++++++++++++
14
1 file changed, 30 insertions(+)
15
16
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/machine.c
19
+++ b/target/riscv/machine.c
20
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_rv128 = {
21
}
22
};
23
24
+static bool kvmtimer_needed(void *opaque)
25
+{
26
+ return kvm_enabled();
27
+}
28
+
29
+static int cpu_post_load(void *opaque, int version_id)
30
+{
31
+ RISCVCPU *cpu = opaque;
32
+ CPURISCVState *env = &cpu->env;
33
+
34
+ env->kvm_timer_dirty = true;
35
+ return 0;
36
+}
37
+
38
+static const VMStateDescription vmstate_kvmtimer = {
39
+ .name = "cpu/kvmtimer",
40
+ .version_id = 1,
41
+ .minimum_version_id = 1,
42
+ .needed = kvmtimer_needed,
43
+ .post_load = cpu_post_load,
44
+ .fields = (VMStateField[]) {
45
+ VMSTATE_UINT64(env.kvm_timer_time, RISCVCPU),
46
+ VMSTATE_UINT64(env.kvm_timer_compare, RISCVCPU),
47
+ VMSTATE_UINT64(env.kvm_timer_state, RISCVCPU),
48
+
49
+ VMSTATE_END_OF_LIST()
50
+ }
51
+};
52
+
53
const VMStateDescription vmstate_riscv_cpu = {
54
.name = "cpu",
55
.version_id = 3,
56
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
57
&vmstate_vector,
58
&vmstate_pointermasking,
59
&vmstate_rv128,
60
+ &vmstate_kvmtimer,
61
NULL
62
}
63
};
64
--
65
2.31.1
66
67
diff view generated by jsdifflib
New patch
1
From: Yifei Jiang <jiangyifei@huawei.com>
1
2
3
Add riscv kvm support in meson.build file.
4
5
Signed-off-by: Yifei Jiang <jiangyifei@huawei.com>
6
Signed-off-by: Mingwang Li <limingwang@huawei.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Anup Patel <anup@brainfault.org>
9
Message-id: 20220112081329.1835-14-jiangyifei@huawei.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
meson.build | 2 ++
13
1 file changed, 2 insertions(+)
14
15
diff --git a/meson.build b/meson.build
16
index XXXXXXX..XXXXXXX 100644
17
--- a/meson.build
18
+++ b/meson.build
19
@@ -XXX,XX +XXX,XX @@ elif cpu in ['ppc', 'ppc64']
20
kvm_targets = ['ppc-softmmu', 'ppc64-softmmu']
21
elif cpu in ['mips', 'mips64']
22
kvm_targets = ['mips-softmmu', 'mipsel-softmmu', 'mips64-softmmu', 'mips64el-softmmu']
23
+elif cpu in ['riscv']
24
+ kvm_targets = ['riscv32-softmmu', 'riscv64-softmmu']
25
else
26
kvm_targets = []
27
endif
28
--
29
2.31.1
30
31
diff view generated by jsdifflib
New patch
1
From: Thomas Huth <thuth@redhat.com>
1
2
3
If I configure my build with --enable-sanitizers, my GCC (v8.5.0)
4
complains:
5
6
.../softmmu/device_tree.c: In function ‘qemu_fdt_add_path’:
7
.../softmmu/device_tree.c:560:18: error: ‘retval’ may be used uninitialized
8
in this function [-Werror=maybe-uninitialized]
9
int namelen, retval;
10
^~~~~~
11
12
It's a false warning since the while loop is always executed at least
13
once (p has to be non-NULL, otherwise the derefence in the if-statement
14
earlier will crash). Thus let's switch to a do-while loop here instead
15
to make the compiler happy in all cases.
16
17
Signed-off-by: Thomas Huth <thuth@redhat.com>
18
Reviewed-by: Andrew Jones <drjones@redhat.com>
19
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
22
Reviewed-by: Yanan Wang <wangyanan55@huawei.com>
23
Message-id: 20220107133844.145039-1-thuth@redhat.com
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
softmmu/device_tree.c | 4 ++--
27
1 file changed, 2 insertions(+), 2 deletions(-)
28
29
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/softmmu/device_tree.c
32
+++ b/softmmu/device_tree.c
33
@@ -XXX,XX +XXX,XX @@ int qemu_fdt_add_path(void *fdt, const char *path)
34
return -1;
35
}
36
37
- while (p) {
38
+ do {
39
name = p + 1;
40
p = strchr(name, '/');
41
namelen = p != NULL ? p - name : strlen(name);
42
@@ -XXX,XX +XXX,XX @@ int qemu_fdt_add_path(void *fdt, const char *path)
43
}
44
45
parent = retval;
46
- }
47
+ } while (p);
48
49
return retval;
50
}
51
--
52
2.31.1
53
54
diff view generated by jsdifflib
New patch
1
From: Yanan Wang <wangyanan55@huawei.com>
1
2
3
The pointer assignment "const char *p = path;" in function
4
qemu_fdt_add_path is unnecessary. Let's remove it and just
5
use the "path" passed in. No functional change.
6
7
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
9
Reviewed-by: Andrew Jones <drjones@redhat.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Thomas Huth <thuth@redhat.com>
12
Message-id: 20220111032758.27804-1-wangyanan55@huawei.com
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
softmmu/device_tree.c | 9 ++++-----
16
1 file changed, 4 insertions(+), 5 deletions(-)
17
18
diff --git a/softmmu/device_tree.c b/softmmu/device_tree.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/softmmu/device_tree.c
21
+++ b/softmmu/device_tree.c
22
@@ -XXX,XX +XXX,XX @@ int qemu_fdt_add_subnode(void *fdt, const char *name)
23
int qemu_fdt_add_path(void *fdt, const char *path)
24
{
25
const char *name;
26
- const char *p = path;
27
int namelen, retval;
28
int parent = 0;
29
30
@@ -XXX,XX +XXX,XX @@ int qemu_fdt_add_path(void *fdt, const char *path)
31
}
32
33
do {
34
- name = p + 1;
35
- p = strchr(name, '/');
36
- namelen = p != NULL ? p - name : strlen(name);
37
+ name = path + 1;
38
+ path = strchr(name, '/');
39
+ namelen = path != NULL ? path - name : strlen(name);
40
41
retval = fdt_subnode_offset_namelen(fdt, parent, name, namelen);
42
if (retval < 0 && retval != -FDT_ERR_NOTFOUND) {
43
@@ -XXX,XX +XXX,XX @@ int qemu_fdt_add_path(void *fdt, const char *path)
44
}
45
46
parent = retval;
47
- } while (p);
48
+ } while (path);
49
50
return retval;
51
}
52
--
53
2.31.1
54
55
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Signed-off-by: Frank Chang <frank.chang@sifive.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20220118014522.13613-2-frank.chang@sifive.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
target/riscv/cpu.h | 1 +
9
target/riscv/cpu.c | 4 ++++
10
target/riscv/cpu_helper.c | 5 ++++-
11
target/riscv/csr.c | 6 +++++-
12
target/riscv/translate.c | 2 ++
13
5 files changed, 16 insertions(+), 2 deletions(-)
14
15
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.h
18
+++ b/target/riscv/cpu.h
19
@@ -XXX,XX +XXX,XX @@ struct RISCVCPU {
20
bool ext_icsr;
21
bool ext_zfh;
22
bool ext_zfhmin;
23
+ bool ext_zve64f;
24
25
char *priv_spec;
26
char *user_spec;
27
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/riscv/cpu.c
30
+++ b/target/riscv/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
32
}
33
set_vext_version(env, vext_version);
34
}
35
+ if (cpu->cfg.ext_zve64f && !cpu->cfg.ext_f) {
36
+ error_setg(errp, "Zve64f extension depends upon RVF.");
37
+ return;
38
+ }
39
if (cpu->cfg.ext_j) {
40
ext |= RVJ;
41
}
42
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/cpu_helper.c
45
+++ b/target/riscv/cpu_helper.c
46
@@ -XXX,XX +XXX,XX @@ static RISCVMXL cpu_get_xl(CPURISCVState *env)
47
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
48
target_ulong *cs_base, uint32_t *pflags)
49
{
50
+ CPUState *cs = env_cpu(env);
51
+ RISCVCPU *cpu = RISCV_CPU(cs);
52
+
53
uint32_t flags = 0;
54
55
*pc = env->pc;
56
*cs_base = 0;
57
58
- if (riscv_has_ext(env, RVV)) {
59
+ if (riscv_has_ext(env, RVV) || cpu->cfg.ext_zve64f) {
60
/*
61
* If env->vl equals to VLMAX, we can use generic vector operation
62
* expanders (GVEC) to accerlate the vector operations.
63
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/riscv/csr.c
66
+++ b/target/riscv/csr.c
67
@@ -XXX,XX +XXX,XX @@ static RISCVException fs(CPURISCVState *env, int csrno)
68
69
static RISCVException vs(CPURISCVState *env, int csrno)
70
{
71
- if (env->misa_ext & RVV) {
72
+ CPUState *cs = env_cpu(env);
73
+ RISCVCPU *cpu = RISCV_CPU(cs);
74
+
75
+ if (env->misa_ext & RVV ||
76
+ cpu->cfg.ext_zve64f) {
77
#if !defined(CONFIG_USER_ONLY)
78
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
79
return RISCV_EXCP_ILLEGAL_INST;
80
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
81
index XXXXXXX..XXXXXXX 100644
82
--- a/target/riscv/translate.c
83
+++ b/target/riscv/translate.c
84
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
85
bool ext_ifencei;
86
bool ext_zfh;
87
bool ext_zfhmin;
88
+ bool ext_zve64f;
89
bool hlsx;
90
/* vector extension */
91
bool vill;
92
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
93
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
94
ctx->ext_zfh = cpu->cfg.ext_zfh;
95
ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
96
+ ctx->ext_zve64f = cpu->cfg.ext_zve64f;
97
ctx->vlen = cpu->cfg.vlen;
98
ctx->elen = cpu->cfg.elen;
99
ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS);
100
--
101
2.31.1
102
103
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
All Zve* extensions support the vector configuration instructions.
4
5
Signed-off-by: Frank Chang <frank.chang@sifive.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20220118014522.13613-3-frank.chang@sifive.com
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/insn_trans/trans_rvv.c.inc | 6 ++++--
11
1 file changed, 4 insertions(+), 2 deletions(-)
12
13
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/insn_trans/trans_rvv.c.inc
16
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
17
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
18
{
19
TCGv s1, dst;
20
21
- if (!require_rvv(s) || !has_ext(s, RVV)) {
22
+ if (!require_rvv(s) ||
23
+ !(has_ext(s, RVV) || s->ext_zve64f)) {
24
return false;
25
}
26
27
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
28
{
29
TCGv dst;
30
31
- if (!require_rvv(s) || !has_ext(s, RVV)) {
32
+ if (!require_rvv(s) ||
33
+ !(has_ext(s, RVV) || s->ext_zve64f)) {
34
return false;
35
}
36
37
--
38
2.31.1
39
40
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
All Zve* extensions support all vector load and store instructions,
4
except Zve64* extensions do not support EEW=64 for index values when
5
XLEN=32.
6
7
Signed-off-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220118014522.13613-4-frank.chang@sifive.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 19 +++++++++++++++----
13
1 file changed, 15 insertions(+), 4 deletions(-)
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 vext_check_st_index(DisasContext *s, int vd, int vs2, int nf,
20
uint8_t eew)
21
{
22
int8_t emul = eew - s->sew + s->lmul;
23
- return (emul >= -3 && emul <= 3) &&
24
- require_align(vs2, emul) &&
25
- require_align(vd, s->lmul) &&
26
- require_nf(vd, nf, s->lmul);
27
+ bool ret = (emul >= -3 && emul <= 3) &&
28
+ require_align(vs2, emul) &&
29
+ require_align(vd, s->lmul) &&
30
+ require_nf(vd, nf, s->lmul);
31
+
32
+ /*
33
+ * All Zve* extensions support all vector load and store instructions,
34
+ * except Zve64* extensions do not support EEW=64 for index values
35
+ * when XLEN=32. (Section 18.2)
36
+ */
37
+ if (get_xl(s) == MXL_RV32) {
38
+ ret &= (!has_ext(s, RVV) && s->ext_zve64f ? eew != MO_64 : true);
39
+ }
40
+
41
+ return ret;
42
}
43
44
/*
45
--
46
2.31.1
47
48
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
All Zve* extensions support all vector integer instructions,
4
except that the vmulh integer multiply variants that return the
5
high word of the product (vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx,
6
vmulhsu.vv, vmulhsu.vx) are not included for EEW=64 in Zve64*.
7
8
Signed-off-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20220118014522.13613-5-frank.chang@sifive.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/insn_trans/trans_rvv.c.inc | 39 +++++++++++++++++++++----
14
1 file changed, 33 insertions(+), 6 deletions(-)
15
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ GEN_OPIVX_TRANS(vmaxu_vx, opivx_check)
21
GEN_OPIVX_TRANS(vmax_vx, opivx_check)
22
23
/* Vector Single-Width Integer Multiply Instructions */
24
+
25
+static bool vmulh_vv_check(DisasContext *s, arg_rmrr *a)
26
+{
27
+ /*
28
+ * All Zve* extensions support all vector integer instructions,
29
+ * except that the vmulh integer multiply variants
30
+ * that return the high word of the product
31
+ * (vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx, vmulhsu.vv, vmulhsu.vx)
32
+ * are not included for EEW=64 in Zve64*. (Section 18.2)
33
+ */
34
+ return opivv_check(s, a) &&
35
+ (!has_ext(s, RVV) && s->ext_zve64f ? s->sew != MO_64 : true);
36
+}
37
+
38
+static bool vmulh_vx_check(DisasContext *s, arg_rmrr *a)
39
+{
40
+ /*
41
+ * All Zve* extensions support all vector integer instructions,
42
+ * except that the vmulh integer multiply variants
43
+ * that return the high word of the product
44
+ * (vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx, vmulhsu.vv, vmulhsu.vx)
45
+ * are not included for EEW=64 in Zve64*. (Section 18.2)
46
+ */
47
+ return opivx_check(s, a) &&
48
+ (!has_ext(s, RVV) && s->ext_zve64f ? s->sew != MO_64 : true);
49
+}
50
+
51
GEN_OPIVV_GVEC_TRANS(vmul_vv, mul)
52
-GEN_OPIVV_TRANS(vmulh_vv, opivv_check)
53
-GEN_OPIVV_TRANS(vmulhu_vv, opivv_check)
54
-GEN_OPIVV_TRANS(vmulhsu_vv, opivv_check)
55
+GEN_OPIVV_TRANS(vmulh_vv, vmulh_vv_check)
56
+GEN_OPIVV_TRANS(vmulhu_vv, vmulh_vv_check)
57
+GEN_OPIVV_TRANS(vmulhsu_vv, vmulh_vv_check)
58
GEN_OPIVX_GVEC_TRANS(vmul_vx, muls)
59
-GEN_OPIVX_TRANS(vmulh_vx, opivx_check)
60
-GEN_OPIVX_TRANS(vmulhu_vx, opivx_check)
61
-GEN_OPIVX_TRANS(vmulhsu_vx, opivx_check)
62
+GEN_OPIVX_TRANS(vmulh_vx, vmulh_vx_check)
63
+GEN_OPIVX_TRANS(vmulhu_vx, vmulh_vx_check)
64
+GEN_OPIVX_TRANS(vmulhsu_vx, vmulh_vx_check)
65
66
/* Vector Integer Divide Instructions */
67
GEN_OPIVV_TRANS(vdivu_vv, opivv_check)
68
--
69
2.31.1
70
71
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
All Zve* extensions support all vector fixed-point arithmetic
4
instructions, except that vsmul.vv and vsmul.vx are not supported
5
for EEW=64 in Zve64*.
6
7
Signed-off-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220118014522.13613-6-frank.chang@sifive.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 27 +++++++++++++++++++++++--
13
1 file changed, 25 insertions(+), 2 deletions(-)
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 @@ GEN_OPIVX_TRANS(vasub_vx, opivx_check)
20
GEN_OPIVX_TRANS(vasubu_vx, opivx_check)
21
22
/* Vector Single-Width Fractional Multiply with Rounding and Saturation */
23
-GEN_OPIVV_TRANS(vsmul_vv, opivv_check)
24
-GEN_OPIVX_TRANS(vsmul_vx, opivx_check)
25
+
26
+static bool vsmul_vv_check(DisasContext *s, arg_rmrr *a)
27
+{
28
+ /*
29
+ * All Zve* extensions support all vector fixed-point arithmetic
30
+ * instructions, except that vsmul.vv and vsmul.vx are not supported
31
+ * for EEW=64 in Zve64*. (Section 18.2)
32
+ */
33
+ return opivv_check(s, a) &&
34
+ (!has_ext(s, RVV) && s->ext_zve64f ? s->sew != MO_64 : true);
35
+}
36
+
37
+static bool vsmul_vx_check(DisasContext *s, arg_rmrr *a)
38
+{
39
+ /*
40
+ * All Zve* extensions support all vector fixed-point arithmetic
41
+ * instructions, except that vsmul.vv and vsmul.vx are not supported
42
+ * for EEW=64 in Zve64*. (Section 18.2)
43
+ */
44
+ return opivx_check(s, a) &&
45
+ (!has_ext(s, RVV) && s->ext_zve64f ? s->sew != MO_64 : true);
46
+}
47
+
48
+GEN_OPIVV_TRANS(vsmul_vv, vsmul_vv_check)
49
+GEN_OPIVX_TRANS(vsmul_vx, vsmul_vx_check)
50
51
/* Vector Single-Width Scaling Shift Instructions */
52
GEN_OPIVV_TRANS(vssrl_vv, opivv_check)
53
--
54
2.31.1
55
56
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Zve64f extension requires the scalar processor to implement the F
4
extension and implement all vector floating-point instructions for
5
floating-point operands with EEW=32 (i.e., no widening floating-point
6
operations).
7
8
Signed-off-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20220118014522.13613-7-frank.chang@sifive.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/insn_trans/trans_rvv.c.inc | 41 +++++++++++++++++++------
14
1 file changed, 31 insertions(+), 10 deletions(-)
15
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvf(DisasContext *s)
21
}
22
}
23
24
+static bool require_zve64f(DisasContext *s)
25
+{
26
+ /* RVV + Zve64f = RVV. */
27
+ if (has_ext(s, RVV)) {
28
+ return true;
29
+ }
30
+
31
+ /* Zve64f doesn't support FP64. (Section 18.2) */
32
+ return s->ext_zve64f ? s->sew <= MO_32 : true;
33
+}
34
+
35
/* Destination vector register group cannot overlap source mask register. */
36
static bool require_vm(int vm, int vd)
37
{
38
@@ -XXX,XX +XXX,XX @@ static bool opfvv_check(DisasContext *s, arg_rmrr *a)
39
return require_rvv(s) &&
40
require_rvf(s) &&
41
vext_check_isa_ill(s) &&
42
- vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm);
43
+ vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm) &&
44
+ require_zve64f(s);
45
}
46
47
/* OPFVV without GVEC IR */
48
@@ -XXX,XX +XXX,XX @@ static bool opfvf_check(DisasContext *s, arg_rmrr *a)
49
return require_rvv(s) &&
50
require_rvf(s) &&
51
vext_check_isa_ill(s) &&
52
- vext_check_ss(s, a->rd, a->rs2, a->vm);
53
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
54
+ require_zve64f(s);
55
}
56
57
/* OPFVF without GVEC IR */
58
@@ -XXX,XX +XXX,XX @@ static bool opfv_check(DisasContext *s, arg_rmr *a)
59
require_rvf(s) &&
60
vext_check_isa_ill(s) &&
61
/* OPFV instructions ignore vs1 check */
62
- vext_check_ss(s, a->rd, a->rs2, a->vm);
63
+ vext_check_ss(s, a->rd, a->rs2, a->vm) &&
64
+ require_zve64f(s);
65
}
66
67
static bool do_opfv(DisasContext *s, arg_rmr *a,
68
@@ -XXX,XX +XXX,XX @@ static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a)
69
return require_rvv(s) &&
70
require_rvf(s) &&
71
vext_check_isa_ill(s) &&
72
- vext_check_mss(s, a->rd, a->rs1, a->rs2);
73
+ vext_check_mss(s, a->rd, a->rs1, a->rs2) &&
74
+ require_zve64f(s);
75
}
76
77
GEN_OPFVV_TRANS(vmfeq_vv, opfvv_cmp_check)
78
@@ -XXX,XX +XXX,XX @@ static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a)
79
return require_rvv(s) &&
80
require_rvf(s) &&
81
vext_check_isa_ill(s) &&
82
- vext_check_ms(s, a->rd, a->rs2);
83
+ vext_check_ms(s, a->rd, a->rs2) &&
84
+ require_zve64f(s);
85
}
86
87
GEN_OPFVF_TRANS(vmfeq_vf, opfvf_cmp_check)
88
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
89
if (require_rvv(s) &&
90
require_rvf(s) &&
91
vext_check_isa_ill(s) &&
92
- require_align(a->rd, s->lmul)) {
93
+ require_align(a->rd, s->lmul) &&
94
+ require_zve64f(s)) {
95
gen_set_rm(s, RISCV_FRM_DYN);
96
97
TCGv_i64 t1;
98
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
99
{
100
if (require_rvv(s) &&
101
require_rvf(s) &&
102
- vext_check_isa_ill(s)) {
103
+ vext_check_isa_ill(s) &&
104
+ require_zve64f(s)) {
105
gen_set_rm(s, RISCV_FRM_DYN);
106
107
unsigned int ofs = (8 << s->sew);
108
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
109
{
110
if (require_rvv(s) &&
111
require_rvf(s) &&
112
- vext_check_isa_ill(s)) {
113
+ vext_check_isa_ill(s) &&
114
+ require_zve64f(s)) {
115
gen_set_rm(s, RISCV_FRM_DYN);
116
117
/* The instructions ignore LMUL and vector register group. */
118
@@ -XXX,XX +XXX,XX @@ GEN_OPIVI_TRANS(vslidedown_vi, IMM_ZX, vslidedown_vx, slidedown_check)
119
static bool fslideup_check(DisasContext *s, arg_rmrr *a)
120
{
121
return slideup_check(s, a) &&
122
- require_rvf(s);
123
+ require_rvf(s) &&
124
+ require_zve64f(s);
125
}
126
127
static bool fslidedown_check(DisasContext *s, arg_rmrr *a)
128
{
129
return slidedown_check(s, a) &&
130
- require_rvf(s);
131
+ require_rvf(s) &&
132
+ require_zve64f(s);
133
}
134
135
GEN_OPFVF_TRANS(vfslide1up_vf, fslideup_check)
136
--
137
2.31.1
138
139
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Vector single-width floating-point reduction operations for EEW=32 are
4
supported for Zve64f extension.
5
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220118014522.13613-8-frank.chang@sifive.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/insn_trans/trans_rvv.c.inc | 3 ++-
12
1 file changed, 2 insertions(+), 1 deletion(-)
13
14
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
@@ -XXX,XX +XXX,XX @@ GEN_OPIVV_WIDEN_TRANS(vwredsumu_vs, reduction_widen_check)
19
static bool freduction_check(DisasContext *s, arg_rmrr *a)
20
{
21
return reduction_check(s, a) &&
22
- require_rvf(s);
23
+ require_rvf(s) &&
24
+ require_zve64f(s);
25
}
26
27
GEN_OPFVV_TRANS(vfredsum_vs, freduction_check)
28
--
29
2.31.1
30
31
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Vector widening conversion instructions are provided to and from all
4
supported integer EEWs for Zve64f extension.
5
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220118014522.13613-9-frank.chang@sifive.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/insn_trans/trans_rvv.c.inc | 32 +++++++++++++++++++------
12
1 file changed, 25 insertions(+), 7 deletions(-)
13
14
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
@@ -XXX,XX +XXX,XX @@ static bool require_zve64f(DisasContext *s)
19
return s->ext_zve64f ? s->sew <= MO_32 : true;
20
}
21
22
+static bool require_scale_zve64f(DisasContext *s)
23
+{
24
+ /* RVV + Zve64f = RVV. */
25
+ if (has_ext(s, RVV)) {
26
+ return true;
27
+ }
28
+
29
+ /* Zve64f doesn't support FP64. (Section 18.2) */
30
+ return s->ext_zve64f ? s->sew <= MO_16 : true;
31
+}
32
+
33
/* Destination vector register group cannot overlap source mask register. */
34
static bool require_vm(int vm, int vd)
35
{
36
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
37
require_scale_rvf(s) &&
38
(s->sew != MO_8) &&
39
vext_check_isa_ill(s) &&
40
- vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm);
41
+ vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
42
+ require_scale_zve64f(s);
43
}
44
45
/* OPFVV with WIDEN */
46
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
47
require_scale_rvf(s) &&
48
(s->sew != MO_8) &&
49
vext_check_isa_ill(s) &&
50
- vext_check_ds(s, a->rd, a->rs2, a->vm);
51
+ vext_check_ds(s, a->rd, a->rs2, a->vm) &&
52
+ require_scale_zve64f(s);
53
}
54
55
/* OPFVF with WIDEN */
56
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
57
require_scale_rvf(s) &&
58
(s->sew != MO_8) &&
59
vext_check_isa_ill(s) &&
60
- vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm);
61
+ vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm) &&
62
+ require_scale_zve64f(s);
63
}
64
65
/* WIDEN OPFVV with WIDEN */
66
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
67
require_scale_rvf(s) &&
68
(s->sew != MO_8) &&
69
vext_check_isa_ill(s) &&
70
- vext_check_dd(s, a->rd, a->rs2, a->vm);
71
+ vext_check_dd(s, a->rd, a->rs2, a->vm) &&
72
+ require_scale_zve64f(s);
73
}
74
75
/* WIDEN OPFVF with WIDEN */
76
@@ -XXX,XX +XXX,XX @@ static bool opfv_widen_check(DisasContext *s, arg_rmr *a)
77
static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
78
{
79
return opfv_widen_check(s, a) &&
80
- require_rvf(s);
81
+ require_rvf(s) &&
82
+ require_zve64f(s);
83
}
84
85
static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
86
{
87
return opfv_widen_check(s, a) &&
88
require_scale_rvf(s) &&
89
- (s->sew != MO_8);
90
+ (s->sew != MO_8) &&
91
+ require_scale_zve64f(s);
92
}
93
94
#define GEN_OPFV_WIDEN_TRANS(NAME, CHECK, HELPER, FRM) \
95
@@ -XXX,XX +XXX,XX @@ static bool opfxv_widen_check(DisasContext *s, arg_rmr *a)
96
require_scale_rvf(s) &&
97
vext_check_isa_ill(s) &&
98
/* OPFV widening instructions ignore vs1 check */
99
- vext_check_ds(s, a->rd, a->rs2, a->vm);
100
+ vext_check_ds(s, a->rd, a->rs2, a->vm) &&
101
+ require_scale_zve64f(s);
102
}
103
104
#define GEN_OPFXV_WIDEN_TRANS(NAME) \
105
--
106
2.31.1
107
108
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Vector narrowing conversion instructions are provided to and from all
4
supported integer EEWs for Zve64f extension.
5
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220118014522.13613-10-frank.chang@sifive.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/insn_trans/trans_rvv.c.inc | 9 ++++++---
12
1 file changed, 6 insertions(+), 3 deletions(-)
13
14
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
19
{
20
return opfv_narrow_check(s, a) &&
21
require_rvf(s) &&
22
- (s->sew != MO_64);
23
+ (s->sew != MO_64) &&
24
+ require_zve64f(s);
25
}
26
27
static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
28
{
29
return opfv_narrow_check(s, a) &&
30
require_scale_rvf(s) &&
31
- (s->sew != MO_8);
32
+ (s->sew != MO_8) &&
33
+ require_scale_zve64f(s);
34
}
35
36
#define GEN_OPFV_NARROW_TRANS(NAME, CHECK, HELPER, FRM) \
37
@@ -XXX,XX +XXX,XX @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
38
require_scale_rvf(s) &&
39
vext_check_isa_ill(s) &&
40
/* OPFV narrowing instructions ignore vs1 check */
41
- vext_check_sd(s, a->rd, a->rs2, a->vm);
42
+ vext_check_sd(s, a->rd, a->rs2, a->vm) &&
43
+ require_scale_zve64f(s);
44
}
45
46
#define GEN_OPXFV_NARROW_TRANS(NAME, HELPER, FRM) \
47
--
48
2.31.1
49
50
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Signed-off-by: Frank Chang <frank.chang@sifive.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20220118014522.13613-11-frank.chang@sifive.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
target/riscv/cpu.c | 1 +
9
1 file changed, 1 insertion(+)
10
11
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/cpu.c
14
+++ b/target/riscv/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
16
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
17
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
18
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
19
+ DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
20
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
21
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
22
23
--
24
2.31.1
25
26
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Signed-off-by: Frank Chang <frank.chang@sifive.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20220118014522.13613-12-frank.chang@sifive.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
target/riscv/cpu.h | 1 +
9
target/riscv/cpu.c | 4 ++--
10
target/riscv/cpu_helper.c | 2 +-
11
target/riscv/csr.c | 2 +-
12
target/riscv/translate.c | 2 ++
13
5 files changed, 7 insertions(+), 4 deletions(-)
14
15
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.h
18
+++ b/target/riscv/cpu.h
19
@@ -XXX,XX +XXX,XX @@ struct RISCVCPU {
20
bool ext_icsr;
21
bool ext_zfh;
22
bool ext_zfhmin;
23
+ bool ext_zve32f;
24
bool ext_zve64f;
25
26
char *priv_spec;
27
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/riscv/cpu.c
30
+++ b/target/riscv/cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
32
}
33
set_vext_version(env, vext_version);
34
}
35
- if (cpu->cfg.ext_zve64f && !cpu->cfg.ext_f) {
36
- error_setg(errp, "Zve64f extension depends upon RVF.");
37
+ if ((cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) && !cpu->cfg.ext_f) {
38
+ error_setg(errp, "Zve32f/Zve64f extension depends upon RVF.");
39
return;
40
}
41
if (cpu->cfg.ext_j) {
42
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/cpu_helper.c
45
+++ b/target/riscv/cpu_helper.c
46
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
47
*pc = env->pc;
48
*cs_base = 0;
49
50
- if (riscv_has_ext(env, RVV) || cpu->cfg.ext_zve64f) {
51
+ if (riscv_has_ext(env, RVV) || cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
52
/*
53
* If env->vl equals to VLMAX, we can use generic vector operation
54
* expanders (GVEC) to accerlate the vector operations.
55
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/csr.c
58
+++ b/target/riscv/csr.c
59
@@ -XXX,XX +XXX,XX @@ static RISCVException vs(CPURISCVState *env, int csrno)
60
RISCVCPU *cpu = RISCV_CPU(cs);
61
62
if (env->misa_ext & RVV ||
63
- cpu->cfg.ext_zve64f) {
64
+ cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
65
#if !defined(CONFIG_USER_ONLY)
66
if (!env->debugger && !riscv_cpu_vector_enabled(env)) {
67
return RISCV_EXCP_ILLEGAL_INST;
68
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/translate.c
71
+++ b/target/riscv/translate.c
72
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
73
bool ext_ifencei;
74
bool ext_zfh;
75
bool ext_zfhmin;
76
+ bool ext_zve32f;
77
bool ext_zve64f;
78
bool hlsx;
79
/* vector extension */
80
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
81
ctx->ext_ifencei = cpu->cfg.ext_ifencei;
82
ctx->ext_zfh = cpu->cfg.ext_zfh;
83
ctx->ext_zfhmin = cpu->cfg.ext_zfhmin;
84
+ ctx->ext_zve32f = cpu->cfg.ext_zve32f;
85
ctx->ext_zve64f = cpu->cfg.ext_zve64f;
86
ctx->vlen = cpu->cfg.vlen;
87
ctx->elen = cpu->cfg.elen;
88
--
89
2.31.1
90
91
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
All Zve* extensions support the vector configuration instructions.
4
5
Signed-off-by: Frank Chang <frank.chang@sifive.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20220118014522.13613-13-frank.chang@sifive.com
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
10
target/riscv/insn_trans/trans_rvv.c.inc | 4 ++--
11
1 file changed, 2 insertions(+), 2 deletions(-)
12
13
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/insn_trans/trans_rvv.c.inc
16
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
17
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
18
TCGv s1, dst;
19
20
if (!require_rvv(s) ||
21
- !(has_ext(s, RVV) || s->ext_zve64f)) {
22
+ !(has_ext(s, RVV) || s->ext_zve32f || s->ext_zve64f)) {
23
return false;
24
}
25
26
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
27
TCGv dst;
28
29
if (!require_rvv(s) ||
30
- !(has_ext(s, RVV) || s->ext_zve64f)) {
31
+ !(has_ext(s, RVV) || s->ext_zve32f || s->ext_zve64f)) {
32
return false;
33
}
34
35
--
36
2.31.1
37
38
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Zve32f extension requires the scalar processor to implement the F
4
extension and implement all vector floating-point instructions for
5
floating-point operands with EEW=32 (i.e., no widening floating-point
6
operations).
7
8
Signed-off-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20220118014522.13613-14-frank.chang@sifive.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/insn_trans/trans_rvv.c.inc | 21 +++++++++++++++++++++
14
1 file changed, 21 insertions(+)
15
16
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static bool require_scale_rvf(DisasContext *s)
21
}
22
}
23
24
+static bool require_zve32f(DisasContext *s)
25
+{
26
+ /* RVV + Zve32f = RVV. */
27
+ if (has_ext(s, RVV)) {
28
+ return true;
29
+ }
30
+
31
+ /* Zve32f doesn't support FP64. (Section 18.2) */
32
+ return s->ext_zve32f ? s->sew <= MO_32 : true;
33
+}
34
+
35
static bool require_zve64f(DisasContext *s)
36
{
37
/* RVV + Zve64f = RVV. */
38
@@ -XXX,XX +XXX,XX @@ static bool opfvv_check(DisasContext *s, arg_rmrr *a)
39
require_rvf(s) &&
40
vext_check_isa_ill(s) &&
41
vext_check_sss(s, a->rd, a->rs1, a->rs2, a->vm) &&
42
+ require_zve32f(s) &&
43
require_zve64f(s);
44
}
45
46
@@ -XXX,XX +XXX,XX @@ static bool opfvf_check(DisasContext *s, arg_rmrr *a)
47
require_rvf(s) &&
48
vext_check_isa_ill(s) &&
49
vext_check_ss(s, a->rd, a->rs2, a->vm) &&
50
+ require_zve32f(s) &&
51
require_zve64f(s);
52
}
53
54
@@ -XXX,XX +XXX,XX @@ static bool opfv_check(DisasContext *s, arg_rmr *a)
55
vext_check_isa_ill(s) &&
56
/* OPFV instructions ignore vs1 check */
57
vext_check_ss(s, a->rd, a->rs2, a->vm) &&
58
+ require_zve32f(s) &&
59
require_zve64f(s);
60
}
61
62
@@ -XXX,XX +XXX,XX @@ static bool opfvv_cmp_check(DisasContext *s, arg_rmrr *a)
63
require_rvf(s) &&
64
vext_check_isa_ill(s) &&
65
vext_check_mss(s, a->rd, a->rs1, a->rs2) &&
66
+ require_zve32f(s) &&
67
require_zve64f(s);
68
}
69
70
@@ -XXX,XX +XXX,XX @@ static bool opfvf_cmp_check(DisasContext *s, arg_rmrr *a)
71
require_rvf(s) &&
72
vext_check_isa_ill(s) &&
73
vext_check_ms(s, a->rd, a->rs2) &&
74
+ require_zve32f(s) &&
75
require_zve64f(s);
76
}
77
78
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_v_f(DisasContext *s, arg_vfmv_v_f *a)
79
require_rvf(s) &&
80
vext_check_isa_ill(s) &&
81
require_align(a->rd, s->lmul) &&
82
+ require_zve32f(s) &&
83
require_zve64f(s)) {
84
gen_set_rm(s, RISCV_FRM_DYN);
85
86
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_f_s(DisasContext *s, arg_vfmv_f_s *a)
87
if (require_rvv(s) &&
88
require_rvf(s) &&
89
vext_check_isa_ill(s) &&
90
+ require_zve32f(s) &&
91
require_zve64f(s)) {
92
gen_set_rm(s, RISCV_FRM_DYN);
93
94
@@ -XXX,XX +XXX,XX @@ static bool trans_vfmv_s_f(DisasContext *s, arg_vfmv_s_f *a)
95
if (require_rvv(s) &&
96
require_rvf(s) &&
97
vext_check_isa_ill(s) &&
98
+ require_zve32f(s) &&
99
require_zve64f(s)) {
100
gen_set_rm(s, RISCV_FRM_DYN);
101
102
@@ -XXX,XX +XXX,XX @@ static bool fslideup_check(DisasContext *s, arg_rmrr *a)
103
{
104
return slideup_check(s, a) &&
105
require_rvf(s) &&
106
+ require_zve32f(s) &&
107
require_zve64f(s);
108
}
109
110
@@ -XXX,XX +XXX,XX @@ static bool fslidedown_check(DisasContext *s, arg_rmrr *a)
111
{
112
return slidedown_check(s, a) &&
113
require_rvf(s) &&
114
+ require_zve32f(s) &&
115
require_zve64f(s);
116
}
117
118
--
119
2.31.1
120
121
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Vector single-width floating-point reduction operations for EEW=32 are
4
supported for Zve32f extension.
5
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220118014522.13613-15-frank.chang@sifive.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/insn_trans/trans_rvv.c.inc | 1 +
12
1 file changed, 1 insertion(+)
13
14
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/insn_trans/trans_rvv.c.inc
17
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
18
@@ -XXX,XX +XXX,XX @@ static bool freduction_check(DisasContext *s, arg_rmrr *a)
19
{
20
return reduction_check(s, a) &&
21
require_rvf(s) &&
22
+ require_zve32f(s) &&
23
require_zve64f(s);
24
}
25
26
--
27
2.31.1
28
29
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
The previous implementation was broken in many ways:
3
Vector widening conversion instructions are provided to and from all
4
- Used mideleg instead of hideleg to mask accesses
4
supported integer EEWs for Zve32f extension.
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
Signed-off-by: Frank Chang <frank.chang@sifive.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
Message-id: 20220118014522.13613-16-frank.chang@sifive.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
10
---
13
target/riscv/csr.c | 68 +++++++++++++++++++++++-----------------------
11
target/riscv/insn_trans/trans_rvv.c.inc | 18 ++++++++++++++++++
14
1 file changed, 34 insertions(+), 34 deletions(-)
12
1 file changed, 18 insertions(+)
15
13
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
14
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
16
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/target/riscv/csr.c
17
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
18
@@ -XXX,XX +XXX,XX @@ static bool require_zve32f(DisasContext *s)
21
return write_mstatus(env, CSR_MSTATUS, newval);
19
return s->ext_zve32f ? s->sew <= MO_32 : true;
22
}
20
}
23
21
24
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
22
+static bool require_scale_zve32f(DisasContext *s)
25
+{
23
+{
26
+ /* Shift the VS bits to their S bit location in vsie */
24
+ /* RVV + Zve32f = RVV. */
27
+ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
25
+ if (has_ext(s, RVV)) {
28
+ return 0;
26
+ return true;
27
+ }
28
+
29
+ /* Zve32f doesn't support FP64. (Section 18.2) */
30
+ return s->ext_zve64f ? s->sew <= MO_16 : true;
29
+}
31
+}
30
+
32
+
31
static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
33
static bool require_zve64f(DisasContext *s)
32
{
34
{
33
if (riscv_cpu_virt_enabled(env)) {
35
/* RVV + Zve64f = RVV. */
34
- /* Tell the guest the VS bits, shifted to the S bit locations */
36
@@ -XXX,XX +XXX,XX @@ static bool opfvv_widen_check(DisasContext *s, arg_rmrr *a)
35
- *val = (env->mie & env->mideleg & VS_MODE_INTERRUPTS) >> 1;
37
(s->sew != MO_8) &&
36
+ read_vsie(env, CSR_VSIE, val);
38
vext_check_isa_ill(s) &&
37
} else {
39
vext_check_dss(s, a->rd, a->rs1, a->rs2, a->vm) &&
38
*val = env->mie & env->mideleg;
40
+ require_scale_zve32f(s) &&
39
}
41
require_scale_zve64f(s);
40
return 0;
41
}
42
}
42
43
43
-static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
44
@@ -XXX,XX +XXX,XX @@ static bool opfvf_widen_check(DisasContext *s, arg_rmrr *a)
44
+static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
45
(s->sew != MO_8) &&
46
vext_check_isa_ill(s) &&
47
vext_check_ds(s, a->rd, a->rs2, a->vm) &&
48
+ require_scale_zve32f(s) &&
49
require_scale_zve64f(s);
50
}
51
52
@@ -XXX,XX +XXX,XX @@ static bool opfwv_widen_check(DisasContext *s, arg_rmrr *a)
53
(s->sew != MO_8) &&
54
vext_check_isa_ill(s) &&
55
vext_check_dds(s, a->rd, a->rs1, a->rs2, a->vm) &&
56
+ require_scale_zve32f(s) &&
57
require_scale_zve64f(s);
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static bool opfwf_widen_check(DisasContext *s, arg_rmrr *a)
61
(s->sew != MO_8) &&
62
vext_check_isa_ill(s) &&
63
vext_check_dd(s, a->rd, a->rs2, a->vm) &&
64
+ require_scale_zve32f(s) &&
65
require_scale_zve64f(s);
66
}
67
68
@@ -XXX,XX +XXX,XX @@ static bool opxfv_widen_check(DisasContext *s, arg_rmr *a)
45
{
69
{
46
- target_ulong newval;
70
return opfv_widen_check(s, a) &&
47
+ /* Shift the S bits to their VS bit location in mie */
71
require_rvf(s) &&
48
+ target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) |
72
+ require_zve32f(s) &&
49
+ ((val << 1) & env->hideleg & VS_MODE_INTERRUPTS);
73
require_zve64f(s);
50
+ return write_mie(env, CSR_MIE, newval);
51
+}
52
53
+static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
54
+{
55
if (riscv_cpu_virt_enabled(env)) {
56
- /* Shift the guests S bits to VS */
57
- newval = (env->mie & ~VS_MODE_INTERRUPTS) |
58
- ((val << 1) & VS_MODE_INTERRUPTS);
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
}
74
}
70
75
71
static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
76
@@ -XXX,XX +XXX,XX @@ static bool opffv_widen_check(DisasContext *s, arg_rmr *a)
72
@@ -XXX,XX +XXX,XX @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
77
return opfv_widen_check(s, a) &&
73
return 0;
78
require_scale_rvf(s) &&
79
(s->sew != MO_8) &&
80
+ require_scale_zve32f(s) &&
81
require_scale_zve64f(s);
74
}
82
}
75
83
76
+static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
84
@@ -XXX,XX +XXX,XX @@ static bool opfxv_widen_check(DisasContext *s, arg_rmr *a)
77
+ target_ulong new_value, target_ulong write_mask)
85
vext_check_isa_ill(s) &&
78
+{
86
/* OPFV widening instructions ignore vs1 check */
79
+ /* Shift the S bits to their VS bit location in mip */
87
vext_check_ds(s, a->rd, a->rs2, a->vm) &&
80
+ int ret = rmw_mip(env, 0, ret_value, new_value << 1,
88
+ require_scale_zve32f(s) &&
81
+ (write_mask << 1) & vsip_writable_mask & env->hideleg);
89
require_scale_zve64f(s);
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
+}
87
+
88
static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
89
target_ulong new_value, target_ulong write_mask)
90
{
91
int ret;
92
93
if (riscv_cpu_virt_enabled(env)) {
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
}
90
}
106
91
107
-static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
108
- target_ulong new_value, target_ulong write_mask)
109
-{
110
- int ret = rmw_mip(env, 0, ret_value, new_value,
111
- write_mask & env->mideleg & vsip_writable_mask);
112
- return ret;
113
-}
114
-
115
-static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
116
-{
117
- *val = env->mie & env->mideleg & VS_MODE_INTERRUPTS;
118
- return 0;
119
-}
120
-
121
-static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
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
{
129
*val = env->vstvec;
130
--
92
--
131
2.30.1
93
2.31.1
132
94
133
95
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
Per SST25VF016B datasheet [1], SST flash requires a dummy byte after
3
Vector narrowing conversion instructions are provided to and from all
4
the address bytes. Note only SPI mode is supported by SST flashes.
4
supported integer EEWs for Zve32f extension.
5
5
6
[1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
8
Message-id: 20220118014522.13613-17-frank.chang@sifive.com
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20210306060152.7250-1-bmeng.cn@gmail.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
10
---
13
hw/block/m25p80.c | 3 +++
11
target/riscv/insn_trans/trans_rvv.c.inc | 3 +++
14
1 file changed, 3 insertions(+)
12
1 file changed, 3 insertions(+)
15
13
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
14
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
16
--- a/target/riscv/insn_trans/trans_rvv.c.inc
19
+++ b/hw/block/m25p80.c
17
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
20
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
18
@@ -XXX,XX +XXX,XX @@ static bool opfxv_narrow_check(DisasContext *s, arg_rmr *a)
21
s->needed_bytes = get_addr_length(s);
19
return opfv_narrow_check(s, a) &&
22
switch (get_man(s)) {
20
require_rvf(s) &&
23
/* Dummy cycles - modeled with bytes writes instead of bits */
21
(s->sew != MO_64) &&
24
+ case MAN_SST:
22
+ require_zve32f(s) &&
25
+ s->needed_bytes += 1;
23
require_zve64f(s);
26
+ break;
24
}
27
case MAN_WINBOND:
25
28
s->needed_bytes += 8;
26
@@ -XXX,XX +XXX,XX @@ static bool opffv_narrow_check(DisasContext *s, arg_rmr *a)
29
break;
27
return opfv_narrow_check(s, a) &&
28
require_scale_rvf(s) &&
29
(s->sew != MO_8) &&
30
+ require_scale_zve32f(s) &&
31
require_scale_zve64f(s);
32
}
33
34
@@ -XXX,XX +XXX,XX @@ static bool opxfv_narrow_check(DisasContext *s, arg_rmr *a)
35
vext_check_isa_ill(s) &&
36
/* OPFV narrowing instructions ignore vs1 check */
37
vext_check_sd(s, a->rd, a->rs2, a->vm) &&
38
+ require_scale_zve32f(s) &&
39
require_scale_zve64f(s);
40
}
41
30
--
42
--
31
2.30.1
43
2.31.1
32
44
33
45
diff view generated by jsdifflib
New patch
1
From: Frank Chang <frank.chang@sifive.com>
1
2
3
Signed-off-by: Frank Chang <frank.chang@sifive.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20220118014522.13613-18-frank.chang@sifive.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
target/riscv/cpu.c | 1 +
9
1 file changed, 1 insertion(+)
10
11
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/cpu.c
14
+++ b/target/riscv/cpu.c
15
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
16
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
17
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
18
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
19
+ DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
20
DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
21
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
22
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
23
--
24
2.31.1
25
26
diff view generated by jsdifflib
New patch
1
1
From: Anup Patel <apatel@ventanamicro.com>
2
3
Currently, we have to use OpenSBI firmware ELF as bios for the spike
4
machine because the HTIF console requires ELF for parsing "fromhost"
5
and "tohost" symbols.
6
7
The latest OpenSBI can now optionally pick-up HTIF register address
8
from HTIF DT node so using this feature spike machine can now use
9
OpenSBI firmware BIN as bios.
10
11
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
include/hw/char/riscv_htif.h | 5 ++++-
17
include/hw/riscv/spike.h | 1 +
18
hw/char/riscv_htif.c | 33 +++++++++++++++++++----------
19
hw/riscv/spike.c | 41 ++++++++++++++++++++++--------------
20
4 files changed, 52 insertions(+), 28 deletions(-)
21
22
diff --git a/include/hw/char/riscv_htif.h b/include/hw/char/riscv_htif.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/char/riscv_htif.h
25
+++ b/include/hw/char/riscv_htif.h
26
@@ -XXX,XX +XXX,XX @@ extern const MemoryRegionOps htif_io_ops;
27
void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
28
uint64_t st_size);
29
30
+/* Check if HTIF uses ELF symbols */
31
+bool htif_uses_elf_symbols(void);
32
+
33
/* legacy pre qom */
34
HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
35
- CPURISCVState *env, Chardev *chr);
36
+ CPURISCVState *env, Chardev *chr, uint64_t nonelf_base);
37
38
#endif
39
diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/include/hw/riscv/spike.h
42
+++ b/include/hw/riscv/spike.h
43
@@ -XXX,XX +XXX,XX @@ struct SpikeState {
44
45
enum {
46
SPIKE_MROM,
47
+ SPIKE_HTIF,
48
SPIKE_CLINT,
49
SPIKE_DRAM
50
};
51
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/char/riscv_htif.c
54
+++ b/hw/char/riscv_htif.c
55
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps htif_mm_ops = {
56
.write = htif_mm_write,
57
};
58
59
+bool htif_uses_elf_symbols(void)
60
+{
61
+ return (address_symbol_set == 3) ? true : false;
62
+}
63
+
64
HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
65
- CPURISCVState *env, Chardev *chr)
66
+ CPURISCVState *env, Chardev *chr, uint64_t nonelf_base)
67
{
68
- uint64_t base = MIN(tohost_addr, fromhost_addr);
69
- uint64_t size = MAX(tohost_addr + 8, fromhost_addr + 8) - base;
70
- uint64_t tohost_offset = tohost_addr - base;
71
- uint64_t fromhost_offset = fromhost_addr - base;
72
+ uint64_t base, size, tohost_offset, fromhost_offset;
73
+
74
+ if (!htif_uses_elf_symbols()) {
75
+ fromhost_addr = nonelf_base;
76
+ tohost_addr = nonelf_base + 8;
77
+ }
78
+
79
+ base = MIN(tohost_addr, fromhost_addr);
80
+ size = MAX(tohost_addr + 8, fromhost_addr + 8) - base;
81
+ tohost_offset = tohost_addr - base;
82
+ fromhost_offset = fromhost_addr - base;
83
84
HTIFState *s = g_malloc0(sizeof(HTIFState));
85
s->address_space = address_space;
86
@@ -XXX,XX +XXX,XX @@ HTIFState *htif_mm_init(MemoryRegion *address_space, MemoryRegion *main_mem,
87
qemu_chr_fe_init(&s->chr, chr, &error_abort);
88
qemu_chr_fe_set_handlers(&s->chr, htif_can_recv, htif_recv, htif_event,
89
htif_be_change, s, NULL, true);
90
- if (address_symbol_set == 3) {
91
- memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
92
- TYPE_HTIF_UART, size);
93
- memory_region_add_subregion_overlap(address_space, base,
94
- &s->mmio, 1);
95
- }
96
+
97
+ memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
98
+ TYPE_HTIF_UART, size);
99
+ memory_region_add_subregion_overlap(address_space, base,
100
+ &s->mmio, 1);
101
102
return s;
103
}
104
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/riscv/spike.c
107
+++ b/hw/riscv/spike.c
108
@@ -XXX,XX +XXX,XX @@
109
110
static const MemMapEntry spike_memmap[] = {
111
[SPIKE_MROM] = { 0x1000, 0xf000 },
112
+ [SPIKE_HTIF] = { 0x1000000, 0x1000 },
113
[SPIKE_CLINT] = { 0x2000000, 0x10000 },
114
[SPIKE_DRAM] = { 0x80000000, 0x0 },
115
};
116
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
117
118
qemu_fdt_add_subnode(fdt, "/htif");
119
qemu_fdt_setprop_string(fdt, "/htif", "compatible", "ucb,htif0");
120
+ if (!htif_uses_elf_symbols()) {
121
+ qemu_fdt_setprop_cells(fdt, "/htif", "reg",
122
+ 0x0, memmap[SPIKE_HTIF].base, 0x0, memmap[SPIKE_HTIF].size);
123
+ }
124
125
qemu_fdt_add_subnode(fdt, "/soc");
126
qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
127
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap,
128
if (cmdline) {
129
qemu_fdt_add_subnode(fdt, "/chosen");
130
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline);
131
+ qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif");
132
}
133
}
134
135
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
136
memory_region_add_subregion(system_memory, memmap[SPIKE_DRAM].base,
137
machine->ram);
138
139
- /* create device tree */
140
- create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
141
- riscv_is_32bit(&s->soc[0]));
142
-
143
/* boot rom */
144
memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom",
145
memmap[SPIKE_MROM].size, &error_fatal);
146
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
147
htif_symbol_callback);
148
}
149
150
+ /* Load kernel */
151
if (machine->kernel_filename) {
152
kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
153
firmware_end_addr);
154
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
155
kernel_entry = riscv_load_kernel(machine->kernel_filename,
156
kernel_start_addr,
157
htif_symbol_callback);
158
-
159
- if (machine->initrd_filename) {
160
- hwaddr start;
161
- hwaddr end = riscv_load_initrd(machine->initrd_filename,
162
- machine->ram_size, kernel_entry,
163
- &start);
164
- qemu_fdt_setprop_cell(s->fdt, "/chosen",
165
- "linux,initrd-start", start);
166
- qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
167
- end);
168
- }
169
} else {
170
/*
171
* If dynamic firmware is used, it doesn't know where is the next mode
172
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
173
kernel_entry = 0;
174
}
175
176
+ /* Create device tree */
177
+ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
178
+ riscv_is_32bit(&s->soc[0]));
179
+
180
+ /* Load initrd */
181
+ if (machine->kernel_filename && machine->initrd_filename) {
182
+ hwaddr start;
183
+ hwaddr end = riscv_load_initrd(machine->initrd_filename,
184
+ machine->ram_size, kernel_entry,
185
+ &start);
186
+ qemu_fdt_setprop_cell(s->fdt, "/chosen",
187
+ "linux,initrd-start", start);
188
+ qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end",
189
+ end);
190
+ }
191
+
192
/* Compute the fdt load address in dram */
193
fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
194
machine->ram_size, s->fdt);
195
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
196
197
/* initialize HTIF using symbols found in load_kernel */
198
htif_mm_init(system_memory, mask_rom,
199
- &s->soc[0].harts[0].env, serial_hd(0));
200
+ &s->soc[0].harts[0].env, serial_hd(0),
201
+ memmap[SPIKE_HTIF].base);
202
}
203
204
static void spike_machine_instance_init(Object *obj)
205
--
206
2.31.1
207
208
diff view generated by jsdifflib
New patch
1
From: Anup Patel <apatel@ventanamicro.com>
1
2
3
Now that RISC-V Spike machine can use BIN BIOS images, we remove
4
the macros used for ELF BIOS image names.
5
6
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/hw/riscv/boot.h | 2 --
12
hw/riscv/spike.c | 4 ++--
13
2 files changed, 2 insertions(+), 4 deletions(-)
14
15
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/riscv/boot.h
18
+++ b/include/hw/riscv/boot.h
19
@@ -XXX,XX +XXX,XX @@
20
#include "hw/riscv/riscv_hart.h"
21
22
#define RISCV32_BIOS_BIN "opensbi-riscv32-generic-fw_dynamic.bin"
23
-#define RISCV32_BIOS_ELF "opensbi-riscv32-generic-fw_dynamic.elf"
24
#define RISCV64_BIOS_BIN "opensbi-riscv64-generic-fw_dynamic.bin"
25
-#define RISCV64_BIOS_ELF "opensbi-riscv64-generic-fw_dynamic.elf"
26
27
bool riscv_is_32bit(RISCVHartArrayState *harts);
28
29
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/riscv/spike.c
32
+++ b/hw/riscv/spike.c
33
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
34
*/
35
if (riscv_is_32bit(&s->soc[0])) {
36
firmware_end_addr = riscv_find_and_load_firmware(machine,
37
- RISCV32_BIOS_ELF, memmap[SPIKE_DRAM].base,
38
+ RISCV32_BIOS_BIN, memmap[SPIKE_DRAM].base,
39
htif_symbol_callback);
40
} else {
41
firmware_end_addr = riscv_find_and_load_firmware(machine,
42
- RISCV64_BIOS_ELF, memmap[SPIKE_DRAM].base,
43
+ RISCV64_BIOS_BIN, memmap[SPIKE_DRAM].base,
44
htif_symbol_callback);
45
}
46
47
--
48
2.31.1
49
50
diff view generated by jsdifflib
New patch
1
From: Anup Patel <apatel@ventanamicro.com>
1
2
3
Now that all RISC-V machines can use OpenSBI BIN images, we remove
4
OpenSBI ELF images and also exclude these images from BIOS build.
5
6
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
.gitlab-ci.d/opensbi.yml | 2 --
12
pc-bios/meson.build | 2 --
13
pc-bios/opensbi-riscv32-generic-fw_dynamic.elf | Bin 838904 -> 0 bytes
14
pc-bios/opensbi-riscv64-generic-fw_dynamic.elf | Bin 934696 -> 0 bytes
15
roms/Makefile | 2 --
16
5 files changed, 6 deletions(-)
17
delete mode 100644 pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
18
delete mode 100644 pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
19
20
diff --git a/.gitlab-ci.d/opensbi.yml b/.gitlab-ci.d/opensbi.yml
21
index XXXXXXX..XXXXXXX 100644
22
--- a/.gitlab-ci.d/opensbi.yml
23
+++ b/.gitlab-ci.d/opensbi.yml
24
@@ -XXX,XX +XXX,XX @@ build-opensbi:
25
artifacts:
26
paths: # 'artifacts.zip' will contains the following files:
27
- pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
28
- - pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
29
- pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
30
- - pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
31
- opensbi32-generic-stdout.log
32
- opensbi32-generic-stderr.log
33
- opensbi64-generic-stdout.log
34
diff --git a/pc-bios/meson.build b/pc-bios/meson.build
35
index XXXXXXX..XXXXXXX 100644
36
--- a/pc-bios/meson.build
37
+++ b/pc-bios/meson.build
38
@@ -XXX,XX +XXX,XX @@ blobs = files(
39
'hppa-firmware.img',
40
'opensbi-riscv32-generic-fw_dynamic.bin',
41
'opensbi-riscv64-generic-fw_dynamic.bin',
42
- 'opensbi-riscv32-generic-fw_dynamic.elf',
43
- 'opensbi-riscv64-generic-fw_dynamic.elf',
44
'npcm7xx_bootrom.bin',
45
)
46
47
diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.elf b/pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
48
deleted file mode 100644
49
index XXXXXXX..XXXXXXX
50
Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.elf and /dev/null differ
51
diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.elf b/pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
52
deleted file mode 100644
53
index XXXXXXX..XXXXXXX
54
Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.elf and /dev/null differ
55
diff --git a/roms/Makefile b/roms/Makefile
56
index XXXXXXX..XXXXXXX 100644
57
--- a/roms/Makefile
58
+++ b/roms/Makefile
59
@@ -XXX,XX +XXX,XX @@ opensbi32-generic:
60
        CROSS_COMPILE=$(riscv32_cross_prefix) \
61
        PLATFORM="generic"
62
    cp opensbi/build/platform/generic/firmware/fw_dynamic.bin ../pc-bios/opensbi-riscv32-generic-fw_dynamic.bin
63
-    cp opensbi/build/platform/generic/firmware/fw_dynamic.elf ../pc-bios/opensbi-riscv32-generic-fw_dynamic.elf
64
65
opensbi64-generic:
66
    $(MAKE) -C opensbi \
67
        CROSS_COMPILE=$(riscv64_cross_prefix) \
68
        PLATFORM="generic"
69
    cp opensbi/build/platform/generic/firmware/fw_dynamic.bin ../pc-bios/opensbi-riscv64-generic-fw_dynamic.bin
70
-    cp opensbi/build/platform/generic/firmware/fw_dynamic.elf ../pc-bios/opensbi-riscv64-generic-fw_dynamic.elf
71
72
MESON = meson
73
NINJA = ninja
74
--
75
2.31.1
76
77
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
If PMP permission of any address has been changed by updating PMP entry,
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
flush all TLB pages to prevent from getting old permission.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 1613916082-19528-4-git-send-email-cwshu@andestech.com
6
Message-id: 20220120122050.41546-2-zhiwei_liu@c-sky.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
8
---
11
target/riscv/pmp.c | 4 ++++
9
target/riscv/csr.c | 19 +++++++++++++++++++
12
1 file changed, 4 insertions(+)
10
target/riscv/pmp.c | 12 ++++--------
11
2 files changed, 23 insertions(+), 8 deletions(-)
13
12
13
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/csr.c
16
+++ b/target/riscv/csr.c
17
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
18
return RISCV_EXCP_NONE;
19
}
20
21
+static bool check_pmp_reg_index(CPURISCVState *env, uint32_t reg_index)
22
+{
23
+ /* TODO: RV128 restriction check */
24
+ if ((reg_index & 1) && (riscv_cpu_mxl(env) == MXL_RV64)) {
25
+ return false;
26
+ }
27
+ return true;
28
+}
29
+
30
static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
31
target_ulong *val)
32
{
33
+ uint32_t reg_index = csrno - CSR_PMPCFG0;
34
+
35
+ if (!check_pmp_reg_index(env, reg_index)) {
36
+ return RISCV_EXCP_ILLEGAL_INST;
37
+ }
38
*val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
39
return RISCV_EXCP_NONE;
40
}
41
@@ -XXX,XX +XXX,XX @@ static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
42
static RISCVException write_pmpcfg(CPURISCVState *env, int csrno,
43
target_ulong val)
44
{
45
+ uint32_t reg_index = csrno - CSR_PMPCFG0;
46
+
47
+ if (!check_pmp_reg_index(env, reg_index)) {
48
+ return RISCV_EXCP_ILLEGAL_INST;
49
+ }
50
pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val);
51
return RISCV_EXCP_NONE;
52
}
14
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
53
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
15
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/pmp.c
55
--- a/target/riscv/pmp.c
17
+++ b/target/riscv/pmp.c
56
+++ b/target/riscv/pmp.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "qapi/error.h"
20
#include "cpu.h"
21
#include "trace.h"
22
+#include "exec/exec-all.h"
23
24
static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
25
uint8_t val);
26
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
57
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
58
{
59
int i;
60
uint8_t cfg_val;
61
+ int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
62
63
trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
64
65
- if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
66
- qemu_log_mask(LOG_GUEST_ERROR,
67
- "ignoring pmpcfg write - incorrect address\n");
68
- return;
69
- }
70
-
71
- for (i = 0; i < sizeof(target_ulong); i++) {
72
+ for (i = 0; i < pmpcfg_nums; i++) {
27
cfg_val = (val >> 8 * i) & 0xff;
73
cfg_val = (val >> 8 * i) & 0xff;
28
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
74
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
29
}
75
}
30
+
76
@@ -XXX,XX +XXX,XX @@ target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index)
31
+ /* If PMP permission of any addr has been changed, flush TLB pages. */
77
int i;
32
+ tlb_flush(env_cpu(env));
78
target_ulong cfg_val = 0;
33
}
79
target_ulong val = 0;
34
80
+ int pmpcfg_nums = 2 << riscv_cpu_mxl(env);
35
81
82
- for (i = 0; i < sizeof(target_ulong); i++) {
83
+ for (i = 0; i < pmpcfg_nums; i++) {
84
val = pmp_read_cfg(env, (reg_index * 4) + i);
85
cfg_val |= (val << (i * 8));
86
}
36
--
87
--
37
2.30.1
88
2.31.1
38
89
39
90
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
As pc will be written by the xepc in exception return, just ignore
4
pc in translation.
5
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220120122050.41546-3-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/helper.h | 4 ++--
13
target/riscv/op_helper.c | 4 ++--
14
target/riscv/insn_trans/trans_privileged.c.inc | 7 ++-----
15
3 files changed, 6 insertions(+), 9 deletions(-)
16
17
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/helper.h
20
+++ b/target/riscv/helper.h
21
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(csrr_i128, tl, env, int)
22
DEF_HELPER_4(csrw_i128, void, env, int, tl, tl)
23
DEF_HELPER_6(csrrw_i128, tl, env, int, tl, tl, tl, tl)
24
#ifndef CONFIG_USER_ONLY
25
-DEF_HELPER_2(sret, tl, env, tl)
26
-DEF_HELPER_2(mret, tl, env, tl)
27
+DEF_HELPER_1(sret, tl, env)
28
+DEF_HELPER_1(mret, tl, env)
29
DEF_HELPER_1(wfi, void, env)
30
DEF_HELPER_1(tlb_flush, void, env)
31
#endif
32
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/riscv/op_helper.c
35
+++ b/target/riscv/op_helper.c
36
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrrw_i128(CPURISCVState *env, int csr,
37
38
#ifndef CONFIG_USER_ONLY
39
40
-target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
41
+target_ulong helper_sret(CPURISCVState *env)
42
{
43
uint64_t mstatus;
44
target_ulong prev_priv, prev_virt;
45
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
46
return retpc;
47
}
48
49
-target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
50
+target_ulong helper_mret(CPURISCVState *env)
51
{
52
if (!(env->priv >= PRV_M)) {
53
riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
54
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/insn_trans/trans_privileged.c.inc
57
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
58
@@ -XXX,XX +XXX,XX @@ static bool trans_uret(DisasContext *ctx, arg_uret *a)
59
static bool trans_sret(DisasContext *ctx, arg_sret *a)
60
{
61
#ifndef CONFIG_USER_ONLY
62
- tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
63
-
64
if (has_ext(ctx, RVS)) {
65
- gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
66
+ gen_helper_sret(cpu_pc, cpu_env);
67
tcg_gen_exit_tb(NULL, 0); /* no chaining */
68
ctx->base.is_jmp = DISAS_NORETURN;
69
} else {
70
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
71
static bool trans_mret(DisasContext *ctx, arg_mret *a)
72
{
73
#ifndef CONFIG_USER_ONLY
74
- tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
75
- gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
76
+ gen_helper_mret(cpu_pc, cpu_env);
77
tcg_gen_exit_tb(NULL, 0); /* no chaining */
78
ctx->base.is_jmp = DISAS_NORETURN;
79
return true;
80
--
81
2.31.1
82
83
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20220120122050.41546-4-zhiwei_liu@c-sky.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
target/riscv/translate.c | 4 +---
9
target/riscv/insn_trans/trans_rvi.c.inc | 4 +---
10
2 files changed, 2 insertions(+), 6 deletions(-)
11
12
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/translate.c
15
+++ b/target/riscv/translate.c
16
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
17
return;
18
}
19
}
20
- if (rd != 0) {
21
- tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
22
- }
23
24
+ gen_set_gpri(ctx, rd, ctx->pc_succ_insn);
25
gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety */
26
ctx->base.is_jmp = DISAS_NORETURN;
27
}
28
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
29
index XXXXXXX..XXXXXXX 100644
30
--- a/target/riscv/insn_trans/trans_rvi.c.inc
31
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
32
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
33
tcg_temp_free(t0);
34
}
35
36
- if (a->rd != 0) {
37
- tcg_gen_movi_tl(cpu_gpr[a->rd], ctx->pc_succ_insn);
38
- }
39
+ gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
40
tcg_gen_lookup_and_goto_ptr();
41
42
if (misaligned) {
43
--
44
2.31.1
45
46
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
When pc is written, it is sign-extended to fill the widest supported XLEN.
4
5
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220120122050.41546-5-zhiwei_liu@c-sky.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/translate.c | 25 ++++++++++++++++---
12
.../riscv/insn_trans/trans_privileged.c.inc | 2 +-
13
target/riscv/insn_trans/trans_rvi.c.inc | 5 ++--
14
target/riscv/insn_trans/trans_rvv.c.inc | 4 +--
15
4 files changed, 27 insertions(+), 9 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 void gen_check_nanbox_s(TCGv_i64 out, TCGv_i64 in)
22
tcg_gen_movcond_i64(TCG_COND_GEU, out, in, t_max, in, t_nan);
23
}
24
25
+static void gen_set_pc_imm(DisasContext *ctx, target_ulong dest)
26
+{
27
+ if (get_xl(ctx) == MXL_RV32) {
28
+ dest = (int32_t)dest;
29
+ }
30
+ tcg_gen_movi_tl(cpu_pc, dest);
31
+}
32
+
33
+static void gen_set_pc(DisasContext *ctx, TCGv dest)
34
+{
35
+ if (get_xl(ctx) == MXL_RV32) {
36
+ tcg_gen_ext32s_tl(cpu_pc, dest);
37
+ } else {
38
+ tcg_gen_mov_tl(cpu_pc, dest);
39
+ }
40
+}
41
+
42
static void generate_exception(DisasContext *ctx, int excp)
43
{
44
- tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
45
+ gen_set_pc_imm(ctx, ctx->base.pc_next);
46
gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
47
ctx->base.is_jmp = DISAS_NORETURN;
48
}
49
50
static void generate_exception_mtval(DisasContext *ctx, int excp)
51
{
52
- tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
53
+ gen_set_pc_imm(ctx, ctx->base.pc_next);
54
tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
55
gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
56
ctx->base.is_jmp = DISAS_NORETURN;
57
@@ -XXX,XX +XXX,XX @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
58
{
59
if (translator_use_goto_tb(&ctx->base, dest)) {
60
tcg_gen_goto_tb(n);
61
- tcg_gen_movi_tl(cpu_pc, dest);
62
+ gen_set_pc_imm(ctx, dest);
63
tcg_gen_exit_tb(ctx->base.tb, n);
64
} else {
65
- tcg_gen_movi_tl(cpu_pc, dest);
66
+ gen_set_pc_imm(ctx, dest);
67
tcg_gen_lookup_and_goto_ptr();
68
}
69
}
70
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/riscv/insn_trans/trans_privileged.c.inc
73
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
74
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
75
static bool trans_wfi(DisasContext *ctx, arg_wfi *a)
76
{
77
#ifndef CONFIG_USER_ONLY
78
- tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
79
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
80
gen_helper_wfi(cpu_env);
81
return true;
82
#else
83
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/riscv/insn_trans/trans_rvi.c.inc
86
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
87
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
88
tcg_gen_addi_tl(cpu_pc, get_gpr(ctx, a->rs1, EXT_NONE), a->imm);
89
tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
90
91
+ gen_set_pc(ctx, cpu_pc);
92
if (!has_ext(ctx, RVC)) {
93
TCGv t0 = tcg_temp_new();
94
95
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
96
* FENCE_I is a no-op in QEMU,
97
* however we need to end the translation block
98
*/
99
- tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
100
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
101
tcg_gen_exit_tb(NULL, 0);
102
ctx->base.is_jmp = DISAS_NORETURN;
103
return true;
104
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
105
static bool do_csr_post(DisasContext *ctx)
106
{
107
/* We may have changed important cpu state -- exit to main loop. */
108
- tcg_gen_movi_tl(cpu_pc, ctx->pc_succ_insn);
109
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
110
tcg_gen_exit_tb(NULL, 0);
111
ctx->base.is_jmp = DISAS_NORETURN;
112
return true;
113
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
114
index XXXXXXX..XXXXXXX 100644
115
--- a/target/riscv/insn_trans/trans_rvv.c.inc
116
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
117
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
118
gen_set_gpr(s, rd, dst);
119
mark_vs_dirty(s);
120
121
- tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
122
+ gen_set_pc_imm(s, s->pc_succ_insn);
123
tcg_gen_lookup_and_goto_ptr();
124
s->base.is_jmp = DISAS_NORETURN;
125
126
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
127
gen_helper_vsetvl(dst, cpu_env, s1, s2);
128
gen_set_gpr(s, rd, dst);
129
mark_vs_dirty(s);
130
- tcg_gen_movi_tl(cpu_pc, s->pc_succ_insn);
131
+ gen_set_pc_imm(s, s->pc_succ_insn);
132
tcg_gen_lookup_and_goto_ptr();
133
s->base.is_jmp = DISAS_NORETURN;
134
135
--
136
2.31.1
137
138
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
According to the specification the "field SPVP of hstatus controls the
3
Current xlen has been used in helper functions and many other places.
4
privilege level of the access" for the hypervisor virtual-machine load
4
The computation of current xlen is not so trivial, so that we should
5
and store instructions HLV, HLVX and HSV.
5
recompute it as little as possible.
6
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
7
Fortunately, xlen only changes in very seldom cases, such as exception,
8
misa write, mstatus write, cpu reset, migration load. So that we can only
9
recompute xlen in this places and cache it into CPURISCVState.
10
11
Signed-off-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
Message-id: 20220120122050.41546-6-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
15
---
12
target/riscv/cpu_helper.c | 25 ++++++++++++++-----------
16
target/riscv/cpu.h | 31 +++++++++++++++++++++++++++++++
13
1 file changed, 14 insertions(+), 11 deletions(-)
17
target/riscv/cpu.c | 1 +
18
target/riscv/cpu_helper.c | 34 ++--------------------------------
19
target/riscv/csr.c | 2 ++
20
target/riscv/machine.c | 10 ++++++++++
21
5 files changed, 46 insertions(+), 32 deletions(-)
14
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 @@ struct CPURISCVState {
28
uint32_t misa_mxl_max; /* max mxl for this cpu */
29
uint32_t misa_ext; /* current extensions */
30
uint32_t misa_ext_mask; /* max ext for this cpu */
31
+ uint32_t xl; /* current xlen */
32
33
/* 128-bit helpers upper part return value */
34
target_ulong retxh;
35
@@ -XXX,XX +XXX,XX @@ static inline RISCVMXL riscv_cpu_mxl(CPURISCVState *env)
36
}
37
#endif
38
39
+#if defined(TARGET_RISCV32)
40
+#define cpu_recompute_xl(env) ((void)(env), MXL_RV32)
41
+#else
42
+static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
43
+{
44
+ RISCVMXL xl = env->misa_mxl;
45
+#if !defined(CONFIG_USER_ONLY)
46
+ /*
47
+ * When emulating a 32-bit-only cpu, use RV32.
48
+ * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
49
+ * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
50
+ * back to RV64 for lower privs.
51
+ */
52
+ if (xl != MXL_RV32) {
53
+ switch (env->priv) {
54
+ case PRV_M:
55
+ break;
56
+ case PRV_U:
57
+ xl = get_field(env->mstatus, MSTATUS64_UXL);
58
+ break;
59
+ default: /* PRV_S | PRV_H */
60
+ xl = get_field(env->mstatus, MSTATUS64_SXL);
61
+ break;
62
+ }
63
+ }
64
+#endif
65
+ return xl;
66
+}
67
+#endif
68
+
69
/*
70
* Encode LMUL to lmul as follows:
71
* LMUL vlmul lmul
72
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/cpu.c
75
+++ b/target/riscv/cpu.c
76
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
77
/* mmte is supposed to have pm.current hardwired to 1 */
78
env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
79
#endif
80
+ env->xl = riscv_cpu_mxl(env);
81
cs->exception_index = RISCV_EXCP_NONE;
82
env->load_res = -1;
83
set_default_nan_mode(1, &env->fp_status);
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
84
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
85
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
86
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
87
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
88
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
20
use_background = true;
89
#endif
90
}
91
92
-static RISCVMXL cpu_get_xl(CPURISCVState *env)
93
-{
94
-#if defined(TARGET_RISCV32)
95
- return MXL_RV32;
96
-#elif defined(CONFIG_USER_ONLY)
97
- return MXL_RV64;
98
-#else
99
- RISCVMXL xl = riscv_cpu_mxl(env);
100
-
101
- /*
102
- * When emulating a 32-bit-only cpu, use RV32.
103
- * When emulating a 64-bit cpu, and MXL has been reduced to RV32,
104
- * MSTATUSH doesn't have UXL/SXL, therefore XLEN cannot be widened
105
- * back to RV64 for lower privs.
106
- */
107
- if (xl != MXL_RV32) {
108
- switch (env->priv) {
109
- case PRV_M:
110
- break;
111
- case PRV_U:
112
- xl = get_field(env->mstatus, MSTATUS64_UXL);
113
- break;
114
- default: /* PRV_S | PRV_H */
115
- xl = get_field(env->mstatus, MSTATUS64_SXL);
116
- break;
117
- }
118
- }
119
- return xl;
120
-#endif
121
-}
122
-
123
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
124
target_ulong *cs_base, uint32_t *pflags)
125
{
126
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
21
}
127
}
22
128
#endif
23
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
129
24
+ /* MPRV does not affect the virtual-machine load/store
130
- flags = FIELD_DP32(flags, TB_FLAGS, XL, cpu_get_xl(env));
25
+ instructions, HLV, HLVX, and HSV. */
131
+ flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
26
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
132
27
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
133
*pflags = flags;
28
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
134
}
29
if (get_field(env->mstatus, MSTATUS_MPRV)) {
135
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
30
mode = get_field(env->mstatus, MSTATUS_MPP);
31
}
32
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
33
qemu_log_mask(CPU_LOG_MMU, "%s ad %" VADDR_PRIx " rw %d mmu_idx %d\n",
34
__func__, address, access_type, mmu_idx);
35
36
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
37
- if (get_field(env->mstatus, MSTATUS_MPRV)) {
38
- mode = get_field(env->mstatus, MSTATUS_MPP);
39
+ /* MPRV does not affect the virtual-machine load/store
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
}
49
}
136
}
50
137
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
51
- if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
138
env->priv = newpriv;
52
- access_type != MMU_INST_FETCH &&
139
+ env->xl = cpu_recompute_xl(env);
53
- get_field(env->mstatus, MSTATUS_MPRV) &&
140
54
- get_field(env->mstatus, MSTATUS_MPV)) {
141
/*
55
- two_stage_lookup = true;
142
* Clear the load reservation - otherwise a reservation placed in one
56
- }
143
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
57
-
144
index XXXXXXX..XXXXXXX 100644
58
if (riscv_cpu_virt_enabled(env) ||
145
--- a/target/riscv/csr.c
59
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
146
+++ b/target/riscv/csr.c
60
access_type != MMU_INST_FETCH)) {
147
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
148
mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
149
}
150
env->mstatus = mstatus;
151
+ env->xl = cpu_recompute_xl(env);
152
153
return RISCV_EXCP_NONE;
154
}
155
@@ -XXX,XX +XXX,XX @@ static RISCVException write_misa(CPURISCVState *env, int csrno,
156
/* flush translation cache */
157
tb_flush(env_cpu(env));
158
env->misa_ext = val;
159
+ env->xl = riscv_cpu_mxl(env);
160
return RISCV_EXCP_NONE;
161
}
162
163
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
164
index XXXXXXX..XXXXXXX 100644
165
--- a/target/riscv/machine.c
166
+++ b/target/riscv/machine.c
167
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_kvmtimer = {
168
}
169
};
170
171
+static int riscv_cpu_post_load(void *opaque, int version_id)
172
+{
173
+ RISCVCPU *cpu = opaque;
174
+ CPURISCVState *env = &cpu->env;
175
+
176
+ env->xl = cpu_recompute_xl(env);
177
+ return 0;
178
+}
179
+
180
const VMStateDescription vmstate_riscv_cpu = {
181
.name = "cpu",
182
.version_id = 3,
183
.minimum_version_id = 3,
184
+ .post_load = riscv_cpu_post_load,
185
.fields = (VMStateField[]) {
186
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
187
VMSTATE_UINT64_ARRAY(env.fpr, RISCVCPU, 32),
61
--
188
--
62
2.30.1
189
2.31.1
63
190
64
191
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
The current condition for the use of background registers only
3
The read from PC for translation is in cpu_get_tb_cpu_state, before translation.
4
considers the hypervisor load and store instructions,
5
but not accesses from M mode via MSTATUS_MPRV+MPV.
6
4
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
5
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103036.1401073-1-georg.kotheimer@kernkonzept.com
8
Message-id: 20220120122050.41546-7-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
10
---
12
target/riscv/cpu_helper.c | 2 +-
11
target/riscv/cpu_helper.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
12
1 file changed, 1 insertion(+), 1 deletion(-)
14
13
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
16
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
17
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
18
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
20
* was called. Background registers will be used if the guest has
19
21
* forced a two stage translation to be on (in HS or M mode).
20
uint32_t flags = 0;
22
*/
21
23
- if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
22
- *pc = env->pc;
24
+ if (!riscv_cpu_virt_enabled(env) && two_stage) {
23
+ *pc = env->xl == MXL_RV32 ? env->pc & UINT32_MAX : env->pc;
25
use_background = true;
24
*cs_base = 0;
26
}
25
27
26
if (riscv_has_ext(env, RVV) || cpu->cfg.ext_zve32f || cpu->cfg.ext_zve64f) {
28
--
27
--
29
2.30.1
28
2.31.1
30
29
31
30
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
In some cases, we must restore the guest PC to the address of the start of
4
the TB, such as when the instruction counter hits zero. So extend pc register
5
according to current xlen for these cases.
6
7
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-id: 20220120122050.41546-8-zhiwei_liu@c-sky.com
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.c | 22 +++++++++++++++++++---
14
1 file changed, 19 insertions(+), 3 deletions(-)
15
16
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/cpu.c
19
+++ b/target/riscv/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_pc(CPUState *cs, vaddr value)
21
{
22
RISCVCPU *cpu = RISCV_CPU(cs);
23
CPURISCVState *env = &cpu->env;
24
- env->pc = value;
25
+
26
+ if (env->xl == MXL_RV32) {
27
+ env->pc = (int32_t)value;
28
+ } else {
29
+ env->pc = value;
30
+ }
31
}
32
33
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
34
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_synchronize_from_tb(CPUState *cs,
35
{
36
RISCVCPU *cpu = RISCV_CPU(cs);
37
CPURISCVState *env = &cpu->env;
38
- env->pc = tb->pc;
39
+ RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
40
+
41
+ if (xl == MXL_RV32) {
42
+ env->pc = (int32_t)tb->pc;
43
+ } else {
44
+ env->pc = tb->pc;
45
+ }
46
}
47
48
static bool riscv_cpu_has_work(CPUState *cs)
49
@@ -XXX,XX +XXX,XX @@ static bool riscv_cpu_has_work(CPUState *cs)
50
void restore_state_to_opc(CPURISCVState *env, TranslationBlock *tb,
51
target_ulong *data)
52
{
53
- env->pc = data[0];
54
+ RISCVMXL xl = FIELD_EX32(tb->flags, TB_FLAGS, XL);
55
+ if (xl == MXL_RV32) {
56
+ env->pc = (int32_t)data[0];
57
+ } else {
58
+ env->pc = data[0];
59
+ }
60
}
61
62
static void riscv_cpu_reset(DeviceState *dev)
63
--
64
2.31.1
65
66
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20220120122050.41546-9-zhiwei_liu@c-sky.com
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
9
target/riscv/cpu.c | 8 ++---
10
target/riscv/gdbstub.c | 71 +++++++++++++++++++++++++++++++-----------
11
2 files changed, 55 insertions(+), 24 deletions(-)
12
13
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.c
16
+++ b/target/riscv/cpu.c
17
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
18
RISCVCPU *cpu = RISCV_CPU(dev);
19
CPURISCVState *env = &cpu->env;
20
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
21
+ CPUClass *cc = CPU_CLASS(mcc);
22
int priv_version = 0;
23
Error *local_err = NULL;
24
25
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
26
switch (env->misa_mxl_max) {
27
#ifdef TARGET_RISCV64
28
case MXL_RV64:
29
+ cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
30
break;
31
case MXL_RV128:
32
break;
33
#endif
34
case MXL_RV32:
35
+ cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
36
break;
37
default:
38
g_assert_not_reached();
39
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
40
cc->gdb_read_register = riscv_cpu_gdb_read_register;
41
cc->gdb_write_register = riscv_cpu_gdb_write_register;
42
cc->gdb_num_core_regs = 33;
43
-#if defined(TARGET_RISCV32)
44
- cc->gdb_core_xml_file = "riscv-32bit-cpu.xml";
45
-#elif defined(TARGET_RISCV64)
46
- cc->gdb_core_xml_file = "riscv-64bit-cpu.xml";
47
-#endif
48
cc->gdb_stop_before_watchpoint = true;
49
cc->disas_set_info = riscv_cpu_disas_set_info;
50
#ifndef CONFIG_USER_ONLY
51
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/gdbstub.c
54
+++ b/target/riscv/gdbstub.c
55
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_gdb_read_register(CPUState *cs, GByteArray *mem_buf, int n)
56
{
57
RISCVCPU *cpu = RISCV_CPU(cs);
58
CPURISCVState *env = &cpu->env;
59
+ target_ulong tmp;
60
61
if (n < 32) {
62
- return gdb_get_regl(mem_buf, env->gpr[n]);
63
+ tmp = env->gpr[n];
64
} else if (n == 32) {
65
- return gdb_get_regl(mem_buf, env->pc);
66
+ tmp = env->pc;
67
+ } else {
68
+ return 0;
69
+ }
70
+
71
+ switch (env->misa_mxl_max) {
72
+ case MXL_RV32:
73
+ return gdb_get_reg32(mem_buf, tmp);
74
+ case MXL_RV64:
75
+ return gdb_get_reg64(mem_buf, tmp);
76
+ default:
77
+ g_assert_not_reached();
78
}
79
return 0;
80
}
81
@@ -XXX,XX +XXX,XX @@ int riscv_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n)
82
{
83
RISCVCPU *cpu = RISCV_CPU(cs);
84
CPURISCVState *env = &cpu->env;
85
-
86
- if (n == 0) {
87
- /* discard writes to x0 */
88
- return sizeof(target_ulong);
89
- } else if (n < 32) {
90
- env->gpr[n] = ldtul_p(mem_buf);
91
- return sizeof(target_ulong);
92
+ int length = 0;
93
+ target_ulong tmp;
94
+
95
+ switch (env->misa_mxl_max) {
96
+ case MXL_RV32:
97
+ tmp = (int32_t)ldl_p(mem_buf);
98
+ length = 4;
99
+ break;
100
+ case MXL_RV64:
101
+ if (env->xl < MXL_RV64) {
102
+ tmp = (int32_t)ldq_p(mem_buf);
103
+ } else {
104
+ tmp = ldq_p(mem_buf);
105
+ }
106
+ length = 8;
107
+ break;
108
+ default:
109
+ g_assert_not_reached();
110
+ }
111
+ if (n > 0 && n < 32) {
112
+ env->gpr[n] = tmp;
113
} else if (n == 32) {
114
- env->pc = ldtul_p(mem_buf);
115
- return sizeof(target_ulong);
116
+ env->pc = tmp;
117
}
118
- return 0;
119
+
120
+ return length;
121
}
122
123
static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
124
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
125
cs->gdb_num_regs),
126
"riscv-vector.xml", 0);
127
}
128
-#if defined(TARGET_RISCV32)
129
- gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
130
- 1, "riscv-32bit-virtual.xml", 0);
131
-#elif defined(TARGET_RISCV64)
132
- gdb_register_coprocessor(cs, riscv_gdb_get_virtual, riscv_gdb_set_virtual,
133
- 1, "riscv-64bit-virtual.xml", 0);
134
-#endif
135
+ switch (env->misa_mxl_max) {
136
+ case MXL_RV32:
137
+ gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
138
+ riscv_gdb_set_virtual,
139
+ 1, "riscv-32bit-virtual.xml", 0);
140
+ break;
141
+ case MXL_RV64:
142
+ gdb_register_coprocessor(cs, riscv_gdb_get_virtual,
143
+ riscv_gdb_set_virtual,
144
+ 1, "riscv-64bit-virtual.xml", 0);
145
+ break;
146
+ default:
147
+ g_assert_not_reached();
148
+ }
149
150
gdb_register_coprocessor(cs, riscv_gdb_get_csr, riscv_gdb_set_csr,
151
riscv_gen_dynamic_csr_xml(cs, cs->gdb_num_regs),
152
--
153
2.31.1
154
155
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
vs() should return -RISCV_EXCP_ILLEGAL_INST instead of -1 if rvv feature
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
is not enabled.
5
6
If -1 is returned, exception will be raised and cs->exception_index will
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
10
Signed-off-by: Frank Chang <frank.chang@sifive.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-id: 20210223065935.20208-1-frank.chang@sifive.com
6
Message-id: 20220120122050.41546-10-zhiwei_liu@c-sky.com
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
8
---
16
target/riscv/csr.c | 2 +-
9
target/riscv/csr.c | 3 +++
17
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 3 insertions(+)
18
11
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
12
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
14
--- a/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
15
+++ b/target/riscv/csr.c
23
@@ -XXX,XX +XXX,XX @@ static int vs(CPURISCVState *env, int csrno)
16
@@ -XXX,XX +XXX,XX @@ static bool check_pm_current_disabled(CPURISCVState *env, int csrno)
24
if (env->misa & RVV) {
17
int csr_priv = get_field(csrno, 0x300);
25
return 0;
18
int pm_current;
26
}
19
27
- return -1;
20
+ if (env->debugger) {
28
+ return -RISCV_EXCP_ILLEGAL_INST;
21
+ return false;
29
}
22
+ }
30
23
/*
31
static int ctr(CPURISCVState *env, int csrno)
24
* If priv lvls differ that means we're accessing csr from higher priv lvl,
25
* so allow the access
32
--
26
--
33
2.30.1
27
2.31.1
34
28
35
29
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
Write mask is representing the bits we care about.
4
5
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220120122050.41546-11-zhiwei_liu@c-sky.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/op_helper.c | 3 ++-
12
target/riscv/insn_trans/trans_rvi.c.inc | 12 ++++++++----
13
2 files changed, 10 insertions(+), 5 deletions(-)
14
15
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/op_helper.c
18
+++ b/target/riscv/op_helper.c
19
@@ -XXX,XX +XXX,XX @@ target_ulong helper_csrr(CPURISCVState *env, int csr)
20
21
void helper_csrw(CPURISCVState *env, int csr, target_ulong src)
22
{
23
- RISCVException ret = riscv_csrrw(env, csr, NULL, src, -1);
24
+ target_ulong mask = env->xl == MXL_RV32 ? UINT32_MAX : (target_ulong)-1;
25
+ RISCVException ret = riscv_csrrw(env, csr, NULL, src, mask);
26
27
if (ret != RISCV_EXCP_NONE) {
28
riscv_raise_exception(env, ret, GETPC());
29
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/insn_trans/trans_rvi.c.inc
32
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
33
@@ -XXX,XX +XXX,XX @@ static bool do_csrrw_i128(DisasContext *ctx, int rd, int rc,
34
35
static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
36
{
37
- if (get_xl(ctx) < MXL_RV128) {
38
+ RISCVMXL xl = get_xl(ctx);
39
+ if (xl < MXL_RV128) {
40
TCGv src = get_gpr(ctx, a->rs1, EXT_NONE);
41
42
/*
43
@@ -XXX,XX +XXX,XX @@ static bool trans_csrrw(DisasContext *ctx, arg_csrrw *a)
44
return do_csrw(ctx, a->csr, src);
45
}
46
47
- TCGv mask = tcg_constant_tl(-1);
48
+ TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
49
+ (target_ulong)-1);
50
return do_csrrw(ctx, a->rd, a->csr, src, mask);
51
} else {
52
TCGv srcl = get_gpr(ctx, a->rs1, EXT_NONE);
53
@@ -XXX,XX +XXX,XX @@ static bool trans_csrrc(DisasContext *ctx, arg_csrrc *a)
54
55
static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
56
{
57
- if (get_xl(ctx) < MXL_RV128) {
58
+ RISCVMXL xl = get_xl(ctx);
59
+ if (xl < MXL_RV128) {
60
TCGv src = tcg_constant_tl(a->rs1);
61
62
/*
63
@@ -XXX,XX +XXX,XX @@ static bool trans_csrrwi(DisasContext *ctx, arg_csrrwi *a)
64
return do_csrw(ctx, a->csr, src);
65
}
66
67
- TCGv mask = tcg_constant_tl(-1);
68
+ TCGv mask = tcg_constant_tl(xl == MXL_RV32 ? UINT32_MAX :
69
+ (target_ulong)-1);
70
return do_csrrw(ctx, a->rd, a->csr, src, mask);
71
} else {
72
TCGv src = tcg_constant_tl(a->rs1);
73
--
74
2.31.1
75
76
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
The current two-stage lookup detection in riscv_cpu_do_interrupt falls
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
short of its purpose, as all it checks is whether two-stage address
5
translation either via the hypervisor-load store instructions or the
6
MPRV feature would be allowed.
7
8
What we really need instead is whether two-stage address translation was
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>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-id: 20210319141459.1196741-1-georg.kotheimer@kernkonzept.com
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20220120122050.41546-12-zhiwei_liu@c-sky.com
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
8
---
19
target/riscv/cpu.h | 4 ++++
9
target/riscv/cpu.h | 4 ++++
20
target/riscv/cpu.c | 1 +
10
target/riscv/cpu.c | 1 +
21
target/riscv/cpu_helper.c | 21 ++++++++-------------
11
target/riscv/cpu_helper.c | 43 +++++++++++++++++++++++++++++++++++++++
22
3 files changed, 13 insertions(+), 13 deletions(-)
12
target/riscv/csr.c | 19 +++++++++++++++++
13
target/riscv/machine.c | 1 +
14
5 files changed, 68 insertions(+)
23
15
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
16
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
18
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
19
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
20
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
29
target_ulong satp_hs;
21
target_ulong upmmask;
30
uint64_t mstatus_hs;
22
target_ulong upmbase;
31
23
#endif
32
+ /* Signals whether the current exception occurred with two-stage address
24
+ target_ulong cur_pmmask;
33
+ translation active. */
25
+ target_ulong cur_pmbase;
34
+ bool two_stage_lookup;
26
27
float_status fp_status;
28
29
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_get_vlmax(RISCVCPU *cpu, target_ulong vtype)
30
void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
31
target_ulong *cs_base, uint32_t *pflags);
32
33
+void riscv_cpu_update_mask(CPURISCVState *env);
35
+
34
+
36
target_ulong scounteren;
35
RISCVException riscv_csrrw(CPURISCVState *env, int csrno,
37
target_ulong mcounteren;
36
target_ulong *ret_value,
38
37
target_ulong new_value, target_ulong write_mask);
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
38
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
index XXXXXXX..XXXXXXX 100644
39
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/cpu.c
40
--- a/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
41
+++ b/target/riscv/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
42
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
44
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
43
env->mmte |= (PM_EXT_INITIAL | MMTE_M_PM_CURRENT);
45
env->mcause = 0;
46
env->pc = env->resetvec;
47
+ env->two_stage_lookup = false;
48
#endif
44
#endif
49
cs->exception_index = EXCP_NONE;
45
env->xl = riscv_cpu_mxl(env);
46
+ riscv_cpu_update_mask(env);
47
cs->exception_index = RISCV_EXCP_NONE;
50
env->load_res = -1;
48
env->load_res = -1;
49
set_default_nan_mode(1, &env->fp_status);
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
50
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
52
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu_helper.c
52
--- a/target/riscv/cpu_helper.c
54
+++ b/target/riscv/cpu_helper.c
53
+++ b/target/riscv/cpu_helper.c
55
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
56
g_assert_not_reached();
55
*pflags = flags;
56
}
57
58
+void riscv_cpu_update_mask(CPURISCVState *env)
59
+{
60
+ target_ulong mask = -1, base = 0;
61
+ /*
62
+ * TODO: Current RVJ spec does not specify
63
+ * how the extension interacts with XLEN.
64
+ */
65
+#ifndef CONFIG_USER_ONLY
66
+ if (riscv_has_ext(env, RVJ)) {
67
+ switch (env->priv) {
68
+ case PRV_M:
69
+ if (env->mmte & M_PM_ENABLE) {
70
+ mask = env->mpmmask;
71
+ base = env->mpmbase;
72
+ }
73
+ break;
74
+ case PRV_S:
75
+ if (env->mmte & S_PM_ENABLE) {
76
+ mask = env->spmmask;
77
+ base = env->spmbase;
78
+ }
79
+ break;
80
+ case PRV_U:
81
+ if (env->mmte & U_PM_ENABLE) {
82
+ mask = env->upmmask;
83
+ base = env->upmbase;
84
+ }
85
+ break;
86
+ default:
87
+ g_assert_not_reached();
88
+ }
89
+ }
90
+#endif
91
+ if (env->xl == MXL_RV32) {
92
+ env->cur_pmmask = mask & UINT32_MAX;
93
+ env->cur_pmbase = base & UINT32_MAX;
94
+ } else {
95
+ env->cur_pmmask = mask;
96
+ env->cur_pmbase = base;
97
+ }
98
+}
99
+
100
#ifndef CONFIG_USER_ONLY
101
static int riscv_cpu_local_irq_pending(CPURISCVState *env)
102
{
103
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
104
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
105
env->priv = newpriv;
106
env->xl = cpu_recompute_xl(env);
107
+ riscv_cpu_update_mask(env);
108
109
/*
110
* Clear the load reservation - otherwise a reservation placed in one
111
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
112
index XXXXXXX..XXXXXXX 100644
113
--- a/target/riscv/csr.c
114
+++ b/target/riscv/csr.c
115
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mmte(CPURISCVState *env, int csrno,
116
/* hardwiring pm.instruction bit to 0, since it's not supported yet */
117
wpri_val &= ~(MMTE_M_PM_INSN | MMTE_S_PM_INSN | MMTE_U_PM_INSN);
118
env->mmte = wpri_val | PM_EXT_DIRTY;
119
+ riscv_cpu_update_mask(env);
120
121
/* Set XS and SD bits, since PM CSRs are dirty */
122
mstatus = env->mstatus | MSTATUS_XS;
123
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mpmmask(CPURISCVState *env, int csrno,
124
uint64_t mstatus;
125
126
env->mpmmask = val;
127
+ if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
128
+ env->cur_pmmask = val;
129
+ }
130
env->mmte |= PM_EXT_DIRTY;
131
132
/* Set XS and SD bits, since PM CSRs are dirty */
133
@@ -XXX,XX +XXX,XX @@ static RISCVException write_spmmask(CPURISCVState *env, int csrno,
134
return RISCV_EXCP_NONE;
57
}
135
}
58
env->badaddr = address;
136
env->spmmask = val;
59
+ env->two_stage_lookup = two_stage;
137
+ if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
138
+ env->cur_pmmask = val;
139
+ }
140
env->mmte |= PM_EXT_DIRTY;
141
142
/* Set XS and SD bits, since PM CSRs are dirty */
143
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmmask(CPURISCVState *env, int csrno,
144
return RISCV_EXCP_NONE;
145
}
146
env->upmmask = val;
147
+ if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
148
+ env->cur_pmmask = val;
149
+ }
150
env->mmte |= PM_EXT_DIRTY;
151
152
/* Set XS and SD bits, since PM CSRs are dirty */
153
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mpmbase(CPURISCVState *env, int csrno,
154
uint64_t mstatus;
155
156
env->mpmbase = val;
157
+ if ((env->priv == PRV_M) && (env->mmte & M_PM_ENABLE)) {
158
+ env->cur_pmbase = val;
159
+ }
160
env->mmte |= PM_EXT_DIRTY;
161
162
/* Set XS and SD bits, since PM CSRs are dirty */
163
@@ -XXX,XX +XXX,XX @@ static RISCVException write_spmbase(CPURISCVState *env, int csrno,
164
return RISCV_EXCP_NONE;
165
}
166
env->spmbase = val;
167
+ if ((env->priv == PRV_S) && (env->mmte & S_PM_ENABLE)) {
168
+ env->cur_pmbase = val;
169
+ }
170
env->mmte |= PM_EXT_DIRTY;
171
172
/* Set XS and SD bits, since PM CSRs are dirty */
173
@@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno,
174
return RISCV_EXCP_NONE;
175
}
176
env->upmbase = val;
177
+ if ((env->priv == PRV_U) && (env->mmte & U_PM_ENABLE)) {
178
+ env->cur_pmbase = val;
179
+ }
180
env->mmte |= PM_EXT_DIRTY;
181
182
/* Set XS and SD bits, since PM CSRs are dirty */
183
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
184
index XXXXXXX..XXXXXXX 100644
185
--- a/target/riscv/machine.c
186
+++ b/target/riscv/machine.c
187
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_post_load(void *opaque, int version_id)
188
CPURISCVState *env = &cpu->env;
189
190
env->xl = cpu_recompute_xl(env);
191
+ riscv_cpu_update_mask(env);
192
return 0;
60
}
193
}
61
194
62
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
64
}
65
66
env->badaddr = addr;
67
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
68
+ riscv_cpu_two_stage_lookup(mmu_idx);
69
riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
70
}
71
72
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
73
g_assert_not_reached();
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
117
cs->exception_index = EXCP_NONE; /* mark handled to qemu */
118
}
119
--
195
--
120
2.30.1
196
2.31.1
121
197
122
198
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
Replace the array of pm_mask/pm_base with scalar variables.
4
Remove the cached array value in DisasContext.
5
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220120122050.41546-13-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/translate.c | 32 ++++++++------------------------
13
1 file changed, 8 insertions(+), 24 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 TCGv_i64 cpu_fpr[32]; /* assume F and D extensions */
20
static TCGv load_res;
21
static TCGv load_val;
22
/* globals for PM CSRs */
23
-static TCGv pm_mask[4];
24
-static TCGv pm_base[4];
25
+static TCGv pm_mask;
26
+static TCGv pm_base;
27
28
#include "exec/gen-icount.h"
29
30
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
31
TCGv temp[4];
32
/* PointerMasking extension */
33
bool pm_enabled;
34
- TCGv pm_mask;
35
- TCGv pm_base;
36
} DisasContext;
37
38
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
39
@@ -XXX,XX +XXX,XX @@ static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
40
return src;
41
} else {
42
temp = temp_new(s);
43
- tcg_gen_andc_tl(temp, src, s->pm_mask);
44
- tcg_gen_or_tl(temp, temp, s->pm_base);
45
+ tcg_gen_andc_tl(temp, src, pm_mask);
46
+ tcg_gen_or_tl(temp, temp, pm_base);
47
return temp;
48
}
49
}
50
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
51
ctx->ntemp = 0;
52
memset(ctx->temp, 0, sizeof(ctx->temp));
53
ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
54
- int priv = tb_flags & TB_FLAGS_PRIV_MMU_MASK;
55
- ctx->pm_mask = pm_mask[priv];
56
- ctx->pm_base = pm_base[priv];
57
-
58
ctx->zero = tcg_constant_tl(0);
59
}
60
61
@@ -XXX,XX +XXX,XX @@ void riscv_translate_init(void)
62
"load_res");
63
load_val = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, load_val),
64
"load_val");
65
-#ifndef CONFIG_USER_ONLY
66
/* Assign PM CSRs to tcg globals */
67
- pm_mask[PRV_U] =
68
- tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmmask), "upmmask");
69
- pm_base[PRV_U] =
70
- tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, upmbase), "upmbase");
71
- pm_mask[PRV_S] =
72
- tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmmask), "spmmask");
73
- pm_base[PRV_S] =
74
- tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, spmbase), "spmbase");
75
- pm_mask[PRV_M] =
76
- tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmmask), "mpmmask");
77
- pm_base[PRV_M] =
78
- tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, mpmbase), "mpmbase");
79
-#endif
80
+ pm_mask = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmmask),
81
+ "pmmask");
82
+ pm_base = tcg_global_mem_new(cpu_env, offsetof(CPURISCVState, cur_pmbase),
83
+ "pmbase");
84
}
85
--
86
2.31.1
87
88
diff view generated by jsdifflib
New patch
1
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
3
Define one common function to compute a canonical address from a register
4
plus offset. Merge gen_pm_adjust_address into this function.
5
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220120122050.41546-14-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/translate.c | 25 ++++++++++++-------------
13
target/riscv/insn_trans/trans_rva.c.inc | 9 +++------
14
target/riscv/insn_trans/trans_rvd.c.inc | 19 ++-----------------
15
target/riscv/insn_trans/trans_rvf.c.inc | 19 ++-----------------
16
target/riscv/insn_trans/trans_rvi.c.inc | 18 ++----------------
17
5 files changed, 21 insertions(+), 69 deletions(-)
18
19
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/translate.c
22
+++ b/target/riscv/translate.c
23
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
24
ctx->base.is_jmp = DISAS_NORETURN;
25
}
26
27
-/*
28
- * Generates address adjustment for PointerMasking
29
- */
30
-static TCGv gen_pm_adjust_address(DisasContext *s, TCGv src)
31
+/* Compute a canonical address from a register plus offset. */
32
+static TCGv get_address(DisasContext *ctx, int rs1, int imm)
33
{
34
- TCGv temp;
35
- if (!s->pm_enabled) {
36
- /* Load unmodified address */
37
- return src;
38
- } else {
39
- temp = temp_new(s);
40
- tcg_gen_andc_tl(temp, src, pm_mask);
41
- tcg_gen_or_tl(temp, temp, pm_base);
42
- return temp;
43
+ TCGv addr = temp_new(ctx);
44
+ TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
45
+
46
+ tcg_gen_addi_tl(addr, src1, imm);
47
+ if (ctx->pm_enabled) {
48
+ tcg_gen_and_tl(addr, addr, pm_mask);
49
+ tcg_gen_or_tl(addr, addr, pm_base);
50
+ } else if (get_xl(ctx) == MXL_RV32) {
51
+ tcg_gen_ext32u_tl(addr, addr);
52
}
53
+ return addr;
54
}
55
56
#ifndef CONFIG_USER_ONLY
57
diff --git a/target/riscv/insn_trans/trans_rva.c.inc b/target/riscv/insn_trans/trans_rva.c.inc
58
index XXXXXXX..XXXXXXX 100644
59
--- a/target/riscv/insn_trans/trans_rva.c.inc
60
+++ b/target/riscv/insn_trans/trans_rva.c.inc
61
@@ -XXX,XX +XXX,XX @@
62
63
static bool gen_lr(DisasContext *ctx, arg_atomic *a, MemOp mop)
64
{
65
- TCGv src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
66
+ TCGv src1 = get_address(ctx, a->rs1, 0);
67
68
if (a->rl) {
69
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
70
}
71
- src1 = gen_pm_adjust_address(ctx, src1);
72
tcg_gen_qemu_ld_tl(load_val, src1, ctx->mem_idx, mop);
73
if (a->aq) {
74
tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
75
@@ -XXX,XX +XXX,XX @@ static bool gen_sc(DisasContext *ctx, arg_atomic *a, MemOp mop)
76
TCGLabel *l1 = gen_new_label();
77
TCGLabel *l2 = gen_new_label();
78
79
- src1 = get_gpr(ctx, a->rs1, EXT_ZERO);
80
- src1 = gen_pm_adjust_address(ctx, src1);
81
+ src1 = get_address(ctx, a->rs1, 0);
82
tcg_gen_brcond_tl(TCG_COND_NE, load_res, src1, l1);
83
84
/*
85
@@ -XXX,XX +XXX,XX @@ static bool gen_amo(DisasContext *ctx, arg_atomic *a,
86
MemOp mop)
87
{
88
TCGv dest = dest_gpr(ctx, a->rd);
89
- TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE);
90
+ TCGv src1 = get_address(ctx, a->rs1, 0);
91
TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE);
92
93
- src1 = gen_pm_adjust_address(ctx, src1);
94
func(dest, src1, src2, ctx->mem_idx, mop);
95
96
gen_set_gpr(ctx, a->rd, dest);
97
diff --git a/target/riscv/insn_trans/trans_rvd.c.inc b/target/riscv/insn_trans/trans_rvd.c.inc
98
index XXXXXXX..XXXXXXX 100644
99
--- a/target/riscv/insn_trans/trans_rvd.c.inc
100
+++ b/target/riscv/insn_trans/trans_rvd.c.inc
101
@@ -XXX,XX +XXX,XX @@ static bool trans_fld(DisasContext *ctx, arg_fld *a)
102
REQUIRE_FPU;
103
REQUIRE_EXT(ctx, RVD);
104
105
- addr = get_gpr(ctx, a->rs1, EXT_NONE);
106
- if (a->imm) {
107
- TCGv temp = temp_new(ctx);
108
- tcg_gen_addi_tl(temp, addr, a->imm);
109
- addr = temp;
110
- }
111
- addr = gen_pm_adjust_address(ctx, addr);
112
-
113
+ addr = get_address(ctx, a->rs1, a->imm);
114
tcg_gen_qemu_ld_i64(cpu_fpr[a->rd], addr, ctx->mem_idx, MO_TEUQ);
115
116
mark_fs_dirty(ctx);
117
@@ -XXX,XX +XXX,XX @@ static bool trans_fsd(DisasContext *ctx, arg_fsd *a)
118
REQUIRE_FPU;
119
REQUIRE_EXT(ctx, RVD);
120
121
- addr = get_gpr(ctx, a->rs1, EXT_NONE);
122
- if (a->imm) {
123
- TCGv temp = temp_new(ctx);
124
- tcg_gen_addi_tl(temp, addr, a->imm);
125
- addr = temp;
126
- }
127
- addr = gen_pm_adjust_address(ctx, addr);
128
-
129
+ addr = get_address(ctx, a->rs1, a->imm);
130
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUQ);
131
-
132
return true;
133
}
134
135
diff --git a/target/riscv/insn_trans/trans_rvf.c.inc b/target/riscv/insn_trans/trans_rvf.c.inc
136
index XXXXXXX..XXXXXXX 100644
137
--- a/target/riscv/insn_trans/trans_rvf.c.inc
138
+++ b/target/riscv/insn_trans/trans_rvf.c.inc
139
@@ -XXX,XX +XXX,XX @@ static bool trans_flw(DisasContext *ctx, arg_flw *a)
140
REQUIRE_FPU;
141
REQUIRE_EXT(ctx, RVF);
142
143
- addr = get_gpr(ctx, a->rs1, EXT_NONE);
144
- if (a->imm) {
145
- TCGv temp = temp_new(ctx);
146
- tcg_gen_addi_tl(temp, addr, a->imm);
147
- addr = temp;
148
- }
149
- addr = gen_pm_adjust_address(ctx, addr);
150
-
151
+ addr = get_address(ctx, a->rs1, a->imm);
152
dest = cpu_fpr[a->rd];
153
tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_TEUL);
154
gen_nanbox_s(dest, dest);
155
@@ -XXX,XX +XXX,XX @@ static bool trans_fsw(DisasContext *ctx, arg_fsw *a)
156
REQUIRE_FPU;
157
REQUIRE_EXT(ctx, RVF);
158
159
- addr = get_gpr(ctx, a->rs1, EXT_NONE);
160
- if (a->imm) {
161
- TCGv temp = tcg_temp_new();
162
- tcg_gen_addi_tl(temp, addr, a->imm);
163
- addr = temp;
164
- }
165
- addr = gen_pm_adjust_address(ctx, addr);
166
-
167
+ addr = get_address(ctx, a->rs1, a->imm);
168
tcg_gen_qemu_st_i64(cpu_fpr[a->rs2], addr, ctx->mem_idx, MO_TEUL);
169
-
170
return true;
171
}
172
173
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
174
index XXXXXXX..XXXXXXX 100644
175
--- a/target/riscv/insn_trans/trans_rvi.c.inc
176
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
177
@@ -XXX,XX +XXX,XX @@ static bool trans_bgeu(DisasContext *ctx, arg_bgeu *a)
178
static bool gen_load_tl(DisasContext *ctx, arg_lb *a, MemOp memop)
179
{
180
TCGv dest = dest_gpr(ctx, a->rd);
181
- TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
182
-
183
- if (a->imm) {
184
- TCGv temp = temp_new(ctx);
185
- tcg_gen_addi_tl(temp, addr, a->imm);
186
- addr = temp;
187
- }
188
- addr = gen_pm_adjust_address(ctx, addr);
189
+ TCGv addr = get_address(ctx, a->rs1, a->imm);
190
191
tcg_gen_qemu_ld_tl(dest, addr, ctx->mem_idx, memop);
192
gen_set_gpr(ctx, a->rd, dest);
193
@@ -XXX,XX +XXX,XX @@ static bool trans_ldu(DisasContext *ctx, arg_ldu *a)
194
195
static bool gen_store_tl(DisasContext *ctx, arg_sb *a, MemOp memop)
196
{
197
- TCGv addr = get_gpr(ctx, a->rs1, EXT_NONE);
198
+ TCGv addr = get_address(ctx, a->rs1, a->imm);
199
TCGv data = get_gpr(ctx, a->rs2, EXT_NONE);
200
201
- if (a->imm) {
202
- TCGv temp = temp_new(ctx);
203
- tcg_gen_addi_tl(temp, addr, a->imm);
204
- addr = temp;
205
- }
206
- addr = gen_pm_adjust_address(ctx, addr);
207
-
208
tcg_gen_qemu_st_tl(data, addr, ctx->mem_idx, memop);
209
return true;
210
}
211
--
212
2.31.1
213
214
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
When decode_insn16() fails, we fall back to decode_RV32_64C() for
3
Use cached cur_pmmask and cur_pmbase to infer the
4
further compressed instruction decoding. However, prior to this change,
4
current PM mode.
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
This may decrease the TCG IR by one when pm_enabled
11
as it is dead code since f330433b363 anyway.
7
is true and pm_base_enabled is false.
12
8
13
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
9
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20220120122050.41546-15-zhiwei_liu@c-sky.com
16
Message-id: 20210322121609.3097928-1-georg.kotheimer@kernkonzept.com
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
14
---
19
target/riscv/translate.c | 179 +--------------------------------------
15
target/riscv/cpu.h | 3 ++-
20
1 file changed, 1 insertion(+), 178 deletions(-)
16
target/riscv/cpu_helper.c | 24 ++++++------------------
17
target/riscv/translate.c | 12 ++++++++----
18
3 files changed, 16 insertions(+), 23 deletions(-)
21
19
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
24
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, MSTATUS_HS_VS, 18, 2)
25
/* The combination of MXL/SXL/UXL that applies to the current cpu mode. */
26
FIELD(TB_FLAGS, XL, 20, 2)
27
/* If PointerMasking should be applied */
28
-FIELD(TB_FLAGS, PM_ENABLED, 22, 1)
29
+FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
30
+FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
31
32
#ifdef TARGET_RISCV32
33
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
34
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/cpu_helper.c
37
+++ b/target/riscv/cpu_helper.c
38
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
39
flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
40
get_field(env->mstatus_hs, MSTATUS_VS));
41
}
42
- if (riscv_has_ext(env, RVJ)) {
43
- int priv = flags & TB_FLAGS_PRIV_MMU_MASK;
44
- bool pm_enabled = false;
45
- switch (priv) {
46
- case PRV_U:
47
- pm_enabled = env->mmte & U_PM_ENABLE;
48
- break;
49
- case PRV_S:
50
- pm_enabled = env->mmte & S_PM_ENABLE;
51
- break;
52
- case PRV_M:
53
- pm_enabled = env->mmte & M_PM_ENABLE;
54
- break;
55
- default:
56
- g_assert_not_reached();
57
- }
58
- flags = FIELD_DP32(flags, TB_FLAGS, PM_ENABLED, pm_enabled);
59
- }
60
#endif
61
62
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
63
+ if (env->cur_pmmask < (env->xl == MXL_RV32 ? UINT32_MAX : UINT64_MAX)) {
64
+ flags = FIELD_DP32(flags, TB_FLAGS, PM_MASK_ENABLED, 1);
65
+ }
66
+ if (env->cur_pmbase != 0) {
67
+ flags = FIELD_DP32(flags, TB_FLAGS, PM_BASE_ENABLED, 1);
68
+ }
69
70
*pflags = flags;
71
}
22
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
72
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
23
index XXXXXXX..XXXXXXX 100644
73
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/translate.c
74
--- a/target/riscv/translate.c
25
+++ b/target/riscv/translate.c
75
+++ b/target/riscv/translate.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
76
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
27
CPUState *cs;
77
/* Space for 3 operands plus 1 extra for address computation. */
78
TCGv temp[4];
79
/* PointerMasking extension */
80
- bool pm_enabled;
81
+ bool pm_mask_enabled;
82
+ bool pm_base_enabled;
28
} DisasContext;
83
} DisasContext;
29
84
30
-#ifdef TARGET_RISCV64
85
static inline bool has_ext(DisasContext *ctx, uint32_t ext)
31
-/* convert riscv funct3 to qemu memop for load/store */
86
@@ -XXX,XX +XXX,XX @@ static TCGv get_address(DisasContext *ctx, int rs1, int imm)
32
-static const int tcg_memop_lookup[8] = {
87
TCGv src1 = get_gpr(ctx, rs1, EXT_NONE);
33
- [0 ... 7] = -1,
88
34
- [0] = MO_SB,
89
tcg_gen_addi_tl(addr, src1, imm);
35
- [1] = MO_TESW,
90
- if (ctx->pm_enabled) {
36
- [2] = MO_TESL,
91
+ if (ctx->pm_mask_enabled) {
37
- [3] = MO_TEQ,
92
tcg_gen_and_tl(addr, addr, pm_mask);
38
- [4] = MO_UB,
93
- tcg_gen_or_tl(addr, addr, pm_base);
39
- [5] = MO_TEUW,
94
} else if (get_xl(ctx) == MXL_RV32) {
40
- [6] = MO_TEUL,
95
tcg_gen_ext32u_tl(addr, addr);
41
-};
96
}
42
-#endif
97
+ if (ctx->pm_base_enabled) {
43
-
98
+ tcg_gen_or_tl(addr, addr, pm_base);
44
#ifdef TARGET_RISCV64
99
+ }
45
#define CASE_OP_32_64(X) case X: case glue(X, W)
100
return addr;
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
}
101
}
50
102
51
-#ifdef TARGET_RISCV64
103
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
52
-static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
104
ctx->cs = cs;
53
- target_long imm)
105
ctx->ntemp = 0;
54
-{
106
memset(ctx->temp, 0, sizeof(ctx->temp));
55
- TCGv t0 = tcg_temp_new();
107
- ctx->pm_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_ENABLED);
56
- TCGv t1 = tcg_temp_new();
108
+ ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
57
- gen_get_gpr(t0, rs1);
109
+ ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
58
- tcg_gen_addi_tl(t0, t0, imm);
110
ctx->zero = tcg_constant_tl(0);
59
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
60
-
61
- if (memop < 0) {
62
- gen_exception_illegal(ctx);
63
- return;
64
- }
65
-
66
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
67
- gen_set_gpr(rd, t1);
68
- tcg_temp_free(t0);
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
{
179
TCGv_i32 t0;
180
@@ -XXX,XX +XXX,XX @@ static void gen_set_rm(DisasContext *ctx, int rm)
181
tcg_temp_free_i32(t0);
182
}
111
}
183
112
184
-static void decode_RV32_64C0(DisasContext *ctx, uint16_t opcode)
185
-{
186
- uint8_t funct3 = extract16(opcode, 13, 3);
187
- uint8_t rd_rs2 = GET_C_RS2S(opcode);
188
- uint8_t rs1s = GET_C_RS1S(opcode);
189
-
190
- switch (funct3) {
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
{
229
return nf + 1;
230
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
231
} else {
232
ctx->pc_succ_insn = ctx->base.pc_next + 2;
233
if (!decode_insn16(ctx, opcode)) {
234
- /* fall back to old decoder */
235
- decode_RV32_64C(ctx, opcode);
236
+ gen_exception_illegal(ctx);
237
}
238
}
239
} else {
240
--
113
--
241
2.30.1
114
2.31.1
242
115
243
116
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
Like MMU translation, add qemu log of PMP permission checking for
3
We need not specially process vtype when XLEN changes.
4
debugging.
5
4
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
5
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
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
Message-id: 20220120122050.41546-16-zhiwei_liu@c-sky.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
10
---
11
target/riscv/cpu_helper.c | 12 ++++++++++++
11
target/riscv/cpu.h | 1 +
12
1 file changed, 12 insertions(+)
12
target/riscv/cpu_helper.c | 3 +--
13
target/riscv/csr.c | 13 ++++++++++++-
14
target/riscv/machine.c | 5 +++--
15
target/riscv/vector_helper.c | 3 ++-
16
5 files changed, 19 insertions(+), 6 deletions(-)
13
17
18
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/cpu.h
21
+++ b/target/riscv/cpu.h
22
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
23
target_ulong vl;
24
target_ulong vstart;
25
target_ulong vtype;
26
+ bool vill;
27
28
target_ulong pc;
29
target_ulong load_res;
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
30
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu_helper.c
32
--- a/target/riscv/cpu_helper.c
17
+++ b/target/riscv/cpu_helper.c
33
+++ b/target/riscv/cpu_helper.c
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
34
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
19
if (ret == TRANSLATE_SUCCESS) {
35
uint32_t maxsz = vlmax << sew;
20
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
36
bool vl_eq_vlmax = (env->vstart == 0) && (vlmax == env->vl) &&
21
size, access_type, mode);
37
(maxsz >= 8);
22
+
38
- flags = FIELD_DP32(flags, TB_FLAGS, VILL,
23
+ qemu_log_mask(CPU_LOG_MMU,
39
- FIELD_EX64(env->vtype, VTYPE, VILL));
24
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
40
+ flags = FIELD_DP32(flags, TB_FLAGS, VILL, env->vill);
25
+ " %d tlb_size " TARGET_FMT_lu "\n",
41
flags = FIELD_DP32(flags, TB_FLAGS, SEW, sew);
26
+ __func__, pa, ret, prot_pmp, tlb_size);
42
flags = FIELD_DP32(flags, TB_FLAGS, LMUL,
27
+
43
FIELD_EX64(env->vtype, VTYPE, VLMUL));
28
prot &= prot_pmp;
44
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
29
}
45
index XXXXXXX..XXXXXXX 100644
30
46
--- a/target/riscv/csr.c
31
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
47
+++ b/target/riscv/csr.c
32
if (ret == TRANSLATE_SUCCESS) {
48
@@ -XXX,XX +XXX,XX @@ static RISCVException write_fcsr(CPURISCVState *env, int csrno,
33
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
49
static RISCVException read_vtype(CPURISCVState *env, int csrno,
34
size, access_type, mode);
50
target_ulong *val)
35
+
51
{
36
+ qemu_log_mask(CPU_LOG_MMU,
52
- *val = env->vtype;
37
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
53
+ uint64_t vill;
38
+ " %d tlb_size " TARGET_FMT_lu "\n",
54
+ switch (env->xl) {
39
+ __func__, pa, ret, prot_pmp, tlb_size);
55
+ case MXL_RV32:
40
+
56
+ vill = (uint32_t)env->vill << 31;
41
prot &= prot_pmp;
57
+ break;
58
+ case MXL_RV64:
59
+ vill = (uint64_t)env->vill << 63;
60
+ break;
61
+ default:
62
+ g_assert_not_reached();
63
+ }
64
+ *val = (target_ulong)vill | env->vtype;
65
return RISCV_EXCP_NONE;
66
}
67
68
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/target/riscv/machine.c
71
+++ b/target/riscv/machine.c
72
@@ -XXX,XX +XXX,XX @@ static bool vector_needed(void *opaque)
73
74
static const VMStateDescription vmstate_vector = {
75
.name = "cpu/vector",
76
- .version_id = 1,
77
- .minimum_version_id = 1,
78
+ .version_id = 2,
79
+ .minimum_version_id = 2,
80
.needed = vector_needed,
81
.fields = (VMStateField[]) {
82
VMSTATE_UINT64_ARRAY(env.vreg, RISCVCPU, 32 * RV_VLEN_MAX / 64),
83
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_vector = {
84
VMSTATE_UINTTL(env.vl, RISCVCPU),
85
VMSTATE_UINTTL(env.vstart, RISCVCPU),
86
VMSTATE_UINTTL(env.vtype, RISCVCPU),
87
+ VMSTATE_BOOL(env.vill, RISCVCPU),
88
VMSTATE_END_OF_LIST()
42
}
89
}
43
}
90
};
91
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
92
index XXXXXXX..XXXXXXX 100644
93
--- a/target/riscv/vector_helper.c
94
+++ b/target/riscv/vector_helper.c
95
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
96
|| (ediv != 0)
97
|| (reserved != 0)) {
98
/* only set vill bit. */
99
- env->vtype = FIELD_DP64(0, VTYPE, VILL, 1);
100
+ env->vill = 1;
101
+ env->vtype = 0;
102
env->vl = 0;
103
env->vstart = 0;
104
return 0;
44
--
105
--
45
2.30.1
106
2.31.1
46
107
47
108
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20220120122050.41546-17-zhiwei_liu@c-sky.com
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
9
target/riscv/cpu.h | 5 +++++
10
target/riscv/vector_helper.c | 7 +++++--
11
2 files changed, 10 insertions(+), 2 deletions(-)
12
13
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu.h
16
+++ b/target/riscv/cpu.h
17
@@ -XXX,XX +XXX,XX @@ static inline RISCVMXL cpu_recompute_xl(CPURISCVState *env)
18
}
19
#endif
20
21
+static inline int riscv_cpu_xlen(CPURISCVState *env)
22
+{
23
+ return 16 << env->xl;
24
+}
25
+
26
/*
27
* Encode LMUL to lmul as follows:
28
* LMUL vlmul lmul
29
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/vector_helper.c
32
+++ b/target/riscv/vector_helper.c
33
@@ -XXX,XX +XXX,XX @@ target_ulong HELPER(vsetvl)(CPURISCVState *env, target_ulong s1,
34
uint64_t lmul = FIELD_EX64(s2, VTYPE, VLMUL);
35
uint16_t sew = 8 << FIELD_EX64(s2, VTYPE, VSEW);
36
uint8_t ediv = FIELD_EX64(s2, VTYPE, VEDIV);
37
- bool vill = FIELD_EX64(s2, VTYPE, VILL);
38
- target_ulong reserved = FIELD_EX64(s2, VTYPE, RESERVED);
39
+ int xlen = riscv_cpu_xlen(env);
40
+ bool vill = (s2 >> (xlen - 1)) & 0x1;
41
+ target_ulong reserved = s2 &
42
+ MAKE_64BIT_MASK(R_VTYPE_RESERVED_SHIFT,
43
+ xlen - 1 - R_VTYPE_RESERVED_SHIFT);
44
45
if (lmul & 4) {
46
/* Fractional LMUL. */
47
--
48
2.31.1
49
50
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
Acked-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-id: 20220120122050.41546-18-zhiwei_liu@c-sky.com
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
9
target/riscv/cpu.h | 1 -
10
1 file changed, 1 deletion(-)
11
12
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/riscv/cpu.h
15
+++ b/target/riscv/cpu.h
16
@@ -XXX,XX +XXX,XX @@ FIELD(VTYPE, VTA, 6, 1)
17
FIELD(VTYPE, VMA, 7, 1)
18
FIELD(VTYPE, VEDIV, 8, 2)
19
FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
20
-FIELD(VTYPE, VILL, sizeof(target_ulong) * 8 - 1, 1)
21
22
struct CPURISCVState {
23
target_ulong gpr[32];
24
--
25
2.31.1
26
27
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
Only check the range that has passed the address translation.
4
5
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20220120122050.41546-19-zhiwei_liu@c-sky.com
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/vector_helper.c | 4 ++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
13
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/vector_helper.c
17
+++ b/target/riscv/vector_helper.c
18
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
19
cpu_mmu_index(env, false));
20
if (host) {
21
#ifdef CONFIG_USER_ONLY
22
- if (page_check_range(addr, nf << esz, PAGE_READ) < 0) {
23
+ if (page_check_range(addr, offset, PAGE_READ) < 0) {
24
vl = i;
25
goto ProbeSuccess;
26
}
27
#else
28
- probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
29
+ probe_pages(env, addr, offset, ra, MMU_DATA_LOAD);
30
#endif
31
} else {
32
vl = i;
33
--
34
2.31.1
35
36
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
Provides fw_cfg for the virt machine on riscv. This enables
3
The mask comes from the pointer masking extension, or the max value
4
using e.g. ramfb later.
4
corresponding to XLEN bits.
5
5
6
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
6
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20210318235041.17175-2-ashe@kivikakk.ee
9
Message-id: 20220120122050.41546-20-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
include/hw/riscv/virt.h | 2 ++
12
target/riscv/vector_helper.c | 25 +++++++++++++++----------
13
hw/riscv/virt.c | 30 ++++++++++++++++++++++++++++++
13
1 file changed, 15 insertions(+), 10 deletions(-)
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/vector_helper.c b/target/riscv/vector_helper.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/virt.h
17
--- a/target/riscv/vector_helper.c
20
+++ b/include/hw/riscv/virt.h
18
+++ b/target/riscv/vector_helper.c
21
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
19
@@ -XXX,XX +XXX,XX @@ static inline uint32_t vext_max_elems(uint32_t desc, uint32_t esz)
22
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
20
return scale < 0 ? vlenb >> -scale : vlenb << scale;
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 inline target_ulong adjust_addr(CPURISCVState *env, target_ulong addr)
54
+{
24
+{
55
+ hwaddr base = virt_memmap[VIRT_FW_CFG].base;
25
+ return (addr & env->cur_pmmask) | env->cur_pmbase;
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
/*
76
{
29
* This function checks watchpoint before real load operation.
77
const MemMapEntry *memmap = virt_memmap;
30
*
78
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
31
@@ -XXX,XX +XXX,XX @@ static void probe_pages(CPURISCVState *env, target_ulong addr,
79
start_addr = virt_memmap[VIRT_FLASH].base;
32
target_ulong pagelen = -(addr | TARGET_PAGE_MASK);
33
target_ulong curlen = MIN(pagelen, len);
34
35
- probe_access(env, addr, curlen, access_type,
36
+ probe_access(env, adjust_addr(env, addr), curlen, access_type,
37
cpu_mmu_index(env, false), ra);
38
if (len > curlen) {
39
addr += curlen;
40
curlen = len - curlen;
41
- probe_access(env, addr, curlen, access_type,
42
+ probe_access(env, adjust_addr(env, addr), curlen, access_type,
43
cpu_mmu_index(env, false), ra);
80
}
44
}
81
45
}
82
+ /*
46
@@ -XXX,XX +XXX,XX @@ vext_ldst_stride(void *vd, void *v0, target_ulong base,
83
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
47
k = 0;
84
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
48
while (k < nf) {
85
+ */
49
target_ulong addr = base + stride * i + (k << esz);
86
+ s->fw_cfg = create_fw_cfg(machine);
50
- ldst_elem(env, addr, i + k * max_elems, vd, ra);
87
+ rom_set_fw(s->fw_cfg);
51
+ ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
88
+
52
k++;
89
/* Compute the fdt load address in dram */
53
}
90
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
54
}
91
machine->ram_size, machine->fdt);
55
@@ -XXX,XX +XXX,XX @@ vext_ldst_us(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
56
k = 0;
93
index XXXXXXX..XXXXXXX 100644
57
while (k < nf) {
94
--- a/hw/riscv/Kconfig
58
target_ulong addr = base + ((i * nf + k) << esz);
95
+++ b/hw/riscv/Kconfig
59
- ldst_elem(env, addr, i + k * max_elems, vd, ra);
96
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
60
+ ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
97
select SIFIVE_PLIC
61
k++;
98
select SIFIVE_TEST
62
}
99
select VIRTIO_MMIO
63
}
100
+ select FW_CFG_DMA
64
@@ -XXX,XX +XXX,XX @@ vext_ldst_index(void *vd, void *v0, target_ulong base,
101
65
k = 0;
102
config SIFIVE_E
66
while (k < nf) {
103
bool
67
abi_ptr addr = get_index_addr(base, i, vs2) + (k << esz);
68
- ldst_elem(env, addr, i + k * max_elems, vd, ra);
69
+ ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
70
k++;
71
}
72
}
73
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
74
if (!vm && !vext_elem_mask(v0, i)) {
75
continue;
76
}
77
- addr = base + i * (nf << esz);
78
+ addr = adjust_addr(env, base + i * (nf << esz));
79
if (i == 0) {
80
probe_pages(env, addr, nf << esz, ra, MMU_DATA_LOAD);
81
} else {
82
@@ -XXX,XX +XXX,XX @@ vext_ldff(void *vd, void *v0, target_ulong base,
83
break;
84
}
85
remain -= offset;
86
- addr += offset;
87
+ addr = adjust_addr(env, addr + offset);
88
}
89
}
90
}
91
@@ -XXX,XX +XXX,XX @@ ProbeSuccess:
92
}
93
while (k < nf) {
94
target_ulong addr = base + ((i * nf + k) << esz);
95
- ldst_elem(env, addr, i + k * max_elems, vd, ra);
96
+ ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
97
k++;
98
}
99
}
100
@@ -XXX,XX +XXX,XX @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
101
/* load/store rest of elements of current segment pointed by vstart */
102
for (pos = off; pos < max_elems; pos++, env->vstart++) {
103
target_ulong addr = base + ((pos + k * max_elems) << esz);
104
- ldst_elem(env, addr, pos + k * max_elems, vd, ra);
105
+ ldst_elem(env, adjust_addr(env, addr), pos + k * max_elems, vd, ra);
106
}
107
k++;
108
}
109
@@ -XXX,XX +XXX,XX @@ vext_ldst_whole(void *vd, target_ulong base, CPURISCVState *env, uint32_t desc,
110
for (; k < nf; k++) {
111
for (i = 0; i < max_elems; i++, env->vstart++) {
112
target_ulong addr = base + ((i + k * max_elems) << esz);
113
- ldst_elem(env, addr, i + k * max_elems, vd, ra);
114
+ ldst_elem(env, adjust_addr(env, addr), i + k * max_elems, vd, ra);
115
}
116
}
117
104
--
118
--
105
2.30.1
119
2.31.1
106
120
107
121
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
1
2
3
When sew <= 32bits, not need to extend scalar reg.
4
When sew > 32bits, if xlen is less that sew, we should sign extend
5
the scalar register, except explicitly specified by the spec.
6
7
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20220120122050.41546-21-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/insn_trans/trans_rvv.c.inc | 2 +-
13
1 file changed, 1 insertion(+), 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 opivx_trans(uint32_t vd, uint32_t rs1, uint32_t vs2, uint32_t vm,
20
dest = tcg_temp_new_ptr();
21
mask = tcg_temp_new_ptr();
22
src2 = tcg_temp_new_ptr();
23
- src1 = get_gpr(s, rs1, EXT_NONE);
24
+ src1 = get_gpr(s, rs1, EXT_SIGN);
25
26
data = FIELD_DP32(data, VDATA, VM, vm);
27
data = FIELD_DP32(data, VDATA, LMUL, s->lmul);
28
--
29
2.31.1
30
31
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
Since HSS commit c20a89f8dcac, the Icicle Kit reference design has
3
When swap regs for hypervisor, the value of vsstatus or mstatus_hs
4
been updated to use a register mapped at 0x4f000000 instead of a
4
should have the right XLEN. Otherwise, it will propagate to mstatus.
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
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
12
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20210322075248.136255-1-bmeng.cn@gmail.com
8
Message-id: 20220120122050.41546-22-zhiwei_liu@c-sky.com
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
10
---
18
include/hw/riscv/microchip_pfsoc.h | 1 +
11
target/riscv/cpu.c | 10 ++++++++++
19
hw/riscv/microchip_pfsoc.c | 6 ++++++
12
1 file changed, 10 insertions(+)
20
2 files changed, 7 insertions(+)
21
13
22
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
14
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/microchip_pfsoc.h
16
--- a/target/riscv/cpu.c
25
+++ b/include/hw/riscv/microchip_pfsoc.h
17
+++ b/target/riscv/cpu.c
26
@@ -XXX,XX +XXX,XX @@ enum {
18
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
27
MICROCHIP_PFSOC_ENVM_DATA,
19
*/
28
MICROCHIP_PFSOC_QSPI_XIP,
20
env->mstatus = set_field(env->mstatus, MSTATUS64_SXL, env->misa_mxl);
29
MICROCHIP_PFSOC_IOSCB,
21
env->mstatus = set_field(env->mstatus, MSTATUS64_UXL, env->misa_mxl);
30
+ MICROCHIP_PFSOC_EMMC_SD_MUX,
22
+ if (riscv_has_ext(env, RVH)) {
31
MICROCHIP_PFSOC_DRAM_LO,
23
+ env->vsstatus = set_field(env->vsstatus,
32
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
24
+ MSTATUS64_SXL, env->misa_mxl);
33
MICROCHIP_PFSOC_DRAM_HI,
25
+ env->vsstatus = set_field(env->vsstatus,
34
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
26
+ MSTATUS64_UXL, env->misa_mxl);
35
index XXXXXXX..XXXXXXX 100644
27
+ env->mstatus_hs = set_field(env->mstatus_hs,
36
--- a/hw/riscv/microchip_pfsoc.c
28
+ MSTATUS64_SXL, env->misa_mxl);
37
+++ b/hw/riscv/microchip_pfsoc.c
29
+ env->mstatus_hs = set_field(env->mstatus_hs,
38
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
30
+ MSTATUS64_UXL, env->misa_mxl);
39
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
31
+ }
40
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
32
}
41
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
33
env->mcause = 0;
42
+ [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
34
env->pc = env->resetvec;
43
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
44
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
45
[MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
46
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
47
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
48
memmap[MICROCHIP_PFSOC_IOSCB].base);
49
50
+ /* eMMC/SD mux */
51
+ create_unimplemented_device("microchip.pfsoc.emmc_sd_mux",
52
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].base,
53
+ memmap[MICROCHIP_PFSOC_EMMC_SD_MUX].size);
54
+
55
/* QSPI Flash */
56
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
57
"microchip.pfsoc.qspi_xip",
58
--
35
--
59
2.30.1
36
2.31.1
60
37
61
38
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20210311094902.1377593-1-georg.kotheimer@kernkonzept.com
6
Message-id: 20220120122050.41546-23-zhiwei_liu@c-sky.com
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
---
8
target/riscv/csr.c | 7 ++++---
9
target/riscv/cpu_bits.h | 3 +++
9
1 file changed, 4 insertions(+), 3 deletions(-)
10
target/riscv/csr.c | 28 ++++++++++++++++++++++------
11
2 files changed, 25 insertions(+), 6 deletions(-)
10
12
13
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/riscv/cpu_bits.h
16
+++ b/target/riscv/cpu_bits.h
17
@@ -XXX,XX +XXX,XX @@ typedef enum {
18
#define COUNTEREN_IR (1 << 2)
19
#define COUNTEREN_HPM3 (1 << 3)
20
21
+/* vsstatus CSR bits */
22
+#define VSSTATUS64_UXL 0x0000000300000000ULL
23
+
24
/* Privilege modes */
25
#define PRV_U 0
26
#define PRV_S 1
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
27
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
12
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/csr.c
29
--- a/target/riscv/csr.c
14
+++ b/target/riscv/csr.c
30
+++ b/target/riscv/csr.c
15
@@ -XXX,XX +XXX,XX @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
31
@@ -XXX,XX +XXX,XX @@ static const target_ulong vs_delegable_excps = DELEGABLE_EXCPS &
32
(1ULL << (RISCV_EXCP_STORE_GUEST_AMO_ACCESS_FAULT)));
33
static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
16
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
34
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
17
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
35
- SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS | (target_ulong)SSTATUS64_UXL;
36
+ SSTATUS_SUM | SSTATUS_MXR | SSTATUS_VS;
18
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
37
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
19
-static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
38
static const target_ulong hip_writable_mask = MIP_VSSIP;
20
+static const target_ulong hip_writable_mask = MIP_VSSIP;
39
static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
21
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
40
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
22
static const target_ulong vsip_writable_mask = MIP_VSSIP;
23
24
static const char valid_vm_1_10_32[16] = {
25
@@ -XXX,XX +XXX,XX @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
26
target_ulong new_value, target_ulong write_mask)
27
{
41
{
28
int ret = rmw_mip(env, 0, ret_value, new_value,
42
uint64_t mstatus = env->mstatus;
29
- write_mask & hip_writable_mask);
43
uint64_t mask = 0;
30
+ write_mask & hvip_writable_mask);
44
+ RISCVMXL xl = riscv_cpu_mxl(env);
31
45
32
- *ret_value &= hip_writable_mask;
46
/* flush tlb on mstatus fields that affect VM */
33
+ *ret_value &= hvip_writable_mask;
47
if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV |
34
48
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
35
return ret;
49
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
50
MSTATUS_TW | MSTATUS_VS;
51
52
- if (riscv_cpu_mxl(env) != MXL_RV32) {
53
+ if (xl != MXL_RV32) {
54
/*
55
* RV32: MPV and GVA are not in mstatus. The current plan is to
56
* add them to mstatush. For now, we just don't support it.
57
*/
58
mask |= MSTATUS_MPV | MSTATUS_GVA;
59
+ if ((val & MSTATUS64_UXL) != 0) {
60
+ mask |= MSTATUS64_UXL;
61
+ }
62
}
63
64
mstatus = (mstatus & ~mask) | (val & mask);
65
66
- RISCVMXL xl = riscv_cpu_mxl(env);
67
if (xl > MXL_RV32) {
68
- /* SXL and UXL fields are for now read only */
69
+ /* SXL field is for now read only */
70
mstatus = set_field(mstatus, MSTATUS64_SXL, xl);
71
- mstatus = set_field(mstatus, MSTATUS64_UXL, xl);
72
}
73
env->mstatus = mstatus;
74
env->xl = cpu_recompute_xl(env);
75
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
76
{
77
uint64_t mask = sstatus_v1_10_mask;
78
uint64_t sstatus = env->mstatus & mask;
79
+ if (env->xl != MXL_RV32) {
80
+ mask |= SSTATUS64_UXL;
81
+ }
82
83
*val = int128_make128(sstatus, add_status_sd(MXL_RV128, sstatus));
84
return RISCV_EXCP_NONE;
85
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
86
target_ulong *val)
87
{
88
target_ulong mask = (sstatus_v1_10_mask);
89
-
90
+ if (env->xl != MXL_RV32) {
91
+ mask |= SSTATUS64_UXL;
92
+ }
93
/* TODO: Use SXL not MXL. */
94
*val = add_status_sd(riscv_cpu_mxl(env), env->mstatus & mask);
95
return RISCV_EXCP_NONE;
96
@@ -XXX,XX +XXX,XX @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
97
target_ulong val)
98
{
99
target_ulong mask = (sstatus_v1_10_mask);
100
+
101
+ if (env->xl != MXL_RV32) {
102
+ if ((val & SSTATUS64_UXL) != 0) {
103
+ mask |= SSTATUS64_UXL;
104
+ }
105
+ }
106
target_ulong newval = (env->mstatus & ~mask) | (val & mask);
107
return write_mstatus(env, CSR_MSTATUS, newval);
108
}
109
@@ -XXX,XX +XXX,XX @@ static RISCVException write_vsstatus(CPURISCVState *env, int csrno,
110
target_ulong val)
111
{
112
uint64_t mask = (target_ulong)-1;
113
+ if ((val & VSSTATUS64_UXL) == 0) {
114
+ mask &= ~VSSTATUS64_UXL;
115
+ }
116
env->vsstatus = (env->vsstatus & ~mask) | (uint64_t)val;
117
return RISCV_EXCP_NONE;
36
}
118
}
37
--
119
--
38
2.30.1
120
2.31.1
39
121
40
122
diff view generated by jsdifflib
1
From: Alexander Wagner <alexander.wagner@ulal.de>
1
From: LIU Zhiwei <zhiwei_liu@c-sky.com>
2
2
3
Not disabling the UART leads to QEMU overwriting the UART receive buffer with
3
Signed-off-by: LIU Zhiwei <zhiwei_liu@c-sky.com>
4
the newest received byte. The rx_level variable is added to allow the use of
5
the existing OpenTitan driver libraries.
6
7
Signed-off-by: Alexander Wagner <alexander.wagner@ulal.de>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210309152130.13038-1-alexander.wagner@ulal.de
5
Message-id: 20220120122050.41546-24-zhiwei_liu@c-sky.com
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
7
---
12
include/hw/char/ibex_uart.h | 4 ++++
8
target/riscv/csr.c | 8 ++++----
13
hw/char/ibex_uart.c | 23 ++++++++++++++++++-----
9
1 file changed, 4 insertions(+), 4 deletions(-)
14
2 files changed, 22 insertions(+), 5 deletions(-)
15
10
16
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/char/ibex_uart.h
13
--- a/target/riscv/csr.c
19
+++ b/include/hw/char/ibex_uart.h
14
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ REG32(FIFO_CTRL, 0x1c)
15
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno,
21
FIELD(FIFO_CTRL, RXILVL, 2, 3)
16
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
22
FIELD(FIFO_CTRL, TXILVL, 5, 2)
17
MSTATUS_TW | MSTATUS_VS;
23
REG32(FIFO_STATUS, 0x20)
18
24
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
19
- if (xl != MXL_RV32) {
25
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
20
+ if (xl != MXL_RV32 || env->debugger) {
26
REG32(OVRD, 0x24)
21
/*
27
REG32(VAL, 0x28)
22
* RV32: MPV and GVA are not in mstatus. The current plan is to
28
REG32(TIMEOUT_CTRL, 0x2c)
23
* add them to mstatush. For now, we just don't support it.
29
@@ -XXX,XX +XXX,XX @@ struct IbexUartState {
24
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus_i128(CPURISCVState *env, int csrno,
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
{
25
{
44
IbexUartState *s = opaque;
26
uint64_t mask = sstatus_v1_10_mask;
45
27
uint64_t sstatus = env->mstatus & mask;
46
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
28
- if (env->xl != MXL_RV32) {
47
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
29
+ if (env->xl != MXL_RV32 || env->debugger) {
48
+ && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
30
mask |= SSTATUS64_UXL;
49
return 1;
50
}
31
}
51
32
52
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_receive(void *opaque, const uint8_t *buf, int size)
33
@@ -XXX,XX +XXX,XX @@ static RISCVException read_sstatus(CPURISCVState *env, int csrno,
53
34
target_ulong *val)
54
s->uart_status &= ~R_STATUS_RXIDLE_MASK;
35
{
55
s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
36
target_ulong mask = (sstatus_v1_10_mask);
56
+ /* The RXFULL is set after receiving a single byte
37
- if (env->xl != MXL_RV32) {
57
+ * as the FIFO buffers are not yet implemented.
38
+ if (env->xl != MXL_RV32 || env->debugger) {
58
+ */
39
mask |= SSTATUS64_UXL;
59
+ s->uart_status |= R_STATUS_RXFULL_MASK;
40
}
60
+ s->rx_level += 1;
41
/* TODO: Use SXL not MXL. */
61
42
@@ -XXX,XX +XXX,XX @@ static RISCVException write_sstatus(CPURISCVState *env, int csrno,
62
if (size > rx_fifo_level) {
43
{
63
s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
44
target_ulong mask = (sstatus_v1_10_mask);
64
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
45
65
s->uart_timeout_ctrl = 0x00000000;
46
- if (env->xl != MXL_RV32) {
66
47
+ if (env->xl != MXL_RV32 || env->debugger) {
67
s->tx_level = 0;
48
if ((val & SSTATUS64_UXL) != 0) {
68
+ s->rx_level = 0;
49
mask |= SSTATUS64_UXL;
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
}
50
}
109
--
51
--
110
2.30.1
52
2.31.1
111
53
112
54
diff view generated by jsdifflib