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 99d6b11b5b44d7dd64f4cb1973184e40a4a174f8:
4
5
Merge tag 'pull-target-arm-20220922' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2022-09-26 13:38:26 -0400)
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
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20220927
8
10
9
for you to fetch changes up to 9a27f69bd668d9d71674407badc412ce1231c7d5:
11
for you to fetch changes up to a3ab69f9f6c000481c439923d16416b8941d5b37:
10
12
11
target/riscv: Prevent lost illegal instruction exceptions (2021-03-22 21:54:40 -0400)
13
target/riscv: rvv-1.0: vf[w]redsum distinguish between ordered/unordered (2022-09-27 11:23:57 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
RISC-V PR for 6.0
16
Second RISC-V PR for QEMU 7.2
15
17
16
This PR includes:
18
* Fixup typos and register addresses for Ibex SPI
17
- Fix for vector CSR access
19
* Cleanup the RISC-V virt machine documentation
18
- Improvements to the Ibex UART device
20
* Remove the sideleg and sedeleg CSR macros
19
- PMP improvements and bug fixes
21
* Fix the CSR check for cycle{h}, instret{h}, time{h}, hpmcounter3-31{h}
20
- Hypervisor extension bug fixes
22
* Remove fixed numbering from GDB xml feature files
21
- ramfb support for the virt machine
23
* Allow setting the resetvec for the OpenTitan machine
22
- Fast read support for SST flash
24
* Check the correct exception cause in vector GDB stub
23
- Improvements to the microchip_pfsoc machine
25
* Fix inheritance of SiFiveEState
26
* Improvements to the RISC-V debugger spec
27
* Simplify some vector code
24
28
25
----------------------------------------------------------------
29
----------------------------------------------------------------
26
Alexander Wagner (1):
30
Alex Bennée (1):
27
hw/char: disable ibex uart receive if the buffer is full
31
docs/system: clean up code escape for riscv virt platform
28
32
29
Asherah Connor (2):
33
Alistair Francis (3):
30
hw/riscv: Add fw_cfg support to virt
34
target/riscv: Set the CPU resetvec directly
31
hw/riscv: allow ramfb on virt
35
hw/riscv: opentitan: Fixup resetvec
36
hw/riscv: opentitan: Expose the resetvec as a SoC property
32
37
33
Bin Meng (3):
38
Andrew Burgess (2):
34
hw/block: m25p80: Support fast read for SST flashes
39
target/riscv: remove fflags, frm, and fcsr from riscv-*-fpu.xml
35
hw/riscv: microchip_pfsoc: Map EMMC/SD mux register
40
target/riscv: remove fixed numbering from GDB xml feature files
36
docs/system: riscv: Add documentation for 'microchip-icicle-kit' machine
37
41
38
Frank Chang (1):
42
Bernhard Beschow (1):
39
target/riscv: fix vs() to return proper error code
43
hw/riscv/sifive_e: Fix inheritance of SiFiveEState
40
44
41
Georg Kotheimer (6):
45
Frank Chang (9):
42
target/riscv: Adjust privilege level for HLV(X)/HSV instructions
46
target/riscv: Check the correct exception cause in vector GDB stub
43
target/riscv: Make VSTIP and VSEIP read-only in hip
47
target/riscv: debug: Determine the trigger type from tdata1.type
44
target/riscv: Use background registers also for MSTATUS_MPV
48
target/riscv: debug: Introduce build_tdata1() to build tdata1 register content
45
target/riscv: Fix read and write accesses to vsip and vsie
49
target/riscv: debug: Introduce tdata1, tdata2, and tdata3 CSRs
46
target/riscv: Add proper two-stage lookup exception detection
50
target/riscv: debug: Restrict the range of tselect value can be written
47
target/riscv: Prevent lost illegal instruction exceptions
51
target/riscv: debug: Introduce tinfo CSR
52
target/riscv: debug: Create common trigger actions function
53
target/riscv: debug: Check VU/VS modes for type 2 trigger
54
target/riscv: debug: Add initial support of type 6 trigger
48
55
49
Jim Shu (3):
56
Rahul Pathak (1):
50
target/riscv: propagate PMP permission to TLB page
57
target/riscv: Remove sideleg and sedeleg
51
target/riscv: add log of PMP permission checking
52
target/riscv: flush TLB pages if PMP permission has been changed
53
58
54
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++
59
Weiwei Li (1):
55
docs/system/target-riscv.rst | 1 +
60
target/riscv: fix csr check for cycle{h}, instret{h}, time{h}, hpmcounter3-31{h}
56
include/hw/char/ibex_uart.h | 4 +
57
include/hw/riscv/microchip_pfsoc.h | 1 +
58
include/hw/riscv/virt.h | 2 +
59
target/riscv/cpu.h | 4 +
60
target/riscv/pmp.h | 4 +-
61
hw/block/m25p80.c | 3 +
62
hw/char/ibex_uart.c | 23 +++-
63
hw/riscv/microchip_pfsoc.c | 6 +
64
hw/riscv/virt.c | 33 ++++++
65
target/riscv/cpu.c | 1 +
66
target/riscv/cpu_helper.c | 144 +++++++++++++++--------
67
target/riscv/csr.c | 77 +++++++------
68
target/riscv/pmp.c | 84 ++++++++++----
69
target/riscv/translate.c | 179 +----------------------------
70
hw/riscv/Kconfig | 1 +
71
17 files changed, 367 insertions(+), 289 deletions(-)
72
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
73
61
62
Wilfred Mallawa (2):
63
hw/ssi: ibex_spi: fixup typos in ibex_spi_host
64
hw/ssi: ibex_spi: update reg addr
65
66
Yang Liu (2):
67
target/riscv: rvv-1.0: Simplify vfwredsum code
68
target/riscv: rvv-1.0: vf[w]redsum distinguish between ordered/unordered
69
70
docs/system/riscv/virt.rst | 13 +-
71
include/hw/riscv/opentitan.h | 2 +
72
include/hw/riscv/sifive_e.h | 3 +-
73
target/riscv/cpu.h | 9 +-
74
target/riscv/cpu_bits.h | 3 +-
75
target/riscv/debug.h | 55 ++--
76
target/riscv/helper.h | 15 +-
77
target/riscv/insn32.decode | 6 +-
78
disas/riscv.c | 2 -
79
hw/riscv/opentitan.c | 8 +-
80
hw/ssi/ibex_spi_host.c | 8 +-
81
target/riscv/cpu.c | 13 +-
82
target/riscv/csr.c | 23 +-
83
target/riscv/debug.c | 484 +++++++++++++++++++++++++-------
84
target/riscv/gdbstub.c | 36 +--
85
target/riscv/machine.c | 26 +-
86
target/riscv/vector_helper.c | 69 ++---
87
target/riscv/insn_trans/trans_rvv.c.inc | 6 +-
88
gdb-xml/riscv-32bit-cpu.xml | 6 +-
89
gdb-xml/riscv-32bit-fpu.xml | 10 +-
90
gdb-xml/riscv-64bit-cpu.xml | 6 +-
91
gdb-xml/riscv-64bit-fpu.xml | 10 +-
92
22 files changed, 531 insertions(+), 282 deletions(-)
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
This patch fixes up minor typos in ibex_spi_host
4
5
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
8
Message-Id: <20220823061201.132342-2-wilfred.mallawa@opensource.wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
hw/ssi/ibex_spi_host.c | 6 +++---
12
1 file changed, 3 insertions(+), 3 deletions(-)
13
14
diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/ibex_spi_host.c
17
+++ b/hw/ssi/ibex_spi_host.c
18
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_irq(IbexSPIHostState *s)
19
& R_INTR_STATE_SPI_EVENT_MASK;
20
int err_irq = 0, event_irq = 0;
21
22
- /* Error IRQ enabled and Error IRQ Cleared*/
23
+ /* Error IRQ enabled and Error IRQ Cleared */
24
if (error_en && !err_pending) {
25
/* Event enabled, Interrupt Test Error */
26
if (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_ERROR_MASK) {
27
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
28
case IBEX_SPI_HOST_TXDATA:
29
/*
30
* This is a hardware `feature` where
31
- * the first word written TXDATA after init is omitted entirely
32
+ * the first word written to TXDATA after init is omitted entirely
33
*/
34
if (s->init_status) {
35
s->init_status = false;
36
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
37
break;
38
case IBEX_SPI_HOST_ERROR_STATUS:
39
/*
40
- * Indicates that any errors that have occurred.
41
+ * Indicates any errors that have occurred.
42
* When an error occurs, the corresponding bit must be cleared
43
* here before issuing any further commands
44
*/
45
--
46
2.37.3
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
Updates the `EVENT_ENABLE` register to offset `0x34` as per
4
OpenTitan spec [1].
5
6
[1] https://docs.opentitan.org/hw/ip/spi_host/doc/#Reg_event_enable
7
8
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20220823061201.132342-5-wilfred.mallawa@opensource.wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/ssi/ibex_spi_host.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/ibex_spi_host.c
19
+++ b/hw/ssi/ibex_spi_host.c
20
@@ -XXX,XX +XXX,XX @@ REG32(ERROR_STATUS, 0x30)
21
FIELD(ERROR_STATUS, CMDINVAL, 3, 1)
22
FIELD(ERROR_STATUS, CSIDINVAL, 4, 1)
23
FIELD(ERROR_STATUS, ACCESSINVAL, 5, 1)
24
-REG32(EVENT_ENABLE, 0x30)
25
+REG32(EVENT_ENABLE, 0x34)
26
FIELD(EVENT_ENABLE, RXFULL, 0, 1)
27
FIELD(EVENT_ENABLE, TXEMPTY, 1, 1)
28
FIELD(EVENT_ENABLE, RXWM, 2, 1)
29
--
30
2.37.3
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
This adds the documentation to describe what is supported for the
3
The example code is rendered slightly mangled due to missing code
4
'microchip-icicle-kit' machine, and how to boot the machine in QEMU.
4
block. Properly escape the code block and add shell prompt and qemu to
5
fit in with the other examples on the page.
5
6
6
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-id: 20210322075248.136255-2-bmeng.cn@gmail.com
9
Message-Id: <20220905163939.1599368-1-alex.bennee@linaro.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
---
11
docs/system/riscv/microchip-icicle-kit.rst | 89 ++++++++++++++++++++++
12
docs/system/riscv/virt.rst | 13 +++++++++----
12
docs/system/target-riscv.rst | 1 +
13
1 file changed, 9 insertions(+), 4 deletions(-)
13
2 files changed, 90 insertions(+)
14
create mode 100644 docs/system/riscv/microchip-icicle-kit.rst
15
14
16
diff --git a/docs/system/riscv/microchip-icicle-kit.rst b/docs/system/riscv/microchip-icicle-kit.rst
15
diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst
17
new file mode 100644
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX
17
--- a/docs/system/riscv/virt.rst
19
--- /dev/null
18
+++ b/docs/system/riscv/virt.rst
20
+++ b/docs/system/riscv/microchip-icicle-kit.rst
19
@@ -XXX,XX +XXX,XX @@ Enabling TPM
21
@@ -XXX,XX +XXX,XX @@
20
22
+Microchip PolarFire SoC Icicle Kit (``microchip-icicle-kit``)
21
A TPM device can be connected to the virt board by following the steps below.
23
+=============================================================
22
23
-First launch the TPM emulator
24
+First launch the TPM emulator:
25
26
- swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
27
+.. code-block:: bash
24
+
28
+
25
+Microchip PolarFire SoC Icicle Kit integrates a PolarFire SoC, with one
29
+ $ swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \
26
+SiFive's E51 plus four U54 cores and many on-chip peripherals and an FPGA.
30
--ctrl type=unixio,path=swtpm-sock
27
+
31
28
+For more details about Microchip PolarFire SoC, please see:
32
-Then launch QEMU with:
29
+https://www.microsemi.com/product-directory/soc-fpgas/5498-polarfire-soc-fpga
33
+Then launch QEMU with some additional arguments to link a TPM device to the backend:
30
+
31
+The Icicle Kit board information can be found here:
32
+https://www.microsemi.com/existing-parts/parts/152514
33
+
34
+Supported devices
35
+-----------------
36
+
37
+The ``microchip-icicle-kit`` machine supports the following devices:
38
+
39
+ * 1 E51 core
40
+ * 4 U54 cores
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
+
50
+Boot options
51
+------------
52
+
53
+The ``microchip-icicle-kit`` machine can start using the standard -bios
54
+functionality for loading its BIOS image, aka Hart Software Services (HSS_).
55
+HSS loads the second stage bootloader U-Boot from an SD card. It does not
56
+support direct kernel loading via the -kernel option. One has to load kernel
57
+from U-Boot.
58
+
59
+The memory is set to 1537 MiB by default which is the minimum required high
60
+memory size by HSS. A sanity check on ram size is performed in the machine
61
+init routine to prompt user to increase the RAM size to > 1537 MiB when less
62
+than 1537 MiB ram is detected.
63
+
64
+Boot the machine
65
+----------------
66
+
67
+HSS 2020.12 release is tested at the time of writing. To build an HSS image
68
+that can be booted by the ``microchip-icicle-kit`` machine, type the following
69
+in the HSS source tree:
70
+
34
+
71
+.. code-block:: bash
35
+.. code-block:: bash
72
+
36
73
+ $ export CROSS_COMPILE=riscv64-linux-
37
- ...
74
+ $ cp boards/mpfs-icicle-kit-es/def_config .config
38
+ $ qemu-system-riscv64 \
75
+ $ make BOARD=mpfs-icicle-kit-es
39
+ ... other args .... \
76
+
40
-chardev socket,id=chrtpm,path=swtpm-sock \
77
+Download the official SD card image released by Microchip and prepare it for
41
-tpmdev emulator,id=tpm0,chardev=chrtpm \
78
+QEMU usage:
42
-device tpm-tis-device,tpmdev=tpm0
79
+
80
+.. code-block:: bash
81
+
82
+ $ wget ftp://ftpsoc.microsemi.com/outgoing/core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
83
+ $ gunzip core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic.gz
84
+ $ qemu-img resize core-image-minimal-dev-icicle-kit-es-sd-20201009141623.rootfs.wic 4G
85
+
86
+Then we can boot the machine by:
87
+
88
+.. code-block:: bash
89
+
90
+ $ qemu-system-riscv64 -M microchip-icicle-kit -smp 5 \
91
+ -bios path/to/hss.bin -sd path/to/sdcard.img \
92
+ -nic user,model=cadence_gem \
93
+ -nic tap,ifname=tap,model=cadence_gem,script=no \
94
+ -display none -serial stdio \
95
+ -chardev socket,id=serial1,path=serial1.sock,server=on,wait=on \
96
+ -serial chardev:serial1
97
+
98
+With above command line, current terminal session will be used for the first
99
+serial port. Open another terminal window, and use `minicom` to connect the
100
+second serial port.
101
+
102
+.. code-block:: bash
103
+
104
+ $ minicom -D unix\#serial1.sock
105
+
106
+HSS output is on the first serial port (stdio) and U-Boot outputs on the
107
+second serial port. U-Boot will automatically load the Linux kernel from
108
+the SD card image.
109
+
110
+.. _HSS: https://github.com/polarfire-soc/hart-software-services
111
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
112
index XXXXXXX..XXXXXXX 100644
113
--- a/docs/system/target-riscv.rst
114
+++ b/docs/system/target-riscv.rst
115
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
116
.. toctree::
117
:maxdepth: 1
118
119
+ riscv/microchip-icicle-kit
120
riscv/sifive_u
121
122
RISC-V CPU features
123
--
43
--
124
2.30.1
44
2.37.3
125
126
diff view generated by jsdifflib
New patch
1
From: Rahul Pathak <rpathak@ventanamicro.com>
1
2
3
sideleg and sedeleg csrs are not part of riscv isa spec
4
anymore, these csrs were part of N extension which
5
is removed from the riscv isa specification.
6
7
These commits removed all traces of these csrs from
8
riscv spec (https://github.com/riscv/riscv-isa-manual) -
9
10
commit f8d27f805b65 ("Remove or downgrade more references to N extension (#674)")
11
commit b6cade07034d ("Remove N extension chapter for now")
12
13
Signed-off-by: Rahul Pathak <rpathak@ventanamicro.com>
14
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-Id: <20220824145255.400040-1-rpathak@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
target/riscv/cpu_bits.h | 2 --
20
disas/riscv.c | 2 --
21
2 files changed, 4 deletions(-)
22
23
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/cpu_bits.h
26
+++ b/target/riscv/cpu_bits.h
27
@@ -XXX,XX +XXX,XX @@
28
29
/* Supervisor Trap Setup */
30
#define CSR_SSTATUS 0x100
31
-#define CSR_SEDELEG 0x102
32
-#define CSR_SIDELEG 0x103
33
#define CSR_SIE 0x104
34
#define CSR_STVEC 0x105
35
#define CSR_SCOUNTEREN 0x106
36
diff --git a/disas/riscv.c b/disas/riscv.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/disas/riscv.c
39
+++ b/disas/riscv.c
40
@@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno)
41
case 0x0043: return "utval";
42
case 0x0044: return "uip";
43
case 0x0100: return "sstatus";
44
- case 0x0102: return "sedeleg";
45
- case 0x0103: return "sideleg";
46
case 0x0104: return "sie";
47
case 0x0105: return "stvec";
48
case 0x0106: return "scounteren";
49
--
50
2.37.3
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Weiwei Li <liweiwei@iscas.ac.cn>
2
2
3
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
3
- modify check for mcounteren to work in all less-privilege mode
4
- modify check for scounteren to work only when S mode is enabled
5
- distinguish the exception type raised by check for scounteren between U
6
and VU mode
7
8
Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-id: 20210311094902.1377593-1-georg.kotheimer@kernkonzept.com
11
Message-Id: <20220817083756.12471-1-liweiwei@iscas.ac.cn>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
13
---
8
target/riscv/csr.c | 7 ++++---
14
target/riscv/csr.c | 13 +++++++++----
9
1 file changed, 4 insertions(+), 3 deletions(-)
15
1 file changed, 9 insertions(+), 4 deletions(-)
10
16
11
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/riscv/csr.c
19
--- a/target/riscv/csr.c
14
+++ b/target/riscv/csr.c
20
+++ b/target/riscv/csr.c
15
@@ -XXX,XX +XXX,XX @@ static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE |
21
@@ -XXX,XX +XXX,XX @@ static RISCVException ctr(CPURISCVState *env, int csrno)
16
SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS |
22
17
SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD;
23
skip_ext_pmu_check:
18
static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
24
19
-static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
25
- if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) ||
20
+static const target_ulong hip_writable_mask = MIP_VSSIP;
26
- ((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask)))) {
21
+static const target_ulong hvip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
27
+ if (env->priv < PRV_M && !get_field(env->mcounteren, ctr_mask)) {
22
static const target_ulong vsip_writable_mask = MIP_VSSIP;
28
return RISCV_EXCP_ILLEGAL_INST;
23
29
}
24
static const char valid_vm_1_10_32[16] = {
30
25
@@ -XXX,XX +XXX,XX @@ static int rmw_hvip(CPURISCVState *env, int csrno, target_ulong *ret_value,
31
if (riscv_cpu_virt_enabled(env)) {
26
target_ulong new_value, target_ulong write_mask)
32
- if (!get_field(env->hcounteren, ctr_mask) &&
27
{
33
- get_field(env->mcounteren, ctr_mask)) {
28
int ret = rmw_mip(env, 0, ret_value, new_value,
34
+ if (!get_field(env->hcounteren, ctr_mask) ||
29
- write_mask & hip_writable_mask);
35
+ (env->priv == PRV_U && !get_field(env->scounteren, ctr_mask))) {
30
+ write_mask & hvip_writable_mask);
36
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
31
37
}
32
- *ret_value &= hip_writable_mask;
38
}
33
+ *ret_value &= hvip_writable_mask;
39
+
34
40
+ if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
35
return ret;
41
+ !get_field(env->scounteren, ctr_mask)) {
42
+ return RISCV_EXCP_ILLEGAL_INST;
43
+ }
44
+
45
#endif
46
return RISCV_EXCP_NONE;
36
}
47
}
37
--
48
--
38
2.30.1
49
2.37.3
39
40
diff view generated by jsdifflib
New patch
1
From: Andrew Burgess <aburgess@redhat.com>
1
2
3
While testing some changes to GDB's handling for the RISC-V registers
4
fcsr, fflags, and frm, I spotted that QEMU includes these registers
5
twice in the target description it sends to GDB, once in the fpu
6
feature, and once in the csr feature.
7
8
Right now things basically work OK, QEMU maps these registers onto two
9
different register numbers, e.g. fcsr maps to both 68 and 73, and GDB
10
can use either of these to access the register.
11
12
However, GDB's target descriptions don't really work this way, each
13
register should appear just once in a target description, mapping the
14
register name onto the number GDB should use when accessing the
15
register on the target. Duplicate register names actually result in
16
duplicate registers on the GDB side, however, as the registers have
17
the same name, the user can only access one of these registers.
18
19
Currently GDB has a hack in place, specifically for RISC-V, to spot
20
the duplicate copies of these three registers, and hide them from the
21
user, ensuring the user only ever sees a single copy of each.
22
23
In this commit I propose fixing this issue on the QEMU side, and in
24
the process, simplify the fpu register handling a little.
25
26
I think we should, remove fflags, frm, and fcsr from the two (32-bit
27
and 64-bit) fpu feature xml files. These files will only contain the
28
32 core floating point register f0 to f31. The fflags, frm, and fcsr
29
registers will continue to be advertised in the csr feature as they
30
currently are.
31
32
With that change made, I will simplify riscv_gdb_get_fpu and
33
riscv_gdb_set_fpu, removing the extra handling for the 3 status
34
registers.
35
36
Signed-off-by: Andrew Burgess <aburgess@redhat.com>
37
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
38
Message-Id: <0fbf2a5b12e3210ff3867d5cf7022b3f3462c9c8.1661934573.git.aburgess@redhat.com>
39
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
40
---
41
target/riscv/gdbstub.c | 32 ++------------------------------
42
gdb-xml/riscv-32bit-fpu.xml | 4 ----
43
gdb-xml/riscv-64bit-fpu.xml | 4 ----
44
3 files changed, 2 insertions(+), 38 deletions(-)
45
46
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/gdbstub.c
49
+++ b/target/riscv/gdbstub.c
50
@@ -XXX,XX +XXX,XX @@ static int riscv_gdb_get_fpu(CPURISCVState *env, GByteArray *buf, int n)
51
if (env->misa_ext & RVF) {
52
return gdb_get_reg32(buf, env->fpr[n]);
53
}
54
- /* there is hole between ft11 and fflags in fpu.xml */
55
- } else if (n < 36 && n > 32) {
56
- target_ulong val = 0;
57
- int result;
58
- /*
59
- * CSR_FFLAGS is at index 1 in csr_register, and gdb says it is FP
60
- * register 33, so we recalculate the map index.
61
- * This also works for CSR_FRM and CSR_FCSR.
62
- */
63
- result = riscv_csrrw_debug(env, n - 32, &val,
64
- 0, 0);
65
- if (result == RISCV_EXCP_NONE) {
66
- return gdb_get_regl(buf, val);
67
- }
68
}
69
return 0;
70
}
71
@@ -XXX,XX +XXX,XX @@ static int riscv_gdb_set_fpu(CPURISCVState *env, uint8_t *mem_buf, int n)
72
if (n < 32) {
73
env->fpr[n] = ldq_p(mem_buf); /* always 64-bit */
74
return sizeof(uint64_t);
75
- /* there is hole between ft11 and fflags in fpu.xml */
76
- } else if (n < 36 && n > 32) {
77
- target_ulong val = ldtul_p(mem_buf);
78
- int result;
79
- /*
80
- * CSR_FFLAGS is at index 1 in csr_register, and gdb says it is FP
81
- * register 33, so we recalculate the map index.
82
- * This also works for CSR_FRM and CSR_FCSR.
83
- */
84
- result = riscv_csrrw_debug(env, n - 32, NULL,
85
- val, -1);
86
- if (result == RISCV_EXCP_NONE) {
87
- return sizeof(target_ulong);
88
- }
89
}
90
return 0;
91
}
92
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_register_gdb_regs_for_features(CPUState *cs)
93
CPURISCVState *env = &cpu->env;
94
if (env->misa_ext & RVD) {
95
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
96
- 36, "riscv-64bit-fpu.xml", 0);
97
+ 32, "riscv-64bit-fpu.xml", 0);
98
} else if (env->misa_ext & RVF) {
99
gdb_register_coprocessor(cs, riscv_gdb_get_fpu, riscv_gdb_set_fpu,
100
- 36, "riscv-32bit-fpu.xml", 0);
101
+ 32, "riscv-32bit-fpu.xml", 0);
102
}
103
if (env->misa_ext & RVV) {
104
gdb_register_coprocessor(cs, riscv_gdb_get_vector, riscv_gdb_set_vector,
105
diff --git a/gdb-xml/riscv-32bit-fpu.xml b/gdb-xml/riscv-32bit-fpu.xml
106
index XXXXXXX..XXXXXXX 100644
107
--- a/gdb-xml/riscv-32bit-fpu.xml
108
+++ b/gdb-xml/riscv-32bit-fpu.xml
109
@@ -XXX,XX +XXX,XX @@
110
<reg name="ft9" bitsize="32" type="ieee_single"/>
111
<reg name="ft10" bitsize="32" type="ieee_single"/>
112
<reg name="ft11" bitsize="32" type="ieee_single"/>
113
-
114
- <reg name="fflags" bitsize="32" type="int" regnum="66"/>
115
- <reg name="frm" bitsize="32" type="int" regnum="67"/>
116
- <reg name="fcsr" bitsize="32" type="int" regnum="68"/>
117
</feature>
118
diff --git a/gdb-xml/riscv-64bit-fpu.xml b/gdb-xml/riscv-64bit-fpu.xml
119
index XXXXXXX..XXXXXXX 100644
120
--- a/gdb-xml/riscv-64bit-fpu.xml
121
+++ b/gdb-xml/riscv-64bit-fpu.xml
122
@@ -XXX,XX +XXX,XX @@
123
<reg name="ft9" bitsize="64" type="riscv_double"/>
124
<reg name="ft10" bitsize="64" type="riscv_double"/>
125
<reg name="ft11" bitsize="64" type="riscv_double"/>
126
-
127
- <reg name="fflags" bitsize="32" type="int" regnum="66"/>
128
- <reg name="frm" bitsize="32" type="int" regnum="67"/>
129
- <reg name="fcsr" bitsize="32" type="int" regnum="68"/>
130
</feature>
131
--
132
2.37.3
diff view generated by jsdifflib
New patch
1
From: Andrew Burgess <aburgess@redhat.com>
1
2
3
The fixed register numbering in the various GDB feature files for
4
RISC-V only exists because these files were originally copied from the
5
GDB source tree.
6
7
However, the fixed numbering only exists in the GDB source tree so
8
that GDB, when it connects to a target that doesn't provide a target
9
description, will use a specific numbering scheme.
10
11
That numbering scheme is designed to be compatible with the first
12
versions of QEMU (for RISC-V), that didn't send a target description,
13
and relied on a fixed numbering scheme.
14
15
Because of the way that QEMU manages its target descriptions,
16
recording the number of registers in each feature, and just relying on
17
GDB's numbering starting from 0, then I propose that we remove all the
18
fixed numbering from the RISC-V feature xml files, and just rely on
19
the standard numbering scheme. Plenty of other targets manage their
20
xml files this way, e.g. ARM, AArch64, Loongarch, m68k, rx, and s390.
21
22
Signed-off-by: Andrew Burgess <aburgess@redhat.com>
23
Acked-by: Alistair Francis <alistair.francis@wdc.com>
24
Reviewed-by: Palmer Dabbelt <palmer@rivosinc.com>
25
Message-Id: <6069395f90e6fc24dac92197be815fedf42f5974.1661934573.git.aburgess@redhat.com>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
28
gdb-xml/riscv-32bit-cpu.xml | 6 +-----
29
gdb-xml/riscv-32bit-fpu.xml | 6 +-----
30
gdb-xml/riscv-64bit-cpu.xml | 6 +-----
31
gdb-xml/riscv-64bit-fpu.xml | 6 +-----
32
4 files changed, 4 insertions(+), 20 deletions(-)
33
34
diff --git a/gdb-xml/riscv-32bit-cpu.xml b/gdb-xml/riscv-32bit-cpu.xml
35
index XXXXXXX..XXXXXXX 100644
36
--- a/gdb-xml/riscv-32bit-cpu.xml
37
+++ b/gdb-xml/riscv-32bit-cpu.xml
38
@@ -XXX,XX +XXX,XX @@
39
are permitted in any medium without royalty provided the copyright
40
notice and this notice are preserved. -->
41
42
-<!-- Register numbers are hard-coded in order to maintain backward
43
- compatibility with older versions of tools that didn't use xml
44
- register descriptions. -->
45
-
46
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
47
<feature name="org.gnu.gdb.riscv.cpu">
48
- <reg name="zero" bitsize="32" type="int" regnum="0"/>
49
+ <reg name="zero" bitsize="32" type="int"/>
50
<reg name="ra" bitsize="32" type="code_ptr"/>
51
<reg name="sp" bitsize="32" type="data_ptr"/>
52
<reg name="gp" bitsize="32" type="data_ptr"/>
53
diff --git a/gdb-xml/riscv-32bit-fpu.xml b/gdb-xml/riscv-32bit-fpu.xml
54
index XXXXXXX..XXXXXXX 100644
55
--- a/gdb-xml/riscv-32bit-fpu.xml
56
+++ b/gdb-xml/riscv-32bit-fpu.xml
57
@@ -XXX,XX +XXX,XX @@
58
are permitted in any medium without royalty provided the copyright
59
notice and this notice are preserved. -->
60
61
-<!-- Register numbers are hard-coded in order to maintain backward
62
- compatibility with older versions of tools that didn't use xml
63
- register descriptions. -->
64
-
65
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
66
<feature name="org.gnu.gdb.riscv.fpu">
67
- <reg name="ft0" bitsize="32" type="ieee_single" regnum="33"/>
68
+ <reg name="ft0" bitsize="32" type="ieee_single"/>
69
<reg name="ft1" bitsize="32" type="ieee_single"/>
70
<reg name="ft2" bitsize="32" type="ieee_single"/>
71
<reg name="ft3" bitsize="32" type="ieee_single"/>
72
diff --git a/gdb-xml/riscv-64bit-cpu.xml b/gdb-xml/riscv-64bit-cpu.xml
73
index XXXXXXX..XXXXXXX 100644
74
--- a/gdb-xml/riscv-64bit-cpu.xml
75
+++ b/gdb-xml/riscv-64bit-cpu.xml
76
@@ -XXX,XX +XXX,XX @@
77
are permitted in any medium without royalty provided the copyright
78
notice and this notice are preserved. -->
79
80
-<!-- Register numbers are hard-coded in order to maintain backward
81
- compatibility with older versions of tools that didn't use xml
82
- register descriptions. -->
83
-
84
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
85
<feature name="org.gnu.gdb.riscv.cpu">
86
- <reg name="zero" bitsize="64" type="int" regnum="0"/>
87
+ <reg name="zero" bitsize="64" type="int"/>
88
<reg name="ra" bitsize="64" type="code_ptr"/>
89
<reg name="sp" bitsize="64" type="data_ptr"/>
90
<reg name="gp" bitsize="64" type="data_ptr"/>
91
diff --git a/gdb-xml/riscv-64bit-fpu.xml b/gdb-xml/riscv-64bit-fpu.xml
92
index XXXXXXX..XXXXXXX 100644
93
--- a/gdb-xml/riscv-64bit-fpu.xml
94
+++ b/gdb-xml/riscv-64bit-fpu.xml
95
@@ -XXX,XX +XXX,XX @@
96
are permitted in any medium without royalty provided the copyright
97
notice and this notice are preserved. -->
98
99
-<!-- Register numbers are hard-coded in order to maintain backward
100
- compatibility with older versions of tools that didn't use xml
101
- register descriptions. -->
102
-
103
<!DOCTYPE feature SYSTEM "gdb-target.dtd">
104
<feature name="org.gnu.gdb.riscv.fpu">
105
106
@@ -XXX,XX +XXX,XX @@
107
<field name="double" type="ieee_double"/>
108
</union>
109
110
- <reg name="ft0" bitsize="64" type="riscv_double" regnum="33"/>
111
+ <reg name="ft0" bitsize="64" type="riscv_double"/>
112
<reg name="ft1" bitsize="64" type="riscv_double"/>
113
<reg name="ft2" bitsize="64" type="riscv_double"/>
114
<reg name="ft3" bitsize="64" type="riscv_double"/>
115
--
116
2.37.3
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
The current two-stage lookup detection in riscv_cpu_do_interrupt falls
3
Instead of using our properties to set a config value which then might
4
short of its purpose, as all it checks is whether two-stage address
4
be used to set the resetvec (depending on your timing), let's instead
5
translation either via the hypervisor-load store instructions or the
5
just set the resetvec directly in the env struct.
6
MPRV feature would be allowed.
7
6
8
What we really need instead is whether two-stage address translation was
7
This allows us to set the reset vec from the command line with:
9
active when the exception was raised. However, in riscv_cpu_do_interrupt
8
-global driver=riscv.hart_array,property=resetvec,value=0x20000400
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
9
14
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-id: 20210319141459.1196741-1-georg.kotheimer@kernkonzept.com
12
Message-Id: <20220914101108.82571-2-alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
14
---
19
target/riscv/cpu.h | 4 ++++
15
target/riscv/cpu.h | 3 +--
20
target/riscv/cpu.c | 1 +
16
target/riscv/cpu.c | 13 +++----------
21
target/riscv/cpu_helper.c | 21 ++++++++-------------
17
target/riscv/machine.c | 6 +++---
22
3 files changed, 13 insertions(+), 13 deletions(-)
18
3 files changed, 7 insertions(+), 15 deletions(-)
23
19
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
22
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
23
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPURISCVState {
24
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
29
target_ulong satp_hs;
25
/* This contains QEMU specific information about the virt state. */
30
uint64_t mstatus_hs;
26
target_ulong virt;
31
27
target_ulong geilen;
32
+ /* Signals whether the current exception occurred with two-stage address
28
- target_ulong resetvec;
33
+ translation active. */
29
+ uint64_t resetvec;
34
+ bool two_stage_lookup;
30
35
+
31
target_ulong mhartid;
36
target_ulong scounteren;
32
/*
37
target_ulong mcounteren;
33
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
38
34
bool pmp;
35
bool epmp;
36
bool debug;
37
- uint64_t resetvec;
38
39
bool short_isa_string;
40
};
39
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
41
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
40
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/cpu.c
43
--- a/target/riscv/cpu.c
42
+++ b/target/riscv/cpu.c
44
+++ b/target/riscv/cpu.c
43
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev)
45
@@ -XXX,XX +XXX,XX @@ static void set_vext_version(CPURISCVState *env, int vext_ver)
44
env->mstatus &= ~(MSTATUS_MIE | MSTATUS_MPRV);
46
env->vext_ver = vext_ver;
45
env->mcause = 0;
47
}
46
env->pc = env->resetvec;
48
47
+ env->two_stage_lookup = false;
49
-static void set_resetvec(CPURISCVState *env, target_ulong resetvec)
50
-{
51
-#ifndef CONFIG_USER_ONLY
52
- env->resetvec = resetvec;
53
-#endif
54
-}
55
-
56
static void riscv_any_cpu_init(Object *obj)
57
{
58
CPURISCVState *env = &RISCV_CPU(obj)->env;
59
@@ -XXX,XX +XXX,XX @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
60
61
set_misa(env, MXL_RV32, RVI | RVM | RVA | RVF | RVC | RVU);
62
set_priv_version(env, PRIV_VERSION_1_10_0);
63
- set_resetvec(env, DEFAULT_RSTVEC);
64
cpu->cfg.mmu = false;
65
}
48
#endif
66
#endif
49
cs->exception_index = EXCP_NONE;
67
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
50
env->load_res = -1;
68
riscv_set_feature(env, RISCV_FEATURE_DEBUG);
51
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
69
}
70
71
- set_resetvec(env, cpu->cfg.resetvec);
72
73
#ifndef CONFIG_USER_ONLY
74
if (cpu->cfg.ext_sstc) {
75
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = {
76
DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID),
77
DEFINE_PROP_UINT64("mimpid", RISCVCPU, cfg.mimpid, RISCV_CPU_MIMPID),
78
79
- DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
80
+#ifndef CONFIG_USER_ONLY
81
+ DEFINE_PROP_UINT64("resetvec", RISCVCPU, env.resetvec, DEFAULT_RSTVEC),
82
+#endif
83
84
DEFINE_PROP_BOOL("short-isa-string", RISCVCPU, cfg.short_isa_string, false),
85
86
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
52
index XXXXXXX..XXXXXXX 100644
87
index XXXXXXX..XXXXXXX 100644
53
--- a/target/riscv/cpu_helper.c
88
--- a/target/riscv/machine.c
54
+++ b/target/riscv/cpu_helper.c
89
+++ b/target/riscv/machine.c
55
@@ -XXX,XX +XXX,XX @@ static void raise_mmu_exception(CPURISCVState *env, target_ulong address,
90
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmu_ctr_state = {
56
g_assert_not_reached();
91
57
}
92
const VMStateDescription vmstate_riscv_cpu = {
58
env->badaddr = address;
93
.name = "cpu",
59
+ env->two_stage_lookup = two_stage;
94
- .version_id = 4,
60
}
95
- .minimum_version_id = 4,
61
96
+ .version_id = 5,
62
hwaddr riscv_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
97
+ .minimum_version_id = 5,
63
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
98
.post_load = riscv_cpu_post_load,
64
}
99
.fields = (VMStateField[]) {
65
100
VMSTATE_UINTTL_ARRAY(env.gpr, RISCVCPU, 32),
66
env->badaddr = addr;
101
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
67
+ env->two_stage_lookup = riscv_cpu_virt_enabled(env) ||
102
VMSTATE_UINT32(env.features, RISCVCPU),
68
+ riscv_cpu_two_stage_lookup(mmu_idx);
103
VMSTATE_UINTTL(env.priv, RISCVCPU),
69
riscv_raise_exception(&cpu->env, cs->exception_index, retaddr);
104
VMSTATE_UINTTL(env.virt, RISCVCPU),
70
}
105
- VMSTATE_UINTTL(env.resetvec, RISCVCPU),
71
106
+ VMSTATE_UINT64(env.resetvec, RISCVCPU),
72
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
107
VMSTATE_UINTTL(env.mhartid, RISCVCPU),
73
g_assert_not_reached();
108
VMSTATE_UINT64(env.mstatus, RISCVCPU),
74
}
109
VMSTATE_UINT64(env.mip, RISCVCPU),
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
--
110
--
120
2.30.1
111
2.37.3
121
122
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
The current condition for the use of background registers only
3
The resetvec for the OpenTitan machine ended up being set to an out of
4
considers the hypervisor load and store instructions,
4
date value, so let's fix that and bump it to the correct start address
5
but not accesses from M mode via MSTATUS_MPRV+MPV.
5
(after the boot ROM)
6
6
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
7
Fixes: bf8803c64d75 "hw/riscv: opentitan: bump opentitan version"
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210311103036.1401073-1-georg.kotheimer@kernkonzept.com
9
Message-Id: <20220914101108.82571-3-alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/cpu_helper.c | 2 +-
12
hw/riscv/opentitan.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
17
--- a/hw/riscv/opentitan.c
18
+++ b/target/riscv/cpu_helper.c
18
+++ b/hw/riscv/opentitan.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
19
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
20
* was called. Background registers will be used if the guest has
20
&error_abort);
21
* forced a two stage translation to be on (in HS or M mode).
21
object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
22
*/
22
&error_abort);
23
- if (!riscv_cpu_virt_enabled(env) && riscv_cpu_two_stage_lookup(mmu_idx)) {
23
- object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x20000490,
24
+ if (!riscv_cpu_virt_enabled(env) && two_stage) {
24
+ object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x20000400,
25
use_background = true;
25
&error_abort);
26
}
26
sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
27
27
28
--
28
--
29
2.30.1
29
2.37.3
30
31
diff view generated by jsdifflib
New patch
1
From: Alistair Francis <alistair.francis@wdc.com>
1
2
3
On the OpenTitan hardware the resetvec is fixed at the start of ROM. In
4
QEMU we don't run the ROM code and instead just jump to the next stage.
5
This means we need to be a little more flexible about what the resetvec
6
is.
7
8
This patch allows us to set the resetvec from the command line with
9
something like this:
10
-global driver=riscv.lowrisc.ibex.soc,property=resetvec,value=0x20000400
11
12
This way as the next stage changes we can update the resetvec.
13
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
Message-Id: <20220914101108.82571-4-alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/riscv/opentitan.h | 2 ++
20
hw/riscv/opentitan.c | 8 +++++++-
21
2 files changed, 9 insertions(+), 1 deletion(-)
22
23
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/opentitan.h
26
+++ b/include/hw/riscv/opentitan.h
27
@@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState {
28
IbexTimerState timer;
29
IbexSPIHostState spi_host[OPENTITAN_NUM_SPI_HOSTS];
30
31
+ uint32_t resetvec;
32
+
33
MemoryRegion flash_mem;
34
MemoryRegion rom;
35
MemoryRegion flash_alias;
36
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/opentitan.c
39
+++ b/hw/riscv/opentitan.c
40
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
41
&error_abort);
42
object_property_set_int(OBJECT(&s->cpus), "num-harts", ms->smp.cpus,
43
&error_abort);
44
- object_property_set_int(OBJECT(&s->cpus), "resetvec", 0x20000400,
45
+ object_property_set_int(OBJECT(&s->cpus), "resetvec", s->resetvec,
46
&error_abort);
47
sysbus_realize(SYS_BUS_DEVICE(&s->cpus), &error_fatal);
48
49
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
50
memmap[IBEX_DEV_PERI].base, memmap[IBEX_DEV_PERI].size);
51
}
52
53
+static Property lowrisc_ibex_soc_props[] = {
54
+ DEFINE_PROP_UINT32("resetvec", LowRISCIbexSoCState, resetvec, 0x20000400),
55
+ DEFINE_PROP_END_OF_LIST()
56
+};
57
+
58
static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
59
{
60
DeviceClass *dc = DEVICE_CLASS(oc);
61
62
+ device_class_set_props(dc, lowrisc_ibex_soc_props);
63
dc->realize = lowrisc_ibex_soc_realize;
64
/* Reason: Uses serial_hds in realize function, thus can't be used twice */
65
dc->user_creatable = false;
66
--
67
2.37.3
diff view generated by jsdifflib
1
From: Alexander Wagner <alexander.wagner@ulal.de>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
Not disabling the UART leads to QEMU overwriting the UART receive buffer with
3
After RISCVException enum is introduced, riscv_csrrw_debug() returns
4
the newest received byte. The rx_level variable is added to allow the use of
4
RISCV_EXCP_NONE to indicate there's no error. RISC-V vector GDB stub
5
the existing OpenTitan driver libraries.
5
should check the result against RISCV_EXCP_NONE instead of value 0.
6
Otherwise, 'E14' packet would be incorrectly reported for vector CSRs
7
when using "info reg vector" GDB command.
6
8
7
Signed-off-by: Alexander Wagner <alexander.wagner@ulal.de>
9
Signed-off-by: Frank Chang <frank.chang@sifive.com>
10
Reviewed-by: Jim Shu <jim.shu@sifive.com>
11
Reviewed-by: Tommy Wu <tommy.wu@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-id: 20210309152130.13038-1-alexander.wagner@ulal.de
13
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Message-Id: <20220918083245.13028-1-frank.chang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
16
---
12
include/hw/char/ibex_uart.h | 4 ++++
17
target/riscv/gdbstub.c | 4 ++--
13
hw/char/ibex_uart.c | 23 ++++++++++++++++++-----
18
1 file changed, 2 insertions(+), 2 deletions(-)
14
2 files changed, 22 insertions(+), 5 deletions(-)
15
19
16
diff --git a/include/hw/char/ibex_uart.h b/include/hw/char/ibex_uart.h
20
diff --git a/target/riscv/gdbstub.c b/target/riscv/gdbstub.c
17
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/char/ibex_uart.h
22
--- a/target/riscv/gdbstub.c
19
+++ b/include/hw/char/ibex_uart.h
23
+++ b/target/riscv/gdbstub.c
20
@@ -XXX,XX +XXX,XX @@ REG32(FIFO_CTRL, 0x1c)
24
@@ -XXX,XX +XXX,XX @@ static int riscv_gdb_get_vector(CPURISCVState *env, GByteArray *buf, int n)
21
FIELD(FIFO_CTRL, RXILVL, 2, 3)
25
target_ulong val = 0;
22
FIELD(FIFO_CTRL, TXILVL, 5, 2)
26
int result = riscv_csrrw_debug(env, csrno, &val, 0, 0);
23
REG32(FIFO_STATUS, 0x20)
27
24
+ FIELD(FIFO_STATUS, TXLVL, 0, 5)
28
- if (result == 0) {
25
+ FIELD(FIFO_STATUS, RXLVL, 16, 5)
29
+ if (result == RISCV_EXCP_NONE) {
26
REG32(OVRD, 0x24)
30
return gdb_get_regl(buf, val);
27
REG32(VAL, 0x28)
28
REG32(TIMEOUT_CTRL, 0x2c)
29
@@ -XXX,XX +XXX,XX @@ struct IbexUartState {
30
uint8_t tx_fifo[IBEX_UART_TX_FIFO_SIZE];
31
uint32_t tx_level;
32
33
+ uint32_t rx_level;
34
+
35
QEMUTimer *fifo_trigger_handle;
36
uint64_t char_tx_time;
37
38
diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/char/ibex_uart.c
41
+++ b/hw/char/ibex_uart.c
42
@@ -XXX,XX +XXX,XX @@ static int ibex_uart_can_receive(void *opaque)
43
{
44
IbexUartState *s = opaque;
45
46
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
47
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK)
48
+ && !(s->uart_status & R_STATUS_RXFULL_MASK)) {
49
return 1;
50
}
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 int riscv_gdb_set_vector(CPURISCVState *env, uint8_t *mem_buf, int n)
53
34
target_ulong val = ldtul_p(mem_buf);
54
s->uart_status &= ~R_STATUS_RXIDLE_MASK;
35
int result = riscv_csrrw_debug(env, csrno, NULL, val, -1);
55
s->uart_status &= ~R_STATUS_RXEMPTY_MASK;
36
56
+ /* The RXFULL is set after receiving a single byte
37
- if (result == 0) {
57
+ * as the FIFO buffers are not yet implemented.
38
+ if (result == RISCV_EXCP_NONE) {
58
+ */
39
return sizeof(target_ulong);
59
+ s->uart_status |= R_STATUS_RXFULL_MASK;
40
}
60
+ s->rx_level += 1;
41
61
62
if (size > rx_fifo_level) {
63
s->uart_intr_state |= R_INTR_STATE_RX_WATERMARK_MASK;
64
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_reset(DeviceState *dev)
65
s->uart_timeout_ctrl = 0x00000000;
66
67
s->tx_level = 0;
68
+ s->rx_level = 0;
69
70
s->char_tx_time = (NANOSECONDS_PER_SECOND / 230400) * 10;
71
72
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
73
74
case R_RDATA:
75
retvalue = s->uart_rdata;
76
- if (s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) {
77
+ if ((s->uart_ctrl & R_CTRL_RX_ENABLE_MASK) && (s->rx_level > 0)) {
78
qemu_chr_fe_accept_input(&s->chr);
79
80
- s->uart_status |= R_STATUS_RXIDLE_MASK;
81
- s->uart_status |= R_STATUS_RXEMPTY_MASK;
82
+ s->rx_level -= 1;
83
+ s->uart_status &= ~R_STATUS_RXFULL_MASK;
84
+ if (s->rx_level == 0) {
85
+ s->uart_status |= R_STATUS_RXIDLE_MASK;
86
+ s->uart_status |= R_STATUS_RXEMPTY_MASK;
87
+ }
88
}
89
break;
90
case R_WDATA:
91
@@ -XXX,XX +XXX,XX @@ static uint64_t ibex_uart_read(void *opaque, hwaddr addr,
92
case R_FIFO_STATUS:
93
retvalue = s->uart_fifo_status;
94
95
- retvalue |= s->tx_level & 0x1F;
96
+ retvalue |= (s->rx_level & 0x1F) << R_FIFO_STATUS_RXLVL_SHIFT;
97
+ retvalue |= (s->tx_level & 0x1F) << R_FIFO_STATUS_TXLVL_SHIFT;
98
99
qemu_log_mask(LOG_UNIMP,
100
"%s: RX fifos are not supported\n", __func__);
101
@@ -XXX,XX +XXX,XX @@ static void ibex_uart_write(void *opaque, hwaddr addr,
102
s->uart_fifo_ctrl = value;
103
104
if (value & R_FIFO_CTRL_RXRST_MASK) {
105
+ s->rx_level = 0;
106
qemu_log_mask(LOG_UNIMP,
107
"%s: RX fifos are not supported\n", __func__);
108
}
109
--
42
--
110
2.30.1
43
2.37.3
111
112
diff view generated by jsdifflib
1
From: Bin Meng <bin.meng@windriver.com>
1
From: Bernhard Beschow <shentey@gmail.com>
2
2
3
Since HSS commit c20a89f8dcac, the Icicle Kit reference design has
3
SiFiveEState inherits from SysBusDevice while it's TypeInfo claims it to
4
been updated to use a register mapped at 0x4f000000 instead of a
4
inherit from TYPE_MACHINE. This is an inconsistency which can cause
5
GPIO to control whether eMMC or SD card is to be used. With this
5
undefined behavior such as memory corruption.
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
6
11
With this commit, HSS image built from 2020.12 release boots again.
7
Change SiFiveEState to inherit from MachineState since it is registered
8
as a machine.
12
9
13
Signed-off-by: Bin Meng <bin.meng@windriver.com>
10
Fixes: 0869490b1c ("riscv: sifive_e: Manually define the machine")
11
12
Signed-off-by: Bernhard Beschow <shentey@gmail.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-id: 20210322075248.136255-1-bmeng.cn@gmail.com
14
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
15
Message-Id: <20220922075232.33653-1-shentey@gmail.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
17
---
18
include/hw/riscv/microchip_pfsoc.h | 1 +
18
include/hw/riscv/sifive_e.h | 3 ++-
19
hw/riscv/microchip_pfsoc.c | 6 ++++++
19
1 file changed, 2 insertions(+), 1 deletion(-)
20
2 files changed, 7 insertions(+)
21
20
22
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
21
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
23
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/microchip_pfsoc.h
23
--- a/include/hw/riscv/sifive_e.h
25
+++ b/include/hw/riscv/microchip_pfsoc.h
24
+++ b/include/hw/riscv/sifive_e.h
26
@@ -XXX,XX +XXX,XX @@ enum {
25
@@ -XXX,XX +XXX,XX @@
27
MICROCHIP_PFSOC_ENVM_DATA,
26
#include "hw/riscv/riscv_hart.h"
28
MICROCHIP_PFSOC_QSPI_XIP,
27
#include "hw/riscv/sifive_cpu.h"
29
MICROCHIP_PFSOC_IOSCB,
28
#include "hw/gpio/sifive_gpio.h"
30
+ MICROCHIP_PFSOC_EMMC_SD_MUX,
29
+#include "hw/boards.h"
31
MICROCHIP_PFSOC_DRAM_LO,
30
32
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
31
#define TYPE_RISCV_E_SOC "riscv.sifive.e.soc"
33
MICROCHIP_PFSOC_DRAM_HI,
32
#define RISCV_E_SOC(obj) \
34
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
33
@@ -XXX,XX +XXX,XX @@ typedef struct SiFiveESoCState {
35
index XXXXXXX..XXXXXXX 100644
34
36
--- a/hw/riscv/microchip_pfsoc.c
35
typedef struct SiFiveEState {
37
+++ b/hw/riscv/microchip_pfsoc.c
36
/*< private >*/
38
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry microchip_pfsoc_memmap[] = {
37
- SysBusDevice parent_obj;
39
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
38
+ MachineState parent_obj;
40
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
39
41
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
40
/*< public >*/
42
+ [MICROCHIP_PFSOC_EMMC_SD_MUX] = { 0x4f000000, 0x4 },
41
SiFiveESoCState soc;
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
--
42
--
59
2.30.1
43
2.37.3
60
61
diff view generated by jsdifflib
1
From: Frank Chang <frank.chang@sifive.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
vs() should return -RISCV_EXCP_ILLEGAL_INST instead of -1 if rvv feature
3
Current RISC-V debug assumes that only type 2 trigger is supported.
4
is not enabled.
4
To allow more types of triggers to be supported in the future
5
(e.g. type 6 trigger, which is similar to type 2 trigger with additional
6
functionality), we should determine the trigger type from tdata1.type.
5
7
6
If -1 is returned, exception will be raised and cs->exception_index will
8
RV_MAX_TRIGGERS is also introduced in replacement of TRIGGER_TYPE2_NUM.
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
9
10
Signed-off-by: Frank Chang <frank.chang@sifive.com>
10
Signed-off-by: Frank Chang <frank.chang@sifive.com>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
13
Message-id: 20210223065935.20208-1-frank.chang@sifive.com
13
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
[bmeng: fixed MXL_RV128 case, and moved macros to the following patch]
15
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
16
Message-Id: <20220909134215.1843865-2-bmeng.cn@gmail.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
18
---
16
target/riscv/csr.c | 2 +-
19
target/riscv/cpu.h | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
20
target/riscv/debug.h | 13 +--
21
target/riscv/csr.c | 2 +-
22
target/riscv/debug.c | 188 +++++++++++++++++++++++++++++------------
23
target/riscv/machine.c | 2 +-
24
5 files changed, 140 insertions(+), 67 deletions(-)
18
25
26
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/cpu.h
29
+++ b/target/riscv/cpu.h
30
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
31
32
/* trigger module */
33
target_ulong trigger_cur;
34
- type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM];
35
+ type2_trigger_t type2_trig[RV_MAX_TRIGGERS];
36
37
/* machine specific rdtime callback */
38
uint64_t (*rdtime_fn)(void *);
39
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/riscv/debug.h
42
+++ b/target/riscv/debug.h
43
@@ -XXX,XX +XXX,XX @@
44
#ifndef RISCV_DEBUG_H
45
#define RISCV_DEBUG_H
46
47
-/* trigger indexes implemented */
48
-enum {
49
- TRIGGER_TYPE2_IDX_0 = 0,
50
- TRIGGER_TYPE2_IDX_1,
51
- TRIGGER_TYPE2_NUM,
52
- TRIGGER_NUM = TRIGGER_TYPE2_NUM
53
-};
54
+#define RV_MAX_TRIGGERS 2
55
56
/* register index of tdata CSRs */
57
enum {
58
@@ -XXX,XX +XXX,XX @@ typedef enum {
59
TRIGGER_TYPE_EXCP = 5, /* exception trigger */
60
TRIGGER_TYPE_AD_MATCH6 = 6, /* new address/data match trigger */
61
TRIGGER_TYPE_EXT_SRC = 7, /* external source trigger */
62
- TRIGGER_TYPE_UNAVAIL = 15 /* trigger exists, but unavailable */
63
+ TRIGGER_TYPE_UNAVAIL = 15, /* trigger exists, but unavailable */
64
+ TRIGGER_TYPE_NUM
65
} trigger_type_t;
66
67
typedef struct {
68
@@ -XXX,XX +XXX,XX @@ typedef struct {
69
struct CPUWatchpoint *wp;
70
} type2_trigger_t;
71
72
-/* tdata field masks */
73
+/* tdata1 field masks */
74
75
#define RV32_TYPE(t) ((uint32_t)(t) << 28)
76
#define RV32_TYPE_MASK (0xf << 28)
19
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
77
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
20
index XXXXXXX..XXXXXXX 100644
78
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/csr.c
79
--- a/target/riscv/csr.c
22
+++ b/target/riscv/csr.c
80
+++ b/target/riscv/csr.c
23
@@ -XXX,XX +XXX,XX @@ static int vs(CPURISCVState *env, int csrno)
81
@@ -XXX,XX +XXX,XX @@ static RISCVException read_tdata(CPURISCVState *env, int csrno,
24
if (env->misa & RVV) {
82
target_ulong *val)
25
return 0;
83
{
26
}
84
/* return 0 in tdata1 to end the trigger enumeration */
27
- return -1;
85
- if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) {
28
+ return -RISCV_EXCP_ILLEGAL_INST;
86
+ if (env->trigger_cur >= RV_MAX_TRIGGERS && csrno == CSR_TDATA1) {
29
}
87
*val = 0;
30
88
return RISCV_EXCP_NONE;
31
static int ctr(CPURISCVState *env, int csrno)
89
}
90
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/target/riscv/debug.c
93
+++ b/target/riscv/debug.c
94
@@ -XXX,XX +XXX,XX @@
95
/* tdata availability of a trigger */
96
typedef bool tdata_avail[TDATA_NUM];
97
98
-static tdata_avail tdata_mapping[TRIGGER_NUM] = {
99
- [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false },
100
+static tdata_avail tdata_mapping[TRIGGER_TYPE_NUM] = {
101
+ [TRIGGER_TYPE_NO_EXIST] = { false, false, false },
102
+ [TRIGGER_TYPE_AD_MATCH] = { true, true, true },
103
+ [TRIGGER_TYPE_INST_CNT] = { true, false, true },
104
+ [TRIGGER_TYPE_INT] = { true, true, true },
105
+ [TRIGGER_TYPE_EXCP] = { true, true, true },
106
+ [TRIGGER_TYPE_AD_MATCH6] = { true, true, true },
107
+ [TRIGGER_TYPE_EXT_SRC] = { true, false, false },
108
+ [TRIGGER_TYPE_UNAVAIL] = { true, true, true }
109
};
110
111
/* only breakpoint size 1/2/4/8 supported */
112
@@ -XXX,XX +XXX,XX @@ static int access_size[SIZE_NUM] = {
113
[6 ... 15] = -1,
114
};
115
116
+static inline target_ulong extract_trigger_type(CPURISCVState *env,
117
+ target_ulong tdata1)
118
+{
119
+ switch (riscv_cpu_mxl(env)) {
120
+ case MXL_RV32:
121
+ return extract32(tdata1, 28, 4);
122
+ case MXL_RV64:
123
+ case MXL_RV128:
124
+ return extract64(tdata1, 60, 4);
125
+ default:
126
+ g_assert_not_reached();
127
+ }
128
+}
129
+
130
+static inline target_ulong get_trigger_type(CPURISCVState *env,
131
+ target_ulong trigger_index)
132
+{
133
+ target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol;
134
+ return extract_trigger_type(env, tdata1);
135
+}
136
+
137
static inline target_ulong trigger_type(CPURISCVState *env,
138
trigger_type_t type)
139
{
140
@@ -XXX,XX +XXX,XX @@ static inline target_ulong trigger_type(CPURISCVState *env,
141
142
bool tdata_available(CPURISCVState *env, int tdata_index)
143
{
144
+ int trigger_type = get_trigger_type(env, env->trigger_cur);
145
+
146
if (unlikely(tdata_index >= TDATA_NUM)) {
147
return false;
148
}
149
150
- if (unlikely(env->trigger_cur >= TRIGGER_NUM)) {
151
+ if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) {
152
return false;
153
}
154
155
- return tdata_mapping[env->trigger_cur][tdata_index];
156
+ return tdata_mapping[trigger_type][tdata_index];
157
}
158
159
target_ulong tselect_csr_read(CPURISCVState *env)
160
@@ -XXX,XX +XXX,XX @@ static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val,
161
qemu_log_mask(LOG_GUEST_ERROR,
162
"ignoring type write to tdata1 register\n");
163
}
164
+
165
if (dmode != 0) {
166
qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n");
167
}
168
@@ -XXX,XX +XXX,XX @@ static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index)
169
}
170
171
static target_ulong type2_reg_read(CPURISCVState *env,
172
- target_ulong trigger_index, int tdata_index)
173
+ target_ulong index, int tdata_index)
174
{
175
- uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0;
176
target_ulong tdata;
177
178
switch (tdata_index) {
179
@@ -XXX,XX +XXX,XX @@ static target_ulong type2_reg_read(CPURISCVState *env,
180
return tdata;
181
}
182
183
-static void type2_reg_write(CPURISCVState *env, target_ulong trigger_index,
184
+static void type2_reg_write(CPURISCVState *env, target_ulong index,
185
int tdata_index, target_ulong val)
186
{
187
- uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0;
188
target_ulong new_val;
189
190
switch (tdata_index) {
191
@@ -XXX,XX +XXX,XX @@ static void type2_reg_write(CPURISCVState *env, target_ulong trigger_index,
192
return;
193
}
194
195
-typedef target_ulong (*tdata_read_func)(CPURISCVState *env,
196
- target_ulong trigger_index,
197
- int tdata_index);
198
-
199
-static tdata_read_func trigger_read_funcs[TRIGGER_NUM] = {
200
- [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_read,
201
-};
202
-
203
-typedef void (*tdata_write_func)(CPURISCVState *env,
204
- target_ulong trigger_index,
205
- int tdata_index,
206
- target_ulong val);
207
-
208
-static tdata_write_func trigger_write_funcs[TRIGGER_NUM] = {
209
- [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_write,
210
-};
211
-
212
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
213
{
214
- tdata_read_func read_func = trigger_read_funcs[env->trigger_cur];
215
+ int trigger_type = get_trigger_type(env, env->trigger_cur);
216
+
217
+ switch (trigger_type) {
218
+ case TRIGGER_TYPE_AD_MATCH:
219
+ return type2_reg_read(env, env->trigger_cur, tdata_index);
220
+ break;
221
+ case TRIGGER_TYPE_INST_CNT:
222
+ case TRIGGER_TYPE_INT:
223
+ case TRIGGER_TYPE_EXCP:
224
+ case TRIGGER_TYPE_AD_MATCH6:
225
+ case TRIGGER_TYPE_EXT_SRC:
226
+ qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n",
227
+ trigger_type);
228
+ break;
229
+ case TRIGGER_TYPE_NO_EXIST:
230
+ case TRIGGER_TYPE_UNAVAIL:
231
+ qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n",
232
+ trigger_type);
233
+ break;
234
+ default:
235
+ g_assert_not_reached();
236
+ }
237
238
- return read_func(env, env->trigger_cur, tdata_index);
239
+ return 0;
240
}
241
242
void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
243
{
244
- tdata_write_func write_func = trigger_write_funcs[env->trigger_cur];
245
+ int trigger_type;
246
247
- return write_func(env, env->trigger_cur, tdata_index, val);
248
+ if (tdata_index == TDATA1) {
249
+ trigger_type = extract_trigger_type(env, val);
250
+ } else {
251
+ trigger_type = get_trigger_type(env, env->trigger_cur);
252
+ }
253
+
254
+ switch (trigger_type) {
255
+ case TRIGGER_TYPE_AD_MATCH:
256
+ type2_reg_write(env, env->trigger_cur, tdata_index, val);
257
+ break;
258
+ case TRIGGER_TYPE_INST_CNT:
259
+ case TRIGGER_TYPE_INT:
260
+ case TRIGGER_TYPE_EXCP:
261
+ case TRIGGER_TYPE_AD_MATCH6:
262
+ case TRIGGER_TYPE_EXT_SRC:
263
+ qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n",
264
+ trigger_type);
265
+ break;
266
+ case TRIGGER_TYPE_NO_EXIST:
267
+ case TRIGGER_TYPE_UNAVAIL:
268
+ qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n",
269
+ trigger_type);
270
+ break;
271
+ default:
272
+ g_assert_not_reached();
273
+ }
274
}
275
276
void riscv_cpu_debug_excp_handler(CPUState *cs)
277
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
278
CPUBreakpoint *bp;
279
target_ulong ctrl;
280
target_ulong pc;
281
+ int trigger_type;
282
int i;
283
284
QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
285
- for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
286
- ctrl = env->type2_trig[i].mcontrol;
287
- pc = env->type2_trig[i].maddress;
288
-
289
- if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
290
- /* check U/S/M bit against current privilege level */
291
- if ((ctrl >> 3) & BIT(env->priv)) {
292
- return true;
293
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
294
+ trigger_type = get_trigger_type(env, i);
295
+
296
+ switch (trigger_type) {
297
+ case TRIGGER_TYPE_AD_MATCH:
298
+ ctrl = env->type2_trig[i].mcontrol;
299
+ pc = env->type2_trig[i].maddress;
300
+
301
+ if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
302
+ /* check U/S/M bit against current privilege level */
303
+ if ((ctrl >> 3) & BIT(env->priv)) {
304
+ return true;
305
+ }
306
}
307
+ break;
308
+ default:
309
+ /* other trigger types are not supported or irrelevant */
310
+ break;
311
}
312
}
313
}
314
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
315
CPURISCVState *env = &cpu->env;
316
target_ulong ctrl;
317
target_ulong addr;
318
+ int trigger_type;
319
int flags;
320
int i;
321
322
- for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
323
- ctrl = env->type2_trig[i].mcontrol;
324
- addr = env->type2_trig[i].maddress;
325
- flags = 0;
326
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
327
+ trigger_type = get_trigger_type(env, i);
328
329
- if (ctrl & TYPE2_LOAD) {
330
- flags |= BP_MEM_READ;
331
- }
332
- if (ctrl & TYPE2_STORE) {
333
- flags |= BP_MEM_WRITE;
334
- }
335
+ switch (trigger_type) {
336
+ case TRIGGER_TYPE_AD_MATCH:
337
+ ctrl = env->type2_trig[i].mcontrol;
338
+ addr = env->type2_trig[i].maddress;
339
+ flags = 0;
340
341
- if ((wp->flags & flags) && (wp->vaddr == addr)) {
342
- /* check U/S/M bit against current privilege level */
343
- if ((ctrl >> 3) & BIT(env->priv)) {
344
- return true;
345
+ if (ctrl & TYPE2_LOAD) {
346
+ flags |= BP_MEM_READ;
347
+ }
348
+ if (ctrl & TYPE2_STORE) {
349
+ flags |= BP_MEM_WRITE;
350
+ }
351
+
352
+ if ((wp->flags & flags) && (wp->vaddr == addr)) {
353
+ /* check U/S/M bit against current privilege level */
354
+ if ((ctrl >> 3) & BIT(env->priv)) {
355
+ return true;
356
+ }
357
}
358
+ break;
359
+ default:
360
+ /* other trigger types are not supported */
361
+ break;
362
}
363
}
364
365
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
366
367
void riscv_trigger_init(CPURISCVState *env)
368
{
369
- target_ulong type2 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
370
+ target_ulong tdata1 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
371
int i;
372
373
- /* type 2 triggers */
374
- for (i = 0; i < TRIGGER_TYPE2_NUM; i++) {
375
+ /* init to type 2 triggers */
376
+ for (i = 0; i < RV_MAX_TRIGGERS; i++) {
377
/*
378
* type = TRIGGER_TYPE_AD_MATCH
379
* dmode = 0 (both debug and M-mode can write tdata)
380
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
381
* chain = 0 (unimplemented, always 0)
382
* match = 0 (always 0, when any compare value equals tdata2)
383
*/
384
- env->type2_trig[i].mcontrol = type2;
385
+ env->type2_trig[i].mcontrol = tdata1;
386
env->type2_trig[i].maddress = 0;
387
env->type2_trig[i].bp = NULL;
388
env->type2_trig[i].wp = NULL;
389
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
390
index XXXXXXX..XXXXXXX 100644
391
--- a/target/riscv/machine.c
392
+++ b/target/riscv/machine.c
393
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_debug = {
394
.needed = debug_needed,
395
.fields = (VMStateField[]) {
396
VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
397
- VMSTATE_STRUCT_ARRAY(env.type2_trig, RISCVCPU, TRIGGER_TYPE2_NUM,
398
+ VMSTATE_STRUCT_ARRAY(env.type2_trig, RISCVCPU, RV_MAX_TRIGGERS,
399
0, vmstate_debug_type2, type2_trigger_t),
400
VMSTATE_END_OF_LIST()
401
}
32
--
402
--
33
2.30.1
403
2.37.3
34
35
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
Allow ramfb on virt. This lets `-device ramfb' work.
3
Introduce build_tdata1() to build tdata1 register content, which can be
4
shared among all types of triggers.
4
5
5
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-id: 20210318235041.17175-3-ashe@kivikakk.ee
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
[bmeng: moved RV{32,64}_DATA_MASK definition to this patch]
11
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
12
Message-Id: <20220909134215.1843865-3-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
14
---
11
hw/riscv/virt.c | 3 +++
15
target/riscv/debug.h | 2 ++
12
1 file changed, 3 insertions(+)
16
target/riscv/debug.c | 15 ++++++++++-----
17
2 files changed, 12 insertions(+), 5 deletions(-)
13
18
14
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
19
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/virt.c
21
--- a/target/riscv/debug.h
17
+++ b/hw/riscv/virt.c
22
+++ b/target/riscv/debug.h
18
@@ -XXX,XX +XXX,XX @@
23
@@ -XXX,XX +XXX,XX @@ typedef struct {
19
#include "sysemu/sysemu.h"
24
#define RV32_TYPE(t) ((uint32_t)(t) << 28)
20
#include "hw/pci/pci.h"
25
#define RV32_TYPE_MASK (0xf << 28)
21
#include "hw/pci-host/gpex.h"
26
#define RV32_DMODE BIT(27)
22
+#include "hw/display/ramfb.h"
27
+#define RV32_DATA_MASK 0x7ffffff
23
28
#define RV64_TYPE(t) ((uint64_t)(t) << 60)
24
static const MemMapEntry virt_memmap[] = {
29
#define RV64_TYPE_MASK (0xfULL << 60)
25
[VIRT_DEBUG] = { 0x0, 0x100 },
30
#define RV64_DMODE BIT_ULL(59)
26
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
31
+#define RV64_DATA_MASK 0x7ffffffffffffff
27
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
32
28
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
33
/* mcontrol field masks */
29
mc->numa_mem_supported = true;
34
30
+
35
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
31
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/debug.c
38
+++ b/target/riscv/debug.c
39
@@ -XXX,XX +XXX,XX @@ static inline target_ulong get_trigger_type(CPURISCVState *env,
40
return extract_trigger_type(env, tdata1);
32
}
41
}
33
42
34
static const TypeInfo virt_machine_typeinfo = {
43
-static inline target_ulong trigger_type(CPURISCVState *env,
44
- trigger_type_t type)
45
+static inline target_ulong build_tdata1(CPURISCVState *env,
46
+ trigger_type_t type,
47
+ bool dmode, target_ulong data)
48
{
49
target_ulong tdata1;
50
51
switch (riscv_cpu_mxl(env)) {
52
case MXL_RV32:
53
- tdata1 = RV32_TYPE(type);
54
+ tdata1 = RV32_TYPE(type) |
55
+ (dmode ? RV32_DMODE : 0) |
56
+ (data & RV32_DATA_MASK);
57
break;
58
case MXL_RV64:
59
case MXL_RV128:
60
- tdata1 = RV64_TYPE(type);
61
+ tdata1 = RV64_TYPE(type) |
62
+ (dmode ? RV64_DMODE : 0) |
63
+ (data & RV64_DATA_MASK);
64
break;
65
default:
66
g_assert_not_reached();
67
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
68
69
void riscv_trigger_init(CPURISCVState *env)
70
{
71
- target_ulong tdata1 = trigger_type(env, TRIGGER_TYPE_AD_MATCH);
72
+ target_ulong tdata1 = build_tdata1(env, TRIGGER_TYPE_AD_MATCH, 0, 0);
73
int i;
74
75
/* init to type 2 triggers */
35
--
76
--
36
2.30.1
77
2.37.3
37
38
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
Like MMU translation, add qemu log of PMP permission checking for
3
Replace type2_trigger_t with the real tdata1, tdata2, and tdata3 CSRs,
4
debugging.
4
which allows us to support more types of triggers in the future.
5
5
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-id: 1613916082-19528-3-git-send-email-cwshu@andestech.com
8
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Message-Id: <20220909134215.1843865-4-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
target/riscv/cpu_helper.c | 12 ++++++++++++
13
target/riscv/cpu.h | 6 ++-
12
1 file changed, 12 insertions(+)
14
target/riscv/debug.h | 7 ---
15
target/riscv/debug.c | 103 +++++++++++++++--------------------------
16
target/riscv/machine.c | 20 ++------
17
4 files changed, 48 insertions(+), 88 deletions(-)
13
18
14
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/cpu_helper.c
21
--- a/target/riscv/cpu.h
17
+++ b/target/riscv/cpu_helper.c
22
+++ b/target/riscv/cpu.h
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
23
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
19
if (ret == TRANSLATE_SUCCESS) {
24
20
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
25
/* trigger module */
21
size, access_type, mode);
26
target_ulong trigger_cur;
27
- type2_trigger_t type2_trig[RV_MAX_TRIGGERS];
28
+ target_ulong tdata1[RV_MAX_TRIGGERS];
29
+ target_ulong tdata2[RV_MAX_TRIGGERS];
30
+ target_ulong tdata3[RV_MAX_TRIGGERS];
31
+ struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
32
+ struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
33
34
/* machine specific rdtime callback */
35
uint64_t (*rdtime_fn)(void *);
36
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
37
index XXXXXXX..XXXXXXX 100644
38
--- a/target/riscv/debug.h
39
+++ b/target/riscv/debug.h
40
@@ -XXX,XX +XXX,XX @@ typedef enum {
41
TRIGGER_TYPE_NUM
42
} trigger_type_t;
43
44
-typedef struct {
45
- target_ulong mcontrol;
46
- target_ulong maddress;
47
- struct CPUBreakpoint *bp;
48
- struct CPUWatchpoint *wp;
49
-} type2_trigger_t;
50
-
51
/* tdata1 field masks */
52
53
#define RV32_TYPE(t) ((uint32_t)(t) << 28)
54
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
55
index XXXXXXX..XXXXXXX 100644
56
--- a/target/riscv/debug.c
57
+++ b/target/riscv/debug.c
58
@@ -XXX,XX +XXX,XX @@ static inline target_ulong extract_trigger_type(CPURISCVState *env,
59
static inline target_ulong get_trigger_type(CPURISCVState *env,
60
target_ulong trigger_index)
61
{
62
- target_ulong tdata1 = env->type2_trig[trigger_index].mcontrol;
63
- return extract_trigger_type(env, tdata1);
64
+ return extract_trigger_type(env, env->tdata1[trigger_index]);
65
}
66
67
static inline target_ulong build_tdata1(CPURISCVState *env,
68
@@ -XXX,XX +XXX,XX @@ static inline void warn_always_zero_bit(target_ulong val, target_ulong mask,
69
}
70
}
71
72
+/* type 2 trigger */
22
+
73
+
23
+ qemu_log_mask(CPU_LOG_MMU,
74
static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl)
24
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
75
{
25
+ " %d tlb_size " TARGET_FMT_lu "\n",
76
uint32_t size, sizelo, sizehi = 0;
26
+ __func__, pa, ret, prot_pmp, tlb_size);
77
@@ -XXX,XX +XXX,XX @@ static target_ulong type2_mcontrol_validate(CPURISCVState *env,
27
+
78
28
prot &= prot_pmp;
79
static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index)
29
}
80
{
30
81
- target_ulong ctrl = env->type2_trig[index].mcontrol;
31
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
82
- target_ulong addr = env->type2_trig[index].maddress;
32
if (ret == TRANSLATE_SUCCESS) {
83
+ target_ulong ctrl = env->tdata1[index];
33
ret = get_physical_address_pmp(env, &prot_pmp, &tlb_size, pa,
84
+ target_ulong addr = env->tdata2[index];
34
size, access_type, mode);
85
bool enabled = type2_breakpoint_enabled(ctrl);
35
+
86
CPUState *cs = env_cpu(env);
36
+ qemu_log_mask(CPU_LOG_MMU,
87
int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
37
+ "%s PMP address=" TARGET_FMT_plx " ret %d prot"
88
@@ -XXX,XX +XXX,XX @@ static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index)
38
+ " %d tlb_size " TARGET_FMT_lu "\n",
89
}
39
+ __func__, pa, ret, prot_pmp, tlb_size);
90
40
+
91
if (ctrl & TYPE2_EXEC) {
41
prot &= prot_pmp;
92
- cpu_breakpoint_insert(cs, addr, flags, &env->type2_trig[index].bp);
93
+ cpu_breakpoint_insert(cs, addr, flags, &env->cpu_breakpoint[index]);
94
}
95
96
if (ctrl & TYPE2_LOAD) {
97
@@ -XXX,XX +XXX,XX @@ static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index)
98
size = type2_breakpoint_size(env, ctrl);
99
if (size != 0) {
100
cpu_watchpoint_insert(cs, addr, size, flags,
101
- &env->type2_trig[index].wp);
102
+ &env->cpu_watchpoint[index]);
103
} else {
104
cpu_watchpoint_insert(cs, addr, 8, flags,
105
- &env->type2_trig[index].wp);
106
+ &env->cpu_watchpoint[index]);
42
}
107
}
43
}
108
}
109
}
110
@@ -XXX,XX +XXX,XX @@ static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index)
111
{
112
CPUState *cs = env_cpu(env);
113
114
- if (env->type2_trig[index].bp) {
115
- cpu_breakpoint_remove_by_ref(cs, env->type2_trig[index].bp);
116
- env->type2_trig[index].bp = NULL;
117
+ if (env->cpu_breakpoint[index]) {
118
+ cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
119
+ env->cpu_breakpoint[index] = NULL;
120
}
121
122
- if (env->type2_trig[index].wp) {
123
- cpu_watchpoint_remove_by_ref(cs, env->type2_trig[index].wp);
124
- env->type2_trig[index].wp = NULL;
125
+ if (env->cpu_watchpoint[index]) {
126
+ cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
127
+ env->cpu_watchpoint[index] = NULL;
128
}
129
}
130
131
-static target_ulong type2_reg_read(CPURISCVState *env,
132
- target_ulong index, int tdata_index)
133
-{
134
- target_ulong tdata;
135
-
136
- switch (tdata_index) {
137
- case TDATA1:
138
- tdata = env->type2_trig[index].mcontrol;
139
- break;
140
- case TDATA2:
141
- tdata = env->type2_trig[index].maddress;
142
- break;
143
- default:
144
- g_assert_not_reached();
145
- }
146
-
147
- return tdata;
148
-}
149
-
150
static void type2_reg_write(CPURISCVState *env, target_ulong index,
151
int tdata_index, target_ulong val)
152
{
153
@@ -XXX,XX +XXX,XX @@ static void type2_reg_write(CPURISCVState *env, target_ulong index,
154
switch (tdata_index) {
155
case TDATA1:
156
new_val = type2_mcontrol_validate(env, val);
157
- if (new_val != env->type2_trig[index].mcontrol) {
158
- env->type2_trig[index].mcontrol = new_val;
159
+ if (new_val != env->tdata1[index]) {
160
+ env->tdata1[index] = new_val;
161
type2_breakpoint_remove(env, index);
162
type2_breakpoint_insert(env, index);
163
}
164
break;
165
case TDATA2:
166
- if (val != env->type2_trig[index].maddress) {
167
- env->type2_trig[index].maddress = val;
168
+ if (val != env->tdata2[index]) {
169
+ env->tdata2[index] = val;
170
type2_breakpoint_remove(env, index);
171
type2_breakpoint_insert(env, index);
172
}
173
break;
174
+ case TDATA3:
175
+ qemu_log_mask(LOG_UNIMP,
176
+ "tdata3 is not supported for type 2 trigger\n");
177
+ break;
178
default:
179
g_assert_not_reached();
180
}
181
@@ -XXX,XX +XXX,XX @@ static void type2_reg_write(CPURISCVState *env, target_ulong index,
182
183
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
184
{
185
- int trigger_type = get_trigger_type(env, env->trigger_cur);
186
-
187
- switch (trigger_type) {
188
- case TRIGGER_TYPE_AD_MATCH:
189
- return type2_reg_read(env, env->trigger_cur, tdata_index);
190
- break;
191
- case TRIGGER_TYPE_INST_CNT:
192
- case TRIGGER_TYPE_INT:
193
- case TRIGGER_TYPE_EXCP:
194
- case TRIGGER_TYPE_AD_MATCH6:
195
- case TRIGGER_TYPE_EXT_SRC:
196
- qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n",
197
- trigger_type);
198
- break;
199
- case TRIGGER_TYPE_NO_EXIST:
200
- case TRIGGER_TYPE_UNAVAIL:
201
- qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n",
202
- trigger_type);
203
- break;
204
+ switch (tdata_index) {
205
+ case TDATA1:
206
+ return env->tdata1[env->trigger_cur];
207
+ case TDATA2:
208
+ return env->tdata2[env->trigger_cur];
209
+ case TDATA3:
210
+ return env->tdata3[env->trigger_cur];
211
default:
212
g_assert_not_reached();
213
}
214
-
215
- return 0;
216
}
217
218
void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
219
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
220
221
switch (trigger_type) {
222
case TRIGGER_TYPE_AD_MATCH:
223
- ctrl = env->type2_trig[i].mcontrol;
224
- pc = env->type2_trig[i].maddress;
225
+ ctrl = env->tdata1[i];
226
+ pc = env->tdata2[i];
227
228
if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) {
229
/* check U/S/M bit against current privilege level */
230
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
231
232
switch (trigger_type) {
233
case TRIGGER_TYPE_AD_MATCH:
234
- ctrl = env->type2_trig[i].mcontrol;
235
- addr = env->type2_trig[i].maddress;
236
+ ctrl = env->tdata1[i];
237
+ addr = env->tdata2[i];
238
flags = 0;
239
240
if (ctrl & TYPE2_LOAD) {
241
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
242
* chain = 0 (unimplemented, always 0)
243
* match = 0 (always 0, when any compare value equals tdata2)
244
*/
245
- env->type2_trig[i].mcontrol = tdata1;
246
- env->type2_trig[i].maddress = 0;
247
- env->type2_trig[i].bp = NULL;
248
- env->type2_trig[i].wp = NULL;
249
+ env->tdata1[i] = tdata1;
250
+ env->tdata2[i] = 0;
251
+ env->tdata3[i] = 0;
252
+ env->cpu_breakpoint[i] = NULL;
253
+ env->cpu_watchpoint[i] = NULL;
254
}
255
}
256
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
257
index XXXXXXX..XXXXXXX 100644
258
--- a/target/riscv/machine.c
259
+++ b/target/riscv/machine.c
260
@@ -XXX,XX +XXX,XX @@ static bool debug_needed(void *opaque)
261
return riscv_feature(env, RISCV_FEATURE_DEBUG);
262
}
263
264
-static const VMStateDescription vmstate_debug_type2 = {
265
- .name = "cpu/debug/type2",
266
- .version_id = 1,
267
- .minimum_version_id = 1,
268
- .fields = (VMStateField[]) {
269
- VMSTATE_UINTTL(mcontrol, type2_trigger_t),
270
- VMSTATE_UINTTL(maddress, type2_trigger_t),
271
- VMSTATE_END_OF_LIST()
272
- }
273
-};
274
-
275
static const VMStateDescription vmstate_debug = {
276
.name = "cpu/debug",
277
- .version_id = 1,
278
- .minimum_version_id = 1,
279
+ .version_id = 2,
280
+ .minimum_version_id = 2,
281
.needed = debug_needed,
282
.fields = (VMStateField[]) {
283
VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
284
- VMSTATE_STRUCT_ARRAY(env.type2_trig, RISCVCPU, RV_MAX_TRIGGERS,
285
- 0, vmstate_debug_type2, type2_trigger_t),
286
+ VMSTATE_UINTTL_ARRAY(env.tdata1, RISCVCPU, RV_MAX_TRIGGERS),
287
+ VMSTATE_UINTTL_ARRAY(env.tdata2, RISCVCPU, RV_MAX_TRIGGERS),
288
+ VMSTATE_UINTTL_ARRAY(env.tdata3, RISCVCPU, RV_MAX_TRIGGERS),
289
VMSTATE_END_OF_LIST()
290
}
291
};
44
--
292
--
45
2.30.1
293
2.37.3
46
47
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
According to the specification the "field SPVP of hstatus controls the
3
The value of tselect CSR can be written should be limited within the
4
privilege level of the access" for the hypervisor virtual-machine load
4
range of supported triggers number.
5
and store instructions HLV, HLVX and HSV.
6
5
7
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Message-id: 20210311103005.1400718-1-georg.kotheimer@kernkonzept.com
8
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Message-Id: <20220909134215.1843865-5-bmeng.cn@gmail.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
target/riscv/cpu_helper.c | 25 ++++++++++++++-----------
13
target/riscv/debug.c | 9 +++------
13
1 file changed, 14 insertions(+), 11 deletions(-)
14
1 file changed, 3 insertions(+), 6 deletions(-)
14
15
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
--- a/target/riscv/debug.c
18
+++ b/target/riscv/cpu_helper.c
19
+++ b/target/riscv/debug.c
19
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
20
@@ -XXX,XX +XXX,XX @@ bool tdata_available(CPURISCVState *env, int tdata_index)
20
use_background = true;
21
return false;
21
}
22
}
22
23
23
- if (mode == PRV_M && access_type != MMU_INST_FETCH) {
24
- if (unlikely(env->trigger_cur >= RV_MAX_TRIGGERS)) {
24
+ /* MPRV does not affect the virtual-machine load/store
25
- return false;
25
+ instructions, HLV, HLVX, and HSV. */
26
+ if (riscv_cpu_two_stage_lookup(mmu_idx)) {
27
+ mode = get_field(env->hstatus, HSTATUS_SPVP);
28
+ } else if (mode == PRV_M && access_type != MMU_INST_FETCH) {
29
if (get_field(env->mstatus, MSTATUS_MPRV)) {
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
}
50
51
- if (riscv_has_ext(env, RVH) && env->priv == PRV_M &&
52
- access_type != MMU_INST_FETCH &&
53
- get_field(env->mstatus, MSTATUS_MPRV) &&
54
- get_field(env->mstatus, MSTATUS_MPV)) {
55
- two_stage_lookup = true;
56
- }
26
- }
57
-
27
-
58
if (riscv_cpu_virt_enabled(env) ||
28
return tdata_mapping[trigger_type][tdata_index];
59
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
29
}
60
access_type != MMU_INST_FETCH)) {
30
31
@@ -XXX,XX +XXX,XX @@ target_ulong tselect_csr_read(CPURISCVState *env)
32
33
void tselect_csr_write(CPURISCVState *env, target_ulong val)
34
{
35
- /* all target_ulong bits of tselect are implemented */
36
- env->trigger_cur = val;
37
+ if (val < RV_MAX_TRIGGERS) {
38
+ env->trigger_cur = val;
39
+ }
40
}
41
42
static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val,
61
--
43
--
62
2.30.1
44
2.37.3
63
64
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
tinfo.info:
4
- Used mideleg instead of hideleg to mask accesses
4
One bit for each possible type enumerated in tdata1.
5
- Used MIP_VSSIP instead of VS_MODE_INTERRUPTS to mask writes to vsie
5
If the bit is set, then that type is supported by the currently
6
- Did not shift between S bits and VS bits (VSEIP <-> SEIP, ...)
6
selected trigger.
7
7
8
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
8
Signed-off-by: Frank Chang <frank.chang@sifive.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
10
Message-id: 20210311094738.1376795-1-georg.kotheimer@kernkonzept.com
10
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
11
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
Message-Id: <20220909134215.1843865-6-bmeng.cn@gmail.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
14
---
13
target/riscv/csr.c | 68 +++++++++++++++++++++++-----------------------
15
target/riscv/cpu_bits.h | 1 +
14
1 file changed, 34 insertions(+), 34 deletions(-)
16
target/riscv/debug.h | 2 ++
17
target/riscv/csr.c | 8 ++++++++
18
target/riscv/debug.c | 10 +++++++---
19
4 files changed, 18 insertions(+), 3 deletions(-)
15
20
21
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_bits.h
24
+++ b/target/riscv/cpu_bits.h
25
@@ -XXX,XX +XXX,XX @@
26
#define CSR_TDATA1 0x7a1
27
#define CSR_TDATA2 0x7a2
28
#define CSR_TDATA3 0x7a3
29
+#define CSR_TINFO 0x7a4
30
31
/* Debug Mode Registers */
32
#define CSR_DCSR 0x7b0
33
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/debug.h
36
+++ b/target/riscv/debug.h
37
@@ -XXX,XX +XXX,XX @@ void tselect_csr_write(CPURISCVState *env, target_ulong val);
38
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index);
39
void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val);
40
41
+target_ulong tinfo_csr_read(CPURISCVState *env);
42
+
43
void riscv_cpu_debug_excp_handler(CPUState *cs);
44
bool riscv_cpu_debug_check_breakpoint(CPUState *cs);
45
bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
46
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
48
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
49
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ static int write_sstatus(CPURISCVState *env, int csrno, target_ulong val)
50
@@ -XXX,XX +XXX,XX @@ static RISCVException write_tdata(CPURISCVState *env, int csrno,
21
return write_mstatus(env, CSR_MSTATUS, newval);
51
return RISCV_EXCP_NONE;
22
}
52
}
23
53
24
+static int read_vsie(CPURISCVState *env, int csrno, target_ulong *val)
54
+static RISCVException read_tinfo(CPURISCVState *env, int csrno,
55
+ target_ulong *val)
25
+{
56
+{
26
+ /* Shift the VS bits to their S bit location in vsie */
57
+ *val = tinfo_csr_read(env);
27
+ *val = (env->mie & env->hideleg & VS_MODE_INTERRUPTS) >> 1;
58
+ return RISCV_EXCP_NONE;
28
+ return 0;
29
+}
59
+}
30
+
60
+
31
static int read_sie(CPURISCVState *env, int csrno, target_ulong *val)
61
/*
32
{
62
* Functions to access Pointer Masking feature registers
33
if (riscv_cpu_virt_enabled(env)) {
63
* We have to check if current priv lvl could modify
34
- /* Tell the guest the VS bits, shifted to the S bit locations */
64
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
35
- *val = (env->mie & env->mideleg & VS_MODE_INTERRUPTS) >> 1;
65
[CSR_TDATA1] = { "tdata1", debug, read_tdata, write_tdata },
36
+ read_vsie(env, CSR_VSIE, val);
66
[CSR_TDATA2] = { "tdata2", debug, read_tdata, write_tdata },
37
} else {
67
[CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata },
38
*val = env->mie & env->mideleg;
68
+ [CSR_TINFO] = { "tinfo", debug, read_tinfo, write_ignore },
69
70
/* User Pointer Masking */
71
[CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte },
72
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/target/riscv/debug.c
75
+++ b/target/riscv/debug.c
76
@@ -XXX,XX +XXX,XX @@
77
* - tdata1
78
* - tdata2
79
* - tdata3
80
- *
81
- * We don't support writable 'type' field in the tdata1 register, so there is
82
- * no need to implement the "tinfo" CSR.
83
+ * - tinfo
84
*
85
* The following triggers are implemented:
86
*
87
@@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
39
}
88
}
40
return 0;
41
}
89
}
42
90
43
-static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
91
+target_ulong tinfo_csr_read(CPURISCVState *env)
44
+static int write_vsie(CPURISCVState *env, int csrno, target_ulong val)
45
{
46
- target_ulong newval;
47
+ /* Shift the S bits to their VS bit location in mie */
48
+ target_ulong newval = (env->mie & ~VS_MODE_INTERRUPTS) |
49
+ ((val << 1) & env->hideleg & VS_MODE_INTERRUPTS);
50
+ return write_mie(env, CSR_MIE, newval);
51
+}
52
53
+static int write_sie(CPURISCVState *env, int csrno, target_ulong val)
54
+{
92
+{
55
if (riscv_cpu_virt_enabled(env)) {
93
+ /* assume all triggers support the same types of triggers */
56
- /* Shift the guests S bits to VS */
94
+ return BIT(TRIGGER_TYPE_AD_MATCH);
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
}
70
71
static int read_stvec(CPURISCVState *env, int csrno, target_ulong *val)
72
@@ -XXX,XX +XXX,XX @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val)
73
return 0;
74
}
75
76
+static int rmw_vsip(CPURISCVState *env, int csrno, target_ulong *ret_value,
77
+ target_ulong new_value, target_ulong write_mask)
78
+{
79
+ /* Shift the S bits to their VS bit location in mip */
80
+ int ret = rmw_mip(env, 0, ret_value, new_value << 1,
81
+ (write_mask << 1) & vsip_writable_mask & env->hideleg);
82
+ *ret_value &= VS_MODE_INTERRUPTS;
83
+ /* Shift the VS bits to their S bit location in vsip */
84
+ *ret_value >>= 1;
85
+ return ret;
86
+}
95
+}
87
+
96
+
88
static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
97
void riscv_cpu_debug_excp_handler(CPUState *cs)
89
target_ulong new_value, target_ulong write_mask)
90
{
98
{
91
int ret;
99
RISCVCPU *cpu = RISCV_CPU(cs);
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
}
106
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
--
100
--
131
2.30.1
101
2.37.3
132
133
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
Currently, PMP permission checking of TLB page is bypassed if TLB hits
3
Trigger actions are shared among all triggers. Extract to a common
4
Fix it by propagating PMP permission to TLB page permission.
4
function.
5
5
6
PMP permission checking also use MMU-style API to change TLB permission
6
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
and size.
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
8
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
9
Signed-off-by: Jim Shu <cwshu@andestech.com>
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
[bmeng: handle the DBG_ACTION_NONE case]
11
Message-id: 1613916082-19528-2-git-send-email-cwshu@andestech.com
11
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
12
Message-Id: <20220909134215.1843865-7-bmeng.cn@gmail.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
---
14
target/riscv/pmp.h | 4 +-
15
target/riscv/debug.h | 13 ++++++++++
15
target/riscv/cpu_helper.c | 84 +++++++++++++++++++++++++++++----------
16
target/riscv/debug.c | 59 ++++++++++++++++++++++++++++++++++++++++++--
16
target/riscv/pmp.c | 80 +++++++++++++++++++++++++++----------
17
2 files changed, 70 insertions(+), 2 deletions(-)
17
3 files changed, 125 insertions(+), 43 deletions(-)
18
18
19
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
19
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
20
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/pmp.h
21
--- a/target/riscv/debug.h
22
+++ b/target/riscv/pmp.h
22
+++ b/target/riscv/debug.h
23
@@ -XXX,XX +XXX,XX @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
23
@@ -XXX,XX +XXX,XX @@ typedef enum {
24
target_ulong val);
24
TRIGGER_TYPE_NUM
25
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
25
} trigger_type_t;
26
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
26
27
- target_ulong size, pmp_priv_t priv, target_ulong mode);
27
+/* actions */
28
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
28
+typedef enum {
29
+ target_ulong mode);
29
+ DBG_ACTION_NONE = -1, /* sentinel value */
30
bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
30
+ DBG_ACTION_BP = 0,
31
target_ulong *tlb_size);
31
+ DBG_ACTION_DBG_MODE,
32
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
32
+ DBG_ACTION_TRACE0,
33
void pmp_update_rule_nums(CPURISCVState *env);
33
+ DBG_ACTION_TRACE1,
34
uint32_t pmp_get_num_rules(CPURISCVState *env);
34
+ DBG_ACTION_TRACE2,
35
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
35
+ DBG_ACTION_TRACE3,
36
36
+ DBG_ACTION_EXT_DBG0 = 8,
37
#endif
37
+ DBG_ACTION_EXT_DBG1
38
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
38
+} trigger_action_t;
39
+
40
/* tdata1 field masks */
41
42
#define RV32_TYPE(t) ((uint32_t)(t) << 28)
43
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
39
index XXXXXXX..XXXXXXX 100644
44
index XXXXXXX..XXXXXXX 100644
40
--- a/target/riscv/cpu_helper.c
45
--- a/target/riscv/debug.c
41
+++ b/target/riscv/cpu_helper.c
46
+++ b/target/riscv/debug.c
42
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
47
@@ -XXX,XX +XXX,XX @@ static inline target_ulong get_trigger_type(CPURISCVState *env,
43
env->load_res = -1;
48
return extract_trigger_type(env, env->tdata1[trigger_index]);
44
}
49
}
45
50
46
+/*
51
+static trigger_action_t get_trigger_action(CPURISCVState *env,
47
+ * get_physical_address_pmp - check PMP permission for this physical address
52
+ target_ulong trigger_index)
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
+{
53
+{
65
+ pmp_priv_t pmp_priv;
54
+ target_ulong tdata1 = env->tdata1[trigger_index];
66
+ target_ulong tlb_size_pmp = 0;
55
+ int trigger_type = get_trigger_type(env, trigger_index);
56
+ trigger_action_t action = DBG_ACTION_NONE;
67
+
57
+
68
+ if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
58
+ switch (trigger_type) {
69
+ *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
59
+ case TRIGGER_TYPE_AD_MATCH:
70
+ return TRANSLATE_SUCCESS;
60
+ action = (tdata1 & TYPE2_ACTION) >> 12;
61
+ break;
62
+ case TRIGGER_TYPE_INST_CNT:
63
+ case TRIGGER_TYPE_INT:
64
+ case TRIGGER_TYPE_EXCP:
65
+ case TRIGGER_TYPE_AD_MATCH6:
66
+ case TRIGGER_TYPE_EXT_SRC:
67
+ qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n",
68
+ trigger_type);
69
+ break;
70
+ case TRIGGER_TYPE_NO_EXIST:
71
+ case TRIGGER_TYPE_UNAVAIL:
72
+ qemu_log_mask(LOG_GUEST_ERROR, "trigger type: %d does not exit\n",
73
+ trigger_type);
74
+ break;
75
+ default:
76
+ g_assert_not_reached();
71
+ }
77
+ }
72
+
78
+
73
+ if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
79
+ return action;
74
+ mode)) {
75
+ *prot = 0;
76
+ return TRANSLATE_PMP_FAIL;
77
+ }
78
+
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
+ }
84
+ }
85
+
86
+ return TRANSLATE_SUCCESS;
87
+}
80
+}
88
+
81
+
89
/* get_physical_address - get the physical address for this virtual address
82
static inline target_ulong build_tdata1(CPURISCVState *env,
90
*
83
trigger_type_t type,
91
* Do a page table walk to obtain the physical address corresponding to a
84
bool dmode, target_ulong data)
92
@@ -XXX,XX +XXX,XX @@ restart:
85
@@ -XXX,XX +XXX,XX @@ static inline void warn_always_zero_bit(target_ulong val, target_ulong mask,
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
}
86
}
87
}
88
89
+static void do_trigger_action(CPURISCVState *env, target_ulong trigger_index)
90
+{
91
+ trigger_action_t action = get_trigger_action(env, trigger_index);
155
+
92
+
156
if (ret == TRANSLATE_PMP_FAIL) {
93
+ switch (action) {
157
pmp_violation = true;
94
+ case DBG_ACTION_NONE:
158
}
95
+ break;
159
96
+ case DBG_ACTION_BP:
160
if (ret == TRANSLATE_SUCCESS) {
97
+ riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
161
- if (pmp_is_range_in_tlb(env, pa & TARGET_PAGE_MASK, &tlb_size)) {
98
+ break;
162
- tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
99
+ case DBG_ACTION_DBG_MODE:
163
- prot, mmu_idx, tlb_size);
100
+ case DBG_ACTION_TRACE0:
164
- } else {
101
+ case DBG_ACTION_TRACE1:
165
- tlb_set_page(cs, address & TARGET_PAGE_MASK, pa & TARGET_PAGE_MASK,
102
+ case DBG_ACTION_TRACE2:
166
- prot, mmu_idx, TARGET_PAGE_SIZE);
103
+ case DBG_ACTION_TRACE3:
167
- }
104
+ case DBG_ACTION_EXT_DBG0:
168
+ tlb_set_page(cs, address & ~(tlb_size - 1), pa & ~(tlb_size - 1),
105
+ case DBG_ACTION_EXT_DBG1:
169
+ prot, mmu_idx, tlb_size);
106
+ qemu_log_mask(LOG_UNIMP, "action: %d is not supported\n", action);
170
return true;
107
+ break;
171
} else if (probe) {
108
+ default:
172
return false;
109
+ g_assert_not_reached();
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
+ }
110
+ }
206
+
207
+ return ret;
208
+}
111
+}
209
+
112
+
210
113
/* type 2 trigger */
211
/*
114
212
* Public Interface
115
static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl)
213
@@ -XXX,XX +XXX,XX @@ static int pmp_is_in_range(CPURISCVState *env, int pmp_index, target_ulong addr)
116
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs)
214
* Check if the address has required RWX privs to complete desired operation
117
if (cs->watchpoint_hit) {
215
*/
118
if (cs->watchpoint_hit->flags & BP_CPU) {
216
bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
119
cs->watchpoint_hit = NULL;
217
- target_ulong size, pmp_priv_t privs, target_ulong mode)
120
- riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
218
+ target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
121
+ do_trigger_action(env, DBG_ACTION_BP);
219
+ target_ulong mode)
122
}
220
{
123
} else {
221
int i = 0;
124
if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) {
222
int ret = -1;
125
- riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0);
223
int pmp_size = 0;
126
+ do_trigger_action(env, DBG_ACTION_BP);
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
}
127
}
257
}
128
}
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
}
129
}
275
276
-
277
/*
278
* Handle a write to a pmpcfg CSP
279
*/
280
@@ -XXX,XX +XXX,XX @@ bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
281
282
return false;
283
}
284
+
285
+/*
286
+ * Convert PMP privilege to TLB page privilege.
287
+ */
288
+int pmp_priv_to_page_prot(pmp_priv_t pmp_priv)
289
+{
290
+ int prot = 0;
291
+
292
+ if (pmp_priv & PMP_READ) {
293
+ prot |= PAGE_READ;
294
+ }
295
+ if (pmp_priv & PMP_WRITE) {
296
+ prot |= PAGE_WRITE;
297
+ }
298
+ if (pmp_priv & PMP_EXEC) {
299
+ prot |= PAGE_EXEC;
300
+ }
301
+
302
+ return prot;
303
+}
304
--
130
--
305
2.30.1
131
2.37.3
306
307
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
Type 2 trigger cannot be fired in VU/VS modes.
4
the address bytes. Note only SPI mode is supported by SST flashes.
5
4
6
[1] http://ww1.microchip.com/downloads/en/devicedoc/s71271_04.pdf
5
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
6
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Signed-off-by: Bin Meng <bin.meng@windriver.com>
7
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20220909134215.1843865-8-bmeng.cn@gmail.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/debug.c | 10 ++++++++++
14
1 file changed, 3 insertions(+)
12
1 file changed, 10 insertions(+)
15
13
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
14
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
16
--- a/target/riscv/debug.c
19
+++ b/hw/block/m25p80.c
17
+++ b/target/riscv/debug.c
20
@@ -XXX,XX +XXX,XX @@ static void decode_fast_read_cmd(Flash *s)
18
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
21
s->needed_bytes = get_addr_length(s);
19
22
switch (get_man(s)) {
20
switch (trigger_type) {
23
/* Dummy cycles - modeled with bytes writes instead of bits */
21
case TRIGGER_TYPE_AD_MATCH:
24
+ case MAN_SST:
22
+ /* type 2 trigger cannot be fired in VU/VS mode */
25
+ s->needed_bytes += 1;
23
+ if (riscv_cpu_virt_enabled(env)) {
26
+ break;
24
+ return false;
27
case MAN_WINBOND:
25
+ }
28
s->needed_bytes += 8;
26
+
29
break;
27
ctrl = env->tdata1[i];
28
pc = env->tdata2[i];
29
30
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
31
32
switch (trigger_type) {
33
case TRIGGER_TYPE_AD_MATCH:
34
+ /* type 2 trigger cannot be fired in VU/VS mode */
35
+ if (riscv_cpu_virt_enabled(env)) {
36
+ return false;
37
+ }
38
+
39
ctrl = env->tdata1[i];
40
addr = env->tdata2[i];
41
flags = 0;
30
--
42
--
31
2.30.1
43
2.37.3
32
33
diff view generated by jsdifflib
1
From: Jim Shu <cwshu@andestech.com>
1
From: Frank Chang <frank.chang@sifive.com>
2
2
3
If PMP permission of any address has been changed by updating PMP entry,
3
Type 6 trigger is similar to a type 2 trigger, but provides additional
4
flush all TLB pages to prevent from getting old permission.
4
functionality and should be used instead of type 2 in newer
5
implementations.
5
6
6
Signed-off-by: Jim Shu <cwshu@andestech.com>
7
Signed-off-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Message-id: 1613916082-19528-4-git-send-email-cwshu@andestech.com
9
Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
10
Message-Id: <20220909134215.1843865-9-bmeng.cn@gmail.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
12
---
11
target/riscv/pmp.c | 4 ++++
13
target/riscv/debug.h | 18 +++++
12
1 file changed, 4 insertions(+)
14
target/riscv/debug.c | 174 ++++++++++++++++++++++++++++++++++++++++++-
15
2 files changed, 188 insertions(+), 4 deletions(-)
13
16
14
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
17
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/pmp.c
19
--- a/target/riscv/debug.h
17
+++ b/target/riscv/pmp.c
20
+++ b/target/riscv/debug.h
21
@@ -XXX,XX +XXX,XX @@ typedef enum {
22
#define TYPE2_HIT BIT(20)
23
#define TYPE2_SIZEHI (0x3 << 21) /* RV64 only */
24
25
+/* mcontrol6 field masks */
26
+
27
+#define TYPE6_LOAD BIT(0)
28
+#define TYPE6_STORE BIT(1)
29
+#define TYPE6_EXEC BIT(2)
30
+#define TYPE6_U BIT(3)
31
+#define TYPE6_S BIT(4)
32
+#define TYPE6_M BIT(6)
33
+#define TYPE6_MATCH (0xf << 7)
34
+#define TYPE6_CHAIN BIT(11)
35
+#define TYPE6_ACTION (0xf << 12)
36
+#define TYPE6_SIZE (0xf << 16)
37
+#define TYPE6_TIMING BIT(20)
38
+#define TYPE6_SELECT BIT(21)
39
+#define TYPE6_HIT BIT(22)
40
+#define TYPE6_VU BIT(23)
41
+#define TYPE6_VS BIT(24)
42
+
43
/* access size */
44
enum {
45
SIZE_ANY = 0,
46
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/riscv/debug.c
49
+++ b/target/riscv/debug.c
18
@@ -XXX,XX +XXX,XX @@
50
@@ -XXX,XX +XXX,XX @@
19
#include "qapi/error.h"
51
* - tdata3
20
#include "cpu.h"
52
* - tinfo
21
#include "trace.h"
53
*
22
+#include "exec/exec-all.h"
54
- * The following triggers are implemented:
23
55
+ * The following triggers are initialized by default:
24
static void pmp_write_cfg(CPURISCVState *env, uint32_t addr_index,
56
*
25
uint8_t val);
57
* Index | Type | tdata mapping | Description
26
@@ -XXX,XX +XXX,XX @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
58
* ------+------+------------------------+------------
27
cfg_val = (val >> 8 * i) & 0xff;
59
@@ -XXX,XX +XXX,XX @@ static trigger_action_t get_trigger_action(CPURISCVState *env,
28
pmp_write_cfg(env, (reg_index * 4) + i, cfg_val);
60
case TRIGGER_TYPE_AD_MATCH:
29
}
61
action = (tdata1 & TYPE2_ACTION) >> 12;
30
+
62
break;
31
+ /* If PMP permission of any addr has been changed, flush TLB pages. */
63
+ case TRIGGER_TYPE_AD_MATCH6:
32
+ tlb_flush(env_cpu(env));
64
+ action = (tdata1 & TYPE6_ACTION) >> 12;
65
+ break;
66
case TRIGGER_TYPE_INST_CNT:
67
case TRIGGER_TYPE_INT:
68
case TRIGGER_TYPE_EXCP:
69
- case TRIGGER_TYPE_AD_MATCH6:
70
case TRIGGER_TYPE_EXT_SRC:
71
qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n",
72
trigger_type);
73
@@ -XXX,XX +XXX,XX @@ static void type2_reg_write(CPURISCVState *env, target_ulong index,
74
return;
33
}
75
}
34
76
35
77
+/* type 6 trigger */
78
+
79
+static inline bool type6_breakpoint_enabled(target_ulong ctrl)
80
+{
81
+ bool mode = !!(ctrl & (TYPE6_VU | TYPE6_VS | TYPE6_U | TYPE6_S | TYPE6_M));
82
+ bool rwx = !!(ctrl & (TYPE6_LOAD | TYPE6_STORE | TYPE6_EXEC));
83
+
84
+ return mode && rwx;
85
+}
86
+
87
+static target_ulong type6_mcontrol6_validate(CPURISCVState *env,
88
+ target_ulong ctrl)
89
+{
90
+ target_ulong val;
91
+ uint32_t size;
92
+
93
+ /* validate the generic part first */
94
+ val = tdata1_validate(env, ctrl, TRIGGER_TYPE_AD_MATCH6);
95
+
96
+ /* validate unimplemented (always zero) bits */
97
+ warn_always_zero_bit(ctrl, TYPE6_MATCH, "match");
98
+ warn_always_zero_bit(ctrl, TYPE6_CHAIN, "chain");
99
+ warn_always_zero_bit(ctrl, TYPE6_ACTION, "action");
100
+ warn_always_zero_bit(ctrl, TYPE6_TIMING, "timing");
101
+ warn_always_zero_bit(ctrl, TYPE6_SELECT, "select");
102
+ warn_always_zero_bit(ctrl, TYPE6_HIT, "hit");
103
+
104
+ /* validate size encoding */
105
+ size = extract32(ctrl, 16, 4);
106
+ if (access_size[size] == -1) {
107
+ qemu_log_mask(LOG_UNIMP, "access size %d is not supported, using SIZE_ANY\n",
108
+ size);
109
+ } else {
110
+ val |= (ctrl & TYPE6_SIZE);
111
+ }
112
+
113
+ /* keep the mode and attribute bits */
114
+ val |= (ctrl & (TYPE6_VU | TYPE6_VS | TYPE6_U | TYPE6_S | TYPE6_M |
115
+ TYPE6_LOAD | TYPE6_STORE | TYPE6_EXEC));
116
+
117
+ return val;
118
+}
119
+
120
+static void type6_breakpoint_insert(CPURISCVState *env, target_ulong index)
121
+{
122
+ target_ulong ctrl = env->tdata1[index];
123
+ target_ulong addr = env->tdata2[index];
124
+ bool enabled = type6_breakpoint_enabled(ctrl);
125
+ CPUState *cs = env_cpu(env);
126
+ int flags = BP_CPU | BP_STOP_BEFORE_ACCESS;
127
+ uint32_t size;
128
+
129
+ if (!enabled) {
130
+ return;
131
+ }
132
+
133
+ if (ctrl & TYPE6_EXEC) {
134
+ cpu_breakpoint_insert(cs, addr, flags, &env->cpu_breakpoint[index]);
135
+ }
136
+
137
+ if (ctrl & TYPE6_LOAD) {
138
+ flags |= BP_MEM_READ;
139
+ }
140
+
141
+ if (ctrl & TYPE6_STORE) {
142
+ flags |= BP_MEM_WRITE;
143
+ }
144
+
145
+ if (flags & BP_MEM_ACCESS) {
146
+ size = extract32(ctrl, 16, 4);
147
+ if (size != 0) {
148
+ cpu_watchpoint_insert(cs, addr, size, flags,
149
+ &env->cpu_watchpoint[index]);
150
+ } else {
151
+ cpu_watchpoint_insert(cs, addr, 8, flags,
152
+ &env->cpu_watchpoint[index]);
153
+ }
154
+ }
155
+}
156
+
157
+static void type6_breakpoint_remove(CPURISCVState *env, target_ulong index)
158
+{
159
+ type2_breakpoint_remove(env, index);
160
+}
161
+
162
+static void type6_reg_write(CPURISCVState *env, target_ulong index,
163
+ int tdata_index, target_ulong val)
164
+{
165
+ target_ulong new_val;
166
+
167
+ switch (tdata_index) {
168
+ case TDATA1:
169
+ new_val = type6_mcontrol6_validate(env, val);
170
+ if (new_val != env->tdata1[index]) {
171
+ env->tdata1[index] = new_val;
172
+ type6_breakpoint_remove(env, index);
173
+ type6_breakpoint_insert(env, index);
174
+ }
175
+ break;
176
+ case TDATA2:
177
+ if (val != env->tdata2[index]) {
178
+ env->tdata2[index] = val;
179
+ type6_breakpoint_remove(env, index);
180
+ type6_breakpoint_insert(env, index);
181
+ }
182
+ break;
183
+ case TDATA3:
184
+ qemu_log_mask(LOG_UNIMP,
185
+ "tdata3 is not supported for type 6 trigger\n");
186
+ break;
187
+ default:
188
+ g_assert_not_reached();
189
+ }
190
+
191
+ return;
192
+}
193
+
194
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
195
{
196
switch (tdata_index) {
197
@@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
198
case TRIGGER_TYPE_AD_MATCH:
199
type2_reg_write(env, env->trigger_cur, tdata_index, val);
200
break;
201
+ case TRIGGER_TYPE_AD_MATCH6:
202
+ type6_reg_write(env, env->trigger_cur, tdata_index, val);
203
+ break;
204
case TRIGGER_TYPE_INST_CNT:
205
case TRIGGER_TYPE_INT:
206
case TRIGGER_TYPE_EXCP:
207
- case TRIGGER_TYPE_AD_MATCH6:
208
case TRIGGER_TYPE_EXT_SRC:
209
qemu_log_mask(LOG_UNIMP, "trigger type: %d is not supported\n",
210
trigger_type);
211
@@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
212
target_ulong tinfo_csr_read(CPURISCVState *env)
213
{
214
/* assume all triggers support the same types of triggers */
215
- return BIT(TRIGGER_TYPE_AD_MATCH);
216
+ return BIT(TRIGGER_TYPE_AD_MATCH) |
217
+ BIT(TRIGGER_TYPE_AD_MATCH6);
218
}
219
220
void riscv_cpu_debug_excp_handler(CPUState *cs)
221
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_breakpoint(CPUState *cs)
222
}
223
}
224
break;
225
+ case TRIGGER_TYPE_AD_MATCH6:
226
+ ctrl = env->tdata1[i];
227
+ pc = env->tdata2[i];
228
+
229
+ if ((ctrl & TYPE6_EXEC) && (bp->pc == pc)) {
230
+ if (riscv_cpu_virt_enabled(env)) {
231
+ /* check VU/VS bit against current privilege level */
232
+ if ((ctrl >> 23) & BIT(env->priv)) {
233
+ return true;
234
+ }
235
+ } else {
236
+ /* check U/S/M bit against current privilege level */
237
+ if ((ctrl >> 3) & BIT(env->priv)) {
238
+ return true;
239
+ }
240
+ }
241
+ }
242
+ break;
243
default:
244
/* other trigger types are not supported or irrelevant */
245
break;
246
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp)
247
}
248
}
249
break;
250
+ case TRIGGER_TYPE_AD_MATCH6:
251
+ ctrl = env->tdata1[i];
252
+ addr = env->tdata2[i];
253
+ flags = 0;
254
+
255
+ if (ctrl & TYPE6_LOAD) {
256
+ flags |= BP_MEM_READ;
257
+ }
258
+ if (ctrl & TYPE6_STORE) {
259
+ flags |= BP_MEM_WRITE;
260
+ }
261
+
262
+ if ((wp->flags & flags) && (wp->vaddr == addr)) {
263
+ if (riscv_cpu_virt_enabled(env)) {
264
+ /* check VU/VS bit against current privilege level */
265
+ if ((ctrl >> 23) & BIT(env->priv)) {
266
+ return true;
267
+ }
268
+ } else {
269
+ /* check U/S/M bit against current privilege level */
270
+ if ((ctrl >> 3) & BIT(env->priv)) {
271
+ return true;
272
+ }
273
+ }
274
+ }
275
+ break;
276
default:
277
/* other trigger types are not supported */
278
break;
36
--
279
--
37
2.30.1
280
2.37.3
38
39
diff view generated by jsdifflib
1
From: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
1
From: Yang Liu <liuyang22@iscas.ac.cn>
2
2
3
When decode_insn16() fails, we fall back to decode_RV32_64C() for
3
Remove duplicate code by wrapping vfwredsum_vs's OP function.
4
further compressed instruction decoding. However, prior to this change,
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
4
10
Instead of patching decode_RV32_64C(), we can just remove it,
5
Signed-off-by: Yang Liu <liuyang22@iscas.ac.cn>
11
as it is dead code since f330433b363 anyway.
12
13
Signed-off-by: Georg Kotheimer <georg.kotheimer@kernkonzept.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Frank Chang <frank.chang@sifive.com>
16
Message-id: 20210322121609.3097928-1-georg.kotheimer@kernkonzept.com
8
Message-Id: <20220817074802.20765-1-liuyang22@iscas.ac.cn>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
10
---
19
target/riscv/translate.c | 179 +--------------------------------------
11
target/riscv/vector_helper.c | 56 +++++++-----------------------------
20
1 file changed, 1 insertion(+), 178 deletions(-)
12
1 file changed, 10 insertions(+), 46 deletions(-)
21
13
22
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
14
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
23
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/translate.c
16
--- a/target/riscv/vector_helper.c
25
+++ b/target/riscv/translate.c
17
+++ b/target/riscv/vector_helper.c
26
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
18
@@ -XXX,XX +XXX,XX @@ GEN_VEXT_FRED(vfredmin_vs_h, uint16_t, uint16_t, H2, H2, float16_minimum_number)
27
CPUState *cs;
19
GEN_VEXT_FRED(vfredmin_vs_w, uint32_t, uint32_t, H4, H4, float32_minimum_number)
28
} DisasContext;
20
GEN_VEXT_FRED(vfredmin_vs_d, uint64_t, uint64_t, H8, H8, float64_minimum_number)
29
21
30
-#ifdef TARGET_RISCV64
22
-/* Vector Widening Floating-Point Reduction Instructions */
31
-/* convert riscv funct3 to qemu memop for load/store */
23
-/* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
32
-static const int tcg_memop_lookup[8] = {
24
-void HELPER(vfwredsum_vs_h)(void *vd, void *v0, void *vs1,
33
- [0 ... 7] = -1,
25
- void *vs2, CPURISCVState *env, uint32_t desc)
34
- [0] = MO_SB,
26
+/* Vector Widening Floating-Point Add Instructions */
35
- [1] = MO_TESW,
27
+static uint32_t fwadd16(uint32_t a, uint16_t b, float_status *s)
36
- [2] = MO_TESL,
28
{
37
- [3] = MO_TEQ,
29
- uint32_t vm = vext_vm(desc);
38
- [4] = MO_UB,
30
- uint32_t vl = env->vl;
39
- [5] = MO_TEUW,
31
- uint32_t esz = sizeof(uint32_t);
40
- [6] = MO_TEUL,
32
- uint32_t vlenb = simd_maxsz(desc);
41
-};
33
- uint32_t vta = vext_vta(desc);
42
-#endif
34
- uint32_t i;
35
- uint32_t s1 = *((uint32_t *)vs1 + H4(0));
43
-
36
-
44
#ifdef TARGET_RISCV64
37
- for (i = env->vstart; i < vl; i++) {
45
#define CASE_OP_32_64(X) case X: case glue(X, W)
38
- uint16_t s2 = *((uint16_t *)vs2 + H2(i));
46
#else
39
- if (!vm && !vext_elem_mask(v0, i)) {
47
@@ -XXX,XX +XXX,XX @@ static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
40
- continue;
48
ctx->base.is_jmp = DISAS_NORETURN;
41
- }
42
- s1 = float32_add(s1, float16_to_float32(s2, true, &env->fp_status),
43
- &env->fp_status);
44
- }
45
- *((uint32_t *)vd + H4(0)) = s1;
46
- env->vstart = 0;
47
- /* set tail elements to 1s */
48
- vext_set_elems_1s(vd, vta, esz, vlenb);
49
+ return float32_add(a, float16_to_float32(b, true, s), s);
49
}
50
}
50
51
51
-#ifdef TARGET_RISCV64
52
-void HELPER(vfwredsum_vs_w)(void *vd, void *v0, void *vs1,
52
-static void gen_load_c(DisasContext *ctx, uint32_t opc, int rd, int rs1,
53
- void *vs2, CPURISCVState *env, uint32_t desc)
53
- target_long imm)
54
+static uint64_t fwadd32(uint64_t a, uint32_t b, float_status *s)
54
-{
55
{
55
- TCGv t0 = tcg_temp_new();
56
- uint32_t vm = vext_vm(desc);
56
- TCGv t1 = tcg_temp_new();
57
- uint32_t vl = env->vl;
57
- gen_get_gpr(t0, rs1);
58
- uint32_t esz = sizeof(uint64_t);
58
- tcg_gen_addi_tl(t0, t0, imm);
59
- uint32_t vlenb = simd_maxsz(desc);
59
- int memop = tcg_memop_lookup[(opc >> 12) & 0x7];
60
- uint32_t vta = vext_vta(desc);
61
- uint32_t i;
62
- uint64_t s1 = *((uint64_t *)vs1);
60
-
63
-
61
- if (memop < 0) {
64
- for (i = env->vstart; i < vl; i++) {
62
- gen_exception_illegal(ctx);
65
- uint32_t s2 = *((uint32_t *)vs2 + H4(i));
63
- return;
66
- if (!vm && !vext_elem_mask(v0, i)) {
67
- continue;
68
- }
69
- s1 = float64_add(s1, float32_to_float64(s2, &env->fp_status),
70
- &env->fp_status);
64
- }
71
- }
65
-
72
- *((uint64_t *)vd) = s1;
66
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, memop);
73
- env->vstart = 0;
67
- gen_set_gpr(rd, t1);
74
- /* set tail elements to 1s */
68
- tcg_temp_free(t0);
75
- vext_set_elems_1s(vd, vta, esz, vlenb);
69
- tcg_temp_free(t1);
76
+ return float64_add(a, float32_to_float64(b, s), s);
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
}
77
}
183
78
184
-static void decode_RV32_64C0(DisasContext *ctx, uint16_t opcode)
79
+/* Vector Widening Floating-Point Reduction Instructions */
185
-{
80
+/* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
186
- uint8_t funct3 = extract16(opcode, 13, 3);
81
+GEN_VEXT_FRED(vfwredsum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16)
187
- uint8_t rd_rs2 = GET_C_RS2S(opcode);
82
+GEN_VEXT_FRED(vfwredsum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32)
188
- uint8_t rs1s = GET_C_RS1S(opcode);
83
+
189
-
84
/*
190
- switch (funct3) {
85
*** Vector Mask Operations
191
- case 3:
86
*/
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
--
87
--
241
2.30.1
88
2.37.3
242
243
diff view generated by jsdifflib
1
From: Asherah Connor <ashe@kivikakk.ee>
1
From: Yang Liu <liuyang22@iscas.ac.cn>
2
2
3
Provides fw_cfg for the virt machine on riscv. This enables
3
Starting with RVV1.0, the original vf[w]redsum_vs instruction was renamed
4
using e.g. ramfb later.
4
to vf[w]redusum_vs. The distinction between ordered and unordered is also
5
more consistent with other instructions, although there is no difference
6
in implementation between the two for QEMU.
5
7
6
Signed-off-by: Asherah Connor <ashe@kivikakk.ee>
8
Signed-off-by: Yang Liu <liuyang22@iscas.ac.cn>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Message-id: 20210318235041.17175-2-ashe@kivikakk.ee
11
Message-Id: <20220817074802.20765-2-liuyang22@iscas.ac.cn>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
13
---
12
include/hw/riscv/virt.h | 2 ++
14
target/riscv/helper.h | 15 ++++++++++-----
13
hw/riscv/virt.c | 30 ++++++++++++++++++++++++++++++
15
target/riscv/insn32.decode | 6 ++++--
14
hw/riscv/Kconfig | 1 +
16
target/riscv/vector_helper.c | 19 +++++++++++++------
15
3 files changed, 33 insertions(+)
17
target/riscv/insn_trans/trans_rvv.c.inc | 6 ++++--
18
4 files changed, 31 insertions(+), 15 deletions(-)
16
19
17
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
20
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
18
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/riscv/virt.h
22
--- a/target/riscv/helper.h
20
+++ b/include/hw/riscv/virt.h
23
+++ b/target/riscv/helper.h
21
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
24
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vwredsum_vs_b, void, ptr, ptr, ptr, ptr, env, i32)
22
RISCVHartArrayState soc[VIRT_SOCKETS_MAX];
25
DEF_HELPER_6(vwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
23
DeviceState *plic[VIRT_SOCKETS_MAX];
26
DEF_HELPER_6(vwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
24
PFlashCFI01 *flash[2];
27
25
+ FWCfgState *fw_cfg;
28
-DEF_HELPER_6(vfredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
26
29
-DEF_HELPER_6(vfredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
27
int fdt_size;
30
-DEF_HELPER_6(vfredsum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
28
};
31
+DEF_HELPER_6(vfredusum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
29
@@ -XXX,XX +XXX,XX @@ enum {
32
+DEF_HELPER_6(vfredusum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
30
VIRT_PLIC,
33
+DEF_HELPER_6(vfredusum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
31
VIRT_UART0,
34
+DEF_HELPER_6(vfredosum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
32
VIRT_VIRTIO,
35
+DEF_HELPER_6(vfredosum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
33
+ VIRT_FW_CFG,
36
+DEF_HELPER_6(vfredosum_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
34
VIRT_FLASH,
37
DEF_HELPER_6(vfredmax_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
35
VIRT_DRAM,
38
DEF_HELPER_6(vfredmax_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
36
VIRT_PCIE_MMIO,
39
DEF_HELPER_6(vfredmax_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
37
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
40
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vfredmin_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
41
DEF_HELPER_6(vfredmin_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
42
DEF_HELPER_6(vfredmin_vs_d, void, ptr, ptr, ptr, ptr, env, i32)
43
44
-DEF_HELPER_6(vfwredsum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
45
-DEF_HELPER_6(vfwredsum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
46
+DEF_HELPER_6(vfwredusum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
47
+DEF_HELPER_6(vfwredusum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
48
+DEF_HELPER_6(vfwredosum_vs_h, void, ptr, ptr, ptr, ptr, env, i32)
49
+DEF_HELPER_6(vfwredosum_vs_w, void, ptr, ptr, ptr, ptr, env, i32)
50
51
DEF_HELPER_6(vmand_mm, void, ptr, ptr, ptr, ptr, env, i32)
52
DEF_HELPER_6(vmnand_mm, void, ptr, ptr, ptr, ptr, env, i32)
53
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
38
index XXXXXXX..XXXXXXX 100644
54
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/riscv/virt.c
55
--- a/target/riscv/insn32.decode
40
+++ b/hw/riscv/virt.c
56
+++ b/target/riscv/insn32.decode
41
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
57
@@ -XXX,XX +XXX,XX @@ vredmax_vs 000111 . ..... ..... 010 ..... 1010111 @r_vm
42
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
58
vwredsumu_vs 110000 . ..... ..... 000 ..... 1010111 @r_vm
43
[VIRT_UART0] = { 0x10000000, 0x100 },
59
vwredsum_vs 110001 . ..... ..... 000 ..... 1010111 @r_vm
44
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
60
# Vector ordered and unordered reduction sum
45
+ [VIRT_FW_CFG] = { 0x10100000, 0x18 },
61
-vfredsum_vs 0000-1 . ..... ..... 001 ..... 1010111 @r_vm
46
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
62
+vfredusum_vs 000001 . ..... ..... 001 ..... 1010111 @r_vm
47
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
63
+vfredosum_vs 000011 . ..... ..... 001 ..... 1010111 @r_vm
48
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
64
vfredmin_vs 000101 . ..... ..... 001 ..... 1010111 @r_vm
49
@@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
65
vfredmax_vs 000111 . ..... ..... 001 ..... 1010111 @r_vm
50
return dev;
66
# Vector widening ordered and unordered float reduction sum
67
-vfwredsum_vs 1100-1 . ..... ..... 001 ..... 1010111 @r_vm
68
+vfwredusum_vs 110001 . ..... ..... 001 ..... 1010111 @r_vm
69
+vfwredosum_vs 110011 . ..... ..... 001 ..... 1010111 @r_vm
70
vmand_mm 011001 - ..... ..... 010 ..... 1010111 @r
71
vmnand_mm 011101 - ..... ..... 010 ..... 1010111 @r
72
vmandn_mm 011000 - ..... ..... 010 ..... 1010111 @r
73
diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/riscv/vector_helper.c
76
+++ b/target/riscv/vector_helper.c
77
@@ -XXX,XX +XXX,XX @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, \
51
}
78
}
52
79
53
+static FWCfgState *create_fw_cfg(const MachineState *mc)
80
/* Unordered sum */
54
+{
81
-GEN_VEXT_FRED(vfredsum_vs_h, uint16_t, uint16_t, H2, H2, float16_add)
55
+ hwaddr base = virt_memmap[VIRT_FW_CFG].base;
82
-GEN_VEXT_FRED(vfredsum_vs_w, uint32_t, uint32_t, H4, H4, float32_add)
56
+ hwaddr size = virt_memmap[VIRT_FW_CFG].size;
83
-GEN_VEXT_FRED(vfredsum_vs_d, uint64_t, uint64_t, H8, H8, float64_add)
57
+ FWCfgState *fw_cfg;
84
+GEN_VEXT_FRED(vfredusum_vs_h, uint16_t, uint16_t, H2, H2, float16_add)
58
+ char *nodename;
85
+GEN_VEXT_FRED(vfredusum_vs_w, uint32_t, uint32_t, H4, H4, float32_add)
86
+GEN_VEXT_FRED(vfredusum_vs_d, uint64_t, uint64_t, H8, H8, float64_add)
59
+
87
+
60
+ fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16,
88
+/* Ordered sum */
61
+ &address_space_memory);
89
+GEN_VEXT_FRED(vfredosum_vs_h, uint16_t, uint16_t, H2, H2, float16_add)
62
+ fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, (uint16_t)mc->smp.cpus);
90
+GEN_VEXT_FRED(vfredosum_vs_w, uint32_t, uint32_t, H4, H4, float32_add)
63
+
91
+GEN_VEXT_FRED(vfredosum_vs_d, uint64_t, uint64_t, H8, H8, float64_add)
64
+ nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base);
92
65
+ qemu_fdt_add_subnode(mc->fdt, nodename);
93
/* Maximum value */
66
+ qemu_fdt_setprop_string(mc->fdt, nodename,
94
GEN_VEXT_FRED(vfredmax_vs_h, uint16_t, uint16_t, H2, H2, float16_maximum_number)
67
+ "compatible", "qemu,fw-cfg-mmio");
95
@@ -XXX,XX +XXX,XX @@ static uint64_t fwadd32(uint64_t a, uint32_t b, float_status *s)
68
+ qemu_fdt_setprop_sized_cells(mc->fdt, nodename, "reg",
96
}
69
+ 2, base, 2, size);
97
70
+ qemu_fdt_setprop(mc->fdt, nodename, "dma-coherent", NULL, 0);
98
/* Vector Widening Floating-Point Reduction Instructions */
71
+ g_free(nodename);
99
-/* Unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
72
+ return fw_cfg;
100
-GEN_VEXT_FRED(vfwredsum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16)
73
+}
101
-GEN_VEXT_FRED(vfwredsum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32)
74
+
102
+/* Ordered/unordered reduce 2*SEW = 2*SEW + sum(promote(SEW)) */
75
static void virt_machine_init(MachineState *machine)
103
+GEN_VEXT_FRED(vfwredusum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16)
76
{
104
+GEN_VEXT_FRED(vfwredusum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32)
77
const MemMapEntry *memmap = virt_memmap;
105
+GEN_VEXT_FRED(vfwredosum_vs_h, uint32_t, uint16_t, H4, H2, fwadd16)
78
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
106
+GEN_VEXT_FRED(vfwredosum_vs_w, uint64_t, uint32_t, H8, H4, fwadd32)
79
start_addr = virt_memmap[VIRT_FLASH].base;
107
80
}
108
/*
81
109
*** Vector Mask Operations
82
+ /*
110
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
83
+ * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device
84
+ * tree cannot be altered and we get FDT_ERR_NOSPACE.
85
+ */
86
+ s->fw_cfg = create_fw_cfg(machine);
87
+ rom_set_fw(s->fw_cfg);
88
+
89
/* Compute the fdt load address in dram */
90
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
91
machine->ram_size, machine->fdt);
92
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
93
index XXXXXXX..XXXXXXX 100644
111
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/Kconfig
112
--- a/target/riscv/insn_trans/trans_rvv.c.inc
95
+++ b/hw/riscv/Kconfig
113
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
96
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
114
@@ -XXX,XX +XXX,XX @@ static bool freduction_check(DisasContext *s, arg_rmrr *a)
97
select SIFIVE_PLIC
115
require_zve64f(s);
98
select SIFIVE_TEST
116
}
99
select VIRTIO_MMIO
117
100
+ select FW_CFG_DMA
118
-GEN_OPFVV_TRANS(vfredsum_vs, freduction_check)
101
119
+GEN_OPFVV_TRANS(vfredusum_vs, freduction_check)
102
config SIFIVE_E
120
+GEN_OPFVV_TRANS(vfredosum_vs, freduction_check)
103
bool
121
GEN_OPFVV_TRANS(vfredmax_vs, freduction_check)
122
GEN_OPFVV_TRANS(vfredmin_vs, freduction_check)
123
124
@@ -XXX,XX +XXX,XX @@ static bool freduction_widen_check(DisasContext *s, arg_rmrr *a)
125
(s->sew != MO_8);
126
}
127
128
-GEN_OPFVV_WIDEN_TRANS(vfwredsum_vs, freduction_widen_check)
129
+GEN_OPFVV_WIDEN_TRANS(vfwredusum_vs, freduction_widen_check)
130
+GEN_OPFVV_WIDEN_TRANS(vfwredosum_vs, freduction_widen_check)
131
132
/*
133
*** Vector Mask Operations
104
--
134
--
105
2.30.1
135
2.37.3
106
107
diff view generated by jsdifflib