1
The following changes since commit 9435a8b3dd35f1f926f1b9127e8a906217a5518a:
1
From: Alistair Francis <alistair.francis@wdc.com>
2
2
3
Merge remote-tracking branch 'remotes/kraxel/tags/sirius/ipxe-20200908-pull-request' into staging (2020-09-08 21:21:13 +0100)
3
The following changes since commit 562d4af32ec2213061f844b3838223fd7711b56a:
4
5
Merge tag 'pull-loongarch-20221215' of https://gitlab.com/gaosong/qemu into staging (2022-12-18 13:53:29 +0000)
4
6
5
are available in the Git repository at:
7
are available in the Git repository at:
6
8
7
git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20200910
9
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20221219-3
8
10
9
for you to fetch changes up to 7595a65818ea9b49c36650a8c217a1ef9bd6e62a:
11
for you to fetch changes up to e59b3c6ece6a1351aeca6b916cd9674e23d15e89:
10
12
11
hw/riscv: Sort the Kconfig options in alphabetical order (2020-09-09 15:54:19 -0700)
13
hw/intc: sifive_plic: Fix the pending register range check (2022-12-19 10:42:14 +1000)
12
14
13
----------------------------------------------------------------
15
----------------------------------------------------------------
14
This PR includes multiple fixes and features for RISC-V:
16
First RISC-V PR for QEMU 8.0
15
- Fixes a bug in printing trap causes
17
16
- Allows 16-bit writes to the SiFive test device. This fixes the
18
* Fix PMP propagation for tlb
17
failure to reboot the RISC-V virt machine
19
* Collection of bug fixes
18
- Support for the Microchip PolarFire SoC and Icicle Kit
20
* Add the `FIELDx_1CLEAR()` macro
19
- A reafactor of RISC-V code out of hw/riscv
21
* Bump the OpenTitan supported version
22
* Add smstateen support
23
* Support native debug icount trigger
24
* Remove the redundant ipi-id property in the virt machine
25
* Support cache-related PMU events in virtual mode
26
* Add some missing PolarFire SoC io regions
27
* Fix mret exception cause when no pmp rule is configured
28
* Fix bug where disabling compressed instructions would crash QEMU
29
* Add Zawrs ISA extension support
30
* A range of code refactoring and cleanups
20
31
21
----------------------------------------------------------------
32
----------------------------------------------------------------
22
Bin Meng (28):
33
Anup Patel (1):
23
target/riscv: cpu: Add a new 'resetvec' property
34
target/riscv: Typo fix in sstc() predicate
24
hw/riscv: hart: Add a new 'resetvec' property
25
target/riscv: cpu: Set reset vector based on the configured property value
26
hw/riscv: Initial support for Microchip PolarFire SoC Icicle Kit board
27
hw/char: Add Microchip PolarFire SoC MMUART emulation
28
hw/riscv: microchip_pfsoc: Connect 5 MMUARTs
29
hw/sd: Add Cadence SDHCI emulation
30
hw/riscv: microchip_pfsoc: Connect a Cadence SDHCI controller and an SD card
31
hw/dma: Add SiFive platform DMA controller emulation
32
hw/riscv: microchip_pfsoc: Connect a DMA controller
33
hw/net: cadence_gem: Add a new 'phy-addr' property
34
hw/arm: xlnx: Set all boards' GEM 'phy-addr' property value to 23
35
hw/riscv: microchip_pfsoc: Connect 2 Cadence GEMs
36
hw/riscv: microchip_pfsoc: Hook GPIO controllers
37
hw/riscv: clint: Avoid using hard-coded timebase frequency
38
hw/riscv: sifive_u: Connect a DMA controller
39
hw/riscv: Move sifive_e_prci model to hw/misc
40
hw/riscv: Move sifive_u_prci model to hw/misc
41
hw/riscv: Move sifive_u_otp model to hw/misc
42
hw/riscv: Move sifive_gpio model to hw/gpio
43
hw/riscv: Move sifive_clint model to hw/intc
44
hw/riscv: Move sifive_plic model to hw/intc
45
hw/riscv: Move riscv_htif model to hw/char
46
hw/riscv: Move sifive_uart model to hw/char
47
hw/riscv: Move sifive_test model to hw/misc
48
hw/riscv: Always build riscv_hart.c
49
hw/riscv: Drop CONFIG_SIFIVE
50
hw/riscv: Sort the Kconfig options in alphabetical order
51
35
52
Nathan Chancellor (1):
36
Atish Patra (1):
53
riscv: sifive_test: Allow 16-bit writes to memory region
37
hw/riscv: virt: Remove the redundant ipi-id property
54
38
55
Yifei Jiang (1):
39
Bin Meng (20):
56
target/riscv: Fix bug in getting trap cause name for trace_riscv_trap
40
target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()
41
target/riscv: Fix mret exception cause when no pmp rule is configured
42
target/riscv: Simplify helper_sret() a little bit
43
target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+
44
hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC
45
hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers
46
hw/riscv: Fix opentitan dependency to SIFIVE_PLIC
47
hw/riscv: Sort machines Kconfig options in alphabetical order
48
hw/riscv: spike: Remove misleading comments
49
hw/intc: sifive_plic: Drop PLICMode_H
50
hw/intc: sifive_plic: Improve robustness of the PLIC config parser
51
hw/intc: sifive_plic: Use error_setg() to propagate the error up via errp in sifive_plic_realize()
52
hw/intc: sifive_plic: Update "num-sources" property default value
53
hw/riscv: microchip_pfsoc: Fix the number of interrupt sources of PLIC
54
hw/riscv: sifive_e: Fix the number of interrupt sources of PLIC
55
hw/riscv: sifive_u: Avoid using magic number for "riscv, ndev"
56
hw/riscv: virt: Fix the value of "riscv, ndev" in the dtb
57
hw/intc: sifive_plic: Change "priority-base" to start from interrupt source 0
58
hw/riscv: opentitan: Drop "hartid-base" and "priority-base" initialization
59
hw/intc: sifive_plic: Fix the pending register range check
57
60
58
default-configs/riscv64-softmmu.mak | 1 +
61
Christoph Muellner (1):
59
{include/hw/riscv => hw/intc}/sifive_plic.h | 0
62
RISC-V: Add Zawrs ISA extension support
60
hw/riscv/trace.h | 1 -
61
include/hw/char/mchp_pfsoc_mmuart.h | 61 ++++
62
include/hw/{riscv => char}/riscv_htif.h | 0
63
include/hw/{riscv => char}/sifive_uart.h | 0
64
include/hw/dma/sifive_pdma.h | 57 ++++
65
include/hw/{riscv => gpio}/sifive_gpio.h | 0
66
include/hw/{riscv => intc}/sifive_clint.h | 4 +-
67
include/hw/{riscv => misc}/sifive_e_prci.h | 0
68
include/hw/{riscv => misc}/sifive_test.h | 0
69
include/hw/{riscv => misc}/sifive_u_otp.h | 0
70
include/hw/{riscv => misc}/sifive_u_prci.h | 0
71
include/hw/net/cadence_gem.h | 2 +
72
include/hw/riscv/microchip_pfsoc.h | 133 +++++++++
73
include/hw/riscv/riscv_hart.h | 1 +
74
include/hw/riscv/sifive_e.h | 2 +-
75
include/hw/riscv/sifive_u.h | 17 +-
76
include/hw/sd/cadence_sdhci.h | 47 +++
77
target/riscv/cpu.h | 8 +-
78
hw/arm/xilinx_zynq.c | 1 +
79
hw/arm/xlnx-versal.c | 1 +
80
hw/arm/xlnx-zynqmp.c | 2 +
81
hw/char/mchp_pfsoc_mmuart.c | 86 ++++++
82
hw/{riscv => char}/riscv_htif.c | 2 +-
83
hw/{riscv => char}/sifive_uart.c | 2 +-
84
hw/dma/sifive_pdma.c | 313 ++++++++++++++++++++
85
hw/{riscv => gpio}/sifive_gpio.c | 2 +-
86
hw/{riscv => intc}/sifive_clint.c | 28 +-
87
hw/{riscv => intc}/sifive_plic.c | 2 +-
88
hw/{riscv => misc}/sifive_e_prci.c | 2 +-
89
hw/{riscv => misc}/sifive_test.c | 4 +-
90
hw/{riscv => misc}/sifive_u_otp.c | 2 +-
91
hw/{riscv => misc}/sifive_u_prci.c | 2 +-
92
hw/net/cadence_gem.c | 7 +-
93
hw/riscv/microchip_pfsoc.c | 437 ++++++++++++++++++++++++++++
94
hw/riscv/opentitan.c | 1 +
95
hw/riscv/riscv_hart.c | 3 +
96
hw/riscv/sifive_e.c | 12 +-
97
hw/riscv/sifive_u.c | 41 ++-
98
hw/riscv/spike.c | 7 +-
99
hw/riscv/virt.c | 9 +-
100
hw/sd/cadence_sdhci.c | 193 ++++++++++++
101
target/riscv/cpu.c | 19 +-
102
target/riscv/cpu_helper.c | 8 +-
103
target/riscv/csr.c | 4 +-
104
MAINTAINERS | 9 +
105
hw/char/Kconfig | 9 +
106
hw/char/meson.build | 3 +
107
hw/dma/Kconfig | 3 +
108
hw/dma/meson.build | 1 +
109
hw/gpio/Kconfig | 3 +
110
hw/gpio/meson.build | 1 +
111
hw/gpio/trace-events | 6 +
112
hw/intc/Kconfig | 6 +
113
hw/intc/meson.build | 2 +
114
hw/misc/Kconfig | 12 +
115
hw/misc/meson.build | 6 +
116
hw/riscv/Kconfig | 70 +++--
117
hw/riscv/meson.build | 12 +-
118
hw/riscv/trace-events | 7 -
119
hw/sd/Kconfig | 4 +
120
hw/sd/meson.build | 1 +
121
meson.build | 1 -
122
64 files changed, 1575 insertions(+), 105 deletions(-)
123
rename {include/hw/riscv => hw/intc}/sifive_plic.h (100%)
124
delete mode 100644 hw/riscv/trace.h
125
create mode 100644 include/hw/char/mchp_pfsoc_mmuart.h
126
rename include/hw/{riscv => char}/riscv_htif.h (100%)
127
rename include/hw/{riscv => char}/sifive_uart.h (100%)
128
create mode 100644 include/hw/dma/sifive_pdma.h
129
rename include/hw/{riscv => gpio}/sifive_gpio.h (100%)
130
rename include/hw/{riscv => intc}/sifive_clint.h (92%)
131
rename include/hw/{riscv => misc}/sifive_e_prci.h (100%)
132
rename include/hw/{riscv => misc}/sifive_test.h (100%)
133
rename include/hw/{riscv => misc}/sifive_u_otp.h (100%)
134
rename include/hw/{riscv => misc}/sifive_u_prci.h (100%)
135
create mode 100644 include/hw/riscv/microchip_pfsoc.h
136
create mode 100644 include/hw/sd/cadence_sdhci.h
137
create mode 100644 hw/char/mchp_pfsoc_mmuart.c
138
rename hw/{riscv => char}/riscv_htif.c (99%)
139
rename hw/{riscv => char}/sifive_uart.c (99%)
140
create mode 100644 hw/dma/sifive_pdma.c
141
rename hw/{riscv => gpio}/sifive_gpio.c (99%)
142
rename hw/{riscv => intc}/sifive_clint.c (90%)
143
rename hw/{riscv => intc}/sifive_plic.c (99%)
144
rename hw/{riscv => misc}/sifive_e_prci.c (99%)
145
rename hw/{riscv => misc}/sifive_test.c (97%)
146
rename hw/{riscv => misc}/sifive_u_otp.c (99%)
147
rename hw/{riscv => misc}/sifive_u_prci.c (99%)
148
create mode 100644 hw/riscv/microchip_pfsoc.c
149
create mode 100644 hw/sd/cadence_sdhci.c
150
delete mode 100644 hw/riscv/trace-events
151
63
64
Conor Dooley (3):
65
hw/misc: pfsoc: add fabric clocks to ioscb
66
hw/riscv: pfsoc: add missing FICs as unimplemented
67
hw/{misc, riscv}: pfsoc: add system controller as unimplemented
68
69
Frédéric Pétrot (1):
70
hw/intc: sifive_plic: Renumber the S irqs for numa support
71
72
Jim Shu (2):
73
target/riscv: support cache-related PMU events in virtual mode
74
hw/intc: sifive_plic: fix out-of-bound access of source_priority array
75
76
LIU Zhiwei (5):
77
target/riscv: Fix PMP propagation for tlb
78
target/riscv: Add itrigger support when icount is not enabled
79
target/riscv: Add itrigger support when icount is enabled
80
target/riscv: Enable native debug itrigger
81
target/riscv: Add itrigger_enabled field to CPURISCVState
82
83
Mayuresh Chitale (3):
84
target/riscv: Add smstateen support
85
target/riscv: smstateen check for h/s/envcfg
86
target/riscv: generate virtual instruction exception
87
88
Richard Henderson (4):
89
tcg/riscv: Fix range matched by TCG_CT_CONST_M12
90
tcg/riscv: Fix reg overlap case in tcg_out_addsub2
91
tcg/riscv: Fix base register for user-only qemu_ld/st
92
target/riscv: Set pc_succ_insn for !rvc illegal insn
93
94
Wilfred Mallawa (4):
95
hw/registerfields: add `FIELDx_1CLEAR()` macro
96
hw/ssi/ibex_spi: implement `FIELD32_1CLEAR` macro
97
hw/riscv/opentitan: bump opentitan
98
hw/riscv/opentitan: add aon_timer base unimpl
99
100
include/hw/intc/sifive_plic.h | 1 -
101
include/hw/misc/mchp_pfsoc_ioscb.h | 4 +
102
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
103
include/hw/registerfields.h | 22 ++
104
include/hw/riscv/microchip_pfsoc.h | 7 +-
105
include/hw/riscv/opentitan.h | 10 +-
106
include/hw/riscv/shakti_c.h | 2 +-
107
include/hw/riscv/sifive_e.h | 9 +-
108
include/hw/riscv/sifive_u.h | 2 +-
109
include/hw/riscv/virt.h | 8 +-
110
target/riscv/cpu.h | 10 +
111
target/riscv/cpu_bits.h | 37 +++
112
target/riscv/debug.h | 13 +
113
target/riscv/helper.h | 2 +
114
target/riscv/pmp.h | 6 +-
115
target/riscv/insn32.decode | 4 +
116
hw/intc/sifive_plic.c | 66 +++--
117
hw/misc/mchp_pfsoc_ioscb.c | 78 ++++-
118
hw/misc/mchp_pfsoc_sysreg.c | 18 +-
119
hw/riscv/microchip_pfsoc.c | 121 ++++----
120
hw/riscv/opentitan.c | 26 +-
121
hw/riscv/sifive_u.c | 3 +-
122
hw/riscv/spike.c | 1 -
123
hw/riscv/virt.c | 7 +-
124
hw/ssi/ibex_spi_host.c | 21 +-
125
target/riscv/cpu.c | 11 +
126
target/riscv/cpu_helper.c | 26 +-
127
target/riscv/csr.c | 393 ++++++++++++++++++++++++-
128
target/riscv/debug.c | 205 +++++++++++++
129
target/riscv/machine.c | 36 +++
130
target/riscv/op_helper.c | 28 +-
131
target/riscv/pmp.c | 90 ++----
132
target/riscv/translate.c | 54 +++-
133
target/riscv/insn_trans/trans_privileged.c.inc | 4 +-
134
target/riscv/insn_trans/trans_rvi.c.inc | 8 +-
135
target/riscv/insn_trans/trans_rvv.c.inc | 4 +-
136
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 ++++
137
tcg/riscv/tcg-target.c.inc | 68 +++--
138
hw/intc/Kconfig | 3 +
139
hw/riscv/Kconfig | 22 +-
140
tests/tcg/Makefile.target | 2 +
141
tests/tcg/riscv64/Makefile.target | 5 +
142
tests/tcg/riscv64/test-noc.S | 32 ++
143
43 files changed, 1255 insertions(+), 266 deletions(-)
144
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
145
create mode 100644 tests/tcg/riscv64/test-noc.S
diff view generated by jsdifflib
New patch
1
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
3
Only the pmp index that be checked by pmp_hart_has_privs can be used
4
by pmp_get_tlb_size to avoid an error pmp index.
5
6
Before modification, we may use an error pmp index. For example,
7
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
8
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
9
will return true;
10
11
However, this checked pmp index is discarded as pmp_hart_has_privs
12
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
13
rules. The tlb_sa will be 0x0, and tlb_ea will be 0xfff. If there is
14
a pmp rule [0x10, 0x14), it will be misused as it is legal in
15
pmp_get_tlb_size.
16
17
As we have already known the correct pmp index, just remove the
18
remove the pmp_is_range_in_tlb and get tlb size directly from
19
pmp_get_tlb_size.
20
21
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-Id: <20221012060016.30856-1-zhiwei_liu@linux.alibaba.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
target/riscv/pmp.h | 6 +--
27
target/riscv/cpu_helper.c | 16 ++++---
28
target/riscv/pmp.c | 90 +++++++++++++--------------------------
29
3 files changed, 42 insertions(+), 70 deletions(-)
30
31
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/pmp.h
34
+++ b/target/riscv/pmp.h
35
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
36
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
37
target_ulong val);
38
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
39
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
40
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
41
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
42
target_ulong mode);
43
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
44
- target_ulong *tlb_size);
45
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
46
+ target_ulong tlb_sa, target_ulong tlb_ea);
47
void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index);
48
void pmp_update_rule_nums(CPURISCVState *env);
49
uint32_t pmp_get_num_rules(CPURISCVState *env);
50
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/riscv/cpu_helper.c
53
+++ b/target/riscv/cpu_helper.c
54
@@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot,
55
int mode)
56
{
57
pmp_priv_t pmp_priv;
58
- target_ulong tlb_size_pmp = 0;
59
+ int pmp_index = -1;
60
61
if (!riscv_feature(env, RISCV_FEATURE_PMP)) {
62
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
63
return TRANSLATE_SUCCESS;
64
}
65
66
- if (!pmp_hart_has_privs(env, addr, size, 1 << access_type, &pmp_priv,
67
- mode)) {
68
+ pmp_index = pmp_hart_has_privs(env, addr, size, 1 << access_type,
69
+ &pmp_priv, mode);
70
+ if (pmp_index < 0) {
71
*prot = 0;
72
return TRANSLATE_PMP_FAIL;
73
}
74
75
*prot = pmp_priv_to_page_prot(pmp_priv);
76
- if (tlb_size != NULL) {
77
- if (pmp_is_range_in_tlb(env, addr & ~(*tlb_size - 1), &tlb_size_pmp)) {
78
- *tlb_size = tlb_size_pmp;
79
- }
80
+ if ((tlb_size != NULL) && pmp_index != MAX_RISCV_PMPS) {
81
+ target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1);
82
+ target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1;
83
+
84
+ *tlb_size = pmp_get_tlb_size(env, pmp_index, tlb_sa, tlb_ea);
85
}
86
87
return TRANSLATE_SUCCESS;
88
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
89
index XXXXXXX..XXXXXXX 100644
90
--- a/target/riscv/pmp.c
91
+++ b/target/riscv/pmp.c
92
@@ -XXX,XX +XXX,XX @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
93
94
/*
95
* Check if the address has required RWX privs to complete desired operation
96
+ * Return PMP rule index if a pmp rule match
97
+ * Return MAX_RISCV_PMPS if default match
98
+ * Return negtive value if no match
99
*/
100
-bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
101
+int pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
102
target_ulong size, pmp_priv_t privs, pmp_priv_t *allowed_privs,
103
target_ulong mode)
104
{
105
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
106
107
/* Short cut if no rules */
108
if (0 == pmp_get_num_rules(env)) {
109
- return pmp_hart_has_privs_default(env, addr, size, privs,
110
- allowed_privs, mode);
111
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
112
+ allowed_privs, mode)) {
113
+ ret = MAX_RISCV_PMPS;
114
+ }
115
}
116
117
if (size == 0) {
118
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
119
if ((s + e) == 1) {
120
qemu_log_mask(LOG_GUEST_ERROR,
121
"pmp violation - access is partially inside\n");
122
- ret = 0;
123
+ ret = -1;
124
break;
125
}
126
127
@@ -XXX,XX +XXX,XX @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
128
}
129
}
130
131
- ret = ((privs & *allowed_privs) == privs);
132
+ if ((privs & *allowed_privs) == privs) {
133
+ ret = i;
134
+ }
135
break;
136
}
137
}
138
139
/* No rule matched */
140
if (ret == -1) {
141
- return pmp_hart_has_privs_default(env, addr, size, privs,
142
- allowed_privs, mode);
143
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
144
+ allowed_privs, mode)) {
145
+ ret = MAX_RISCV_PMPS;
146
+ }
147
}
148
149
- return ret == 1 ? true : false;
150
+ return ret;
151
}
152
153
/*
154
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
155
* Calculate the TLB size if the start address or the end address of
156
* PMP entry is presented in the TLB page.
157
*/
158
-static target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
159
- target_ulong tlb_sa, target_ulong tlb_ea)
160
+target_ulong pmp_get_tlb_size(CPURISCVState *env, int pmp_index,
161
+ target_ulong tlb_sa, target_ulong tlb_ea)
162
{
163
target_ulong pmp_sa = env->pmp_state.addr[pmp_index].sa;
164
target_ulong pmp_ea = env->pmp_state.addr[pmp_index].ea;
165
166
- if (pmp_sa >= tlb_sa && pmp_ea <= tlb_ea) {
167
- return pmp_ea - pmp_sa + 1;
168
- }
169
-
170
- if (pmp_sa >= tlb_sa && pmp_sa <= tlb_ea && pmp_ea >= tlb_ea) {
171
- return tlb_ea - pmp_sa + 1;
172
- }
173
-
174
- if (pmp_ea <= tlb_ea && pmp_ea >= tlb_sa && pmp_sa <= tlb_sa) {
175
- return pmp_ea - tlb_sa + 1;
176
- }
177
-
178
- return 0;
179
-}
180
-
181
-/*
182
- * Check is there a PMP entry which range covers this page. If so,
183
- * try to find the minimum granularity for the TLB size.
184
- */
185
-bool pmp_is_range_in_tlb(CPURISCVState *env, hwaddr tlb_sa,
186
- target_ulong *tlb_size)
187
-{
188
- int i;
189
- target_ulong val;
190
- target_ulong tlb_ea = (tlb_sa + TARGET_PAGE_SIZE - 1);
191
-
192
- for (i = 0; i < MAX_RISCV_PMPS; i++) {
193
- val = pmp_get_tlb_size(env, i, tlb_sa, tlb_ea);
194
- if (val) {
195
- if (*tlb_size == 0 || *tlb_size > val) {
196
- *tlb_size = val;
197
- }
198
- }
199
- }
200
-
201
- if (*tlb_size != 0) {
202
+ if (pmp_sa <= tlb_sa && pmp_ea >= tlb_ea) {
203
+ return TARGET_PAGE_SIZE;
204
+ } else {
205
/*
206
- * At this point we have a tlb_size that is the smallest possible size
207
- * That fits within a TARGET_PAGE_SIZE and the PMP region.
208
- *
209
- * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
210
- * This means the result isn't cached in the TLB and is only used for
211
- * a single translation.
212
- */
213
- if (*tlb_size < TARGET_PAGE_SIZE) {
214
- *tlb_size = 1;
215
- }
216
-
217
- return true;
218
+ * At this point we have a tlb_size that is the smallest possible size
219
+ * That fits within a TARGET_PAGE_SIZE and the PMP region.
220
+ *
221
+ * If the size is less then TARGET_PAGE_SIZE we drop the size to 1.
222
+ * This means the result isn't cached in the TLB and is only used for
223
+ * a single translation.
224
+ */
225
+ return 1;
226
}
227
-
228
- return false;
229
}
230
231
/*
232
--
233
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
Adds a helper macro that implements the register `w1c`
4
functionality.
5
6
Ex:
7
uint32_t data = FIELD32_1CLEAR(val, REG, FIELD);
8
9
If ANY bits of the specified `FIELD` is set
10
then the respective field is cleared and returned to `data`.
11
12
If the field is cleared (0), then no change and
13
val is returned.
14
15
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20221017054950.317584-2-wilfred.mallawa@opensource.wdc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
20
include/hw/registerfields.h | 22 ++++++++++++++++++++++
21
1 file changed, 22 insertions(+)
22
23
diff --git a/include/hw/registerfields.h b/include/hw/registerfields.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/registerfields.h
26
+++ b/include/hw/registerfields.h
27
@@ -XXX,XX +XXX,XX @@
28
R_ ## reg ## _ ## field ## _LENGTH, _v.v); \
29
_d; })
30
31
+/*
32
+ * Clear the specified field in storage if
33
+ * any field bits are set, else no changes made. Implements
34
+ * single/multi-bit `w1c`
35
+ *
36
+ */
37
+#define FIELD8_1CLEAR(storage, reg, field) \
38
+ (FIELD_EX8(storage, reg, field) ? \
39
+ FIELD_DP8(storage, reg, field, 0x00) : storage)
40
+
41
+#define FIELD16_1CLEAR(storage, reg, field) \
42
+ (FIELD_EX16(storage, reg, field) ? \
43
+ FIELD_DP16(storage, reg, field, 0x00) : storage)
44
+
45
+#define FIELD32_1CLEAR(storage, reg, field) \
46
+ (FIELD_EX32(storage, reg, field) ? \
47
+ FIELD_DP32(storage, reg, field, 0x00) : storage)
48
+
49
+#define FIELD64_1CLEAR(storage, reg, field) \
50
+ (FIELD_EX64(storage, reg, field) ? \
51
+ FIELD_DP64(storage, reg, field, 0x00) : storage)
52
+
53
#define FIELD_SDP8(storage, reg, field, val) ({ \
54
struct { \
55
signed int v:R_ ## reg ## _ ## field ## _LENGTH; \
56
--
57
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
use the `FIELD32_1CLEAR` macro to implement register
4
`rw1c` functionality to `ibex_spi`.
5
6
This change was tested by running the `SPI_HOST` from TockOS.
7
8
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221017054950.317584-3-wilfred.mallawa@opensource.wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/ssi/ibex_spi_host.c | 21 +++++++++------------
14
1 file changed, 9 insertions(+), 12 deletions(-)
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 @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
21
{
22
IbexSPIHostState *s = opaque;
23
uint32_t val32 = val64;
24
- uint32_t shift_mask = 0xff, status = 0, data = 0;
25
+ uint32_t shift_mask = 0xff, status = 0;
26
uint8_t txqd_len;
27
28
trace_ibex_spi_host_write(addr, size, val64);
29
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
30
case IBEX_SPI_HOST_INTR_STATE:
31
/* rw1c status register */
32
if (FIELD_EX32(val32, INTR_STATE, ERROR)) {
33
- data = FIELD_DP32(data, INTR_STATE, ERROR, 0);
34
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, ERROR);
35
}
36
if (FIELD_EX32(val32, INTR_STATE, SPI_EVENT)) {
37
- data = FIELD_DP32(data, INTR_STATE, SPI_EVENT, 0);
38
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], INTR_STATE, SPI_EVENT);
39
}
40
- s->regs[addr] = data;
41
break;
42
case IBEX_SPI_HOST_INTR_ENABLE:
43
s->regs[addr] = val32;
44
@@ -XXX,XX +XXX,XX @@ static void ibex_spi_host_write(void *opaque, hwaddr addr,
45
* When an error occurs, the corresponding bit must be cleared
46
* here before issuing any further commands
47
*/
48
- status = s->regs[addr];
49
/* rw1c status register */
50
if (FIELD_EX32(val32, ERROR_STATUS, CMDBUSY)) {
51
- status = FIELD_DP32(status, ERROR_STATUS, CMDBUSY, 0);
52
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CMDBUSY);
53
}
54
if (FIELD_EX32(val32, ERROR_STATUS, OVERFLOW)) {
55
- status = FIELD_DP32(status, ERROR_STATUS, OVERFLOW, 0);
56
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, OVERFLOW);
57
}
58
if (FIELD_EX32(val32, ERROR_STATUS, UNDERFLOW)) {
59
- status = FIELD_DP32(status, ERROR_STATUS, UNDERFLOW, 0);
60
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, UNDERFLOW);
61
}
62
if (FIELD_EX32(val32, ERROR_STATUS, CMDINVAL)) {
63
- status = FIELD_DP32(status, ERROR_STATUS, CMDINVAL, 0);
64
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CMDINVAL);
65
}
66
if (FIELD_EX32(val32, ERROR_STATUS, CSIDINVAL)) {
67
- status = FIELD_DP32(status, ERROR_STATUS, CSIDINVAL, 0);
68
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, CSIDINVAL);
69
}
70
if (FIELD_EX32(val32, ERROR_STATUS, ACCESSINVAL)) {
71
- status = FIELD_DP32(status, ERROR_STATUS, ACCESSINVAL, 0);
72
+ s->regs[addr] = FIELD32_1CLEAR(s->regs[addr], ERROR_STATUS, ACCESSINVAL);
73
}
74
- s->regs[addr] = status;
75
break;
76
case IBEX_SPI_HOST_EVENT_ENABLE:
77
/* Controls which classes of SPI events raise an interrupt. */
78
--
79
2.38.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
We were matching a signed 13-bit range, not a 12-bit range.
4
Expand the commentary within the function and be explicit
5
about all of the ranges.
6
7
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221022095821.2441874-1-richard.henderson@linaro.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
tcg/riscv/tcg-target.c.inc | 19 ++++++++++++++++---
15
1 file changed, 16 insertions(+), 3 deletions(-)
16
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
20
+++ b/tcg/riscv/tcg-target.c.inc
21
@@ -XXX,XX +XXX,XX @@ static bool tcg_target_const_match(int64_t val, TCGType type, int ct)
22
if ((ct & TCG_CT_CONST_ZERO) && val == 0) {
23
return 1;
24
}
25
- if ((ct & TCG_CT_CONST_S12) && val == sextreg(val, 0, 12)) {
26
+ /*
27
+ * Sign extended from 12 bits: [-0x800, 0x7ff].
28
+ * Used for most arithmetic, as this is the isa field.
29
+ */
30
+ if ((ct & TCG_CT_CONST_S12) && val >= -0x800 && val <= 0x7ff) {
31
return 1;
32
}
33
- if ((ct & TCG_CT_CONST_N12) && -val == sextreg(-val, 0, 12)) {
34
+ /*
35
+ * Sign extended from 12 bits, negated: [-0x7ff, 0x800].
36
+ * Used for subtraction, where a constant must be handled by ADDI.
37
+ */
38
+ if ((ct & TCG_CT_CONST_N12) && val >= -0x7ff && val <= 0x800) {
39
return 1;
40
}
41
- if ((ct & TCG_CT_CONST_M12) && val >= -0xfff && val <= 0xfff) {
42
+ /*
43
+ * Sign extended from 12 bits, +/- matching: [-0x7ff, 0x7ff].
44
+ * Used by addsub2, which may need the negative operation,
45
+ * and requires the modified constant to be representable.
46
+ */
47
+ if ((ct & TCG_CT_CONST_M12) && val >= -0x7ff && val <= 0x7ff) {
48
return 1;
49
}
50
return 0;
51
--
52
2.38.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
There was a typo using opc_addi instead of opc_add with the
4
two registers. While we're at it, simplify the gating test
5
to al == bl to improve dynamic scheduling even when the
6
output register does not overlap the inputs.
7
8
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221020233836.2341671-1-richard.henderson@linaro.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
tcg/riscv/tcg-target.c.inc | 10 ++++++++--
15
1 file changed, 8 insertions(+), 2 deletions(-)
16
17
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tcg/riscv/tcg-target.c.inc
20
+++ b/tcg/riscv/tcg-target.c.inc
21
@@ -XXX,XX +XXX,XX @@ static void tcg_out_addsub2(TCGContext *s,
22
if (cbl) {
23
tcg_out_opc_imm(s, opc_addi, rl, al, bl);
24
tcg_out_opc_imm(s, OPC_SLTIU, TCG_REG_TMP0, rl, bl);
25
- } else if (rl == al && rl == bl) {
26
+ } else if (al == bl) {
27
+ /*
28
+ * If the input regs overlap, this is a simple doubling
29
+ * and carry-out is the input msb. This special case is
30
+ * required when the output reg overlaps the input,
31
+ * but we might as well use it always.
32
+ */
33
tcg_out_opc_imm(s, OPC_SLTI, TCG_REG_TMP0, al, 0);
34
- tcg_out_opc_reg(s, opc_addi, rl, al, bl);
35
+ tcg_out_opc_reg(s, opc_add, rl, al, al);
36
} else {
37
tcg_out_opc_reg(s, opc_add, rl, al, bl);
38
tcg_out_opc_reg(s, OPC_SLTU, TCG_REG_TMP0,
39
--
40
2.38.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
When guest_base != 0, we were not coordinating the usage of
4
TCG_REG_TMP0 as base properly, leading to a previous zero-extend
5
of the input address being discarded.
6
7
Shuffle the alignment check to the front, because that does not
8
depend on the zero-extend, and it keeps the register usage clear.
9
Set base after each step of the address arithmetic instead of before.
10
11
Return the base register used from tcg_out_tlb_load, so as to
12
keep that register choice localized to that function.
13
14
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Message-Id: <20221023233337.2846860-1-richard.henderson@linaro.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
21
tcg/riscv/tcg-target.c.inc | 39 +++++++++++++++++++++-----------------
22
1 file changed, 22 insertions(+), 17 deletions(-)
23
24
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
25
index XXXXXXX..XXXXXXX 100644
26
--- a/tcg/riscv/tcg-target.c.inc
27
+++ b/tcg/riscv/tcg-target.c.inc
28
@@ -XXX,XX +XXX,XX @@ static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
29
tcg_debug_assert(ok);
30
}
31
32
-static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
33
- TCGReg addrh, MemOpIdx oi,
34
- tcg_insn_unit **label_ptr, bool is_load)
35
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
36
+ TCGReg addrh, MemOpIdx oi,
37
+ tcg_insn_unit **label_ptr, bool is_load)
38
{
39
MemOp opc = get_memop(oi);
40
unsigned s_bits = opc & MO_SIZE;
41
@@ -XXX,XX +XXX,XX @@ static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
42
addrl = TCG_REG_TMP0;
43
}
44
tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_REG_TMP2, addrl);
45
+ return TCG_REG_TMP0;
46
}
47
48
static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
49
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
50
#else
51
unsigned a_bits;
52
#endif
53
- TCGReg base = TCG_REG_TMP0;
54
+ TCGReg base;
55
56
data_regl = *args++;
57
data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
58
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, bool is_64)
59
opc = get_memop(oi);
60
61
#if defined(CONFIG_SOFTMMU)
62
- tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
63
+ base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 1);
64
tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
65
add_qemu_ldst_label(s, 1, oi,
66
(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
67
data_regl, data_regh, addr_regl, addr_regh,
68
s->code_ptr, label_ptr);
69
#else
70
- if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
71
- tcg_out_ext32u(s, base, addr_regl);
72
- addr_regl = base;
73
- }
74
a_bits = get_alignment_bits(opc);
75
if (a_bits) {
76
tcg_out_test_alignment(s, true, addr_regl, a_bits);
77
}
78
+ base = addr_regl;
79
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
80
+ tcg_out_ext32u(s, TCG_REG_TMP0, base);
81
+ base = TCG_REG_TMP0;
82
+ }
83
if (guest_base != 0) {
84
- tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
85
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
86
+ base = TCG_REG_TMP0;
87
}
88
tcg_out_qemu_ld_direct(s, data_regl, data_regh, base, opc, is_64);
89
#endif
90
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
91
#else
92
unsigned a_bits;
93
#endif
94
- TCGReg base = TCG_REG_TMP0;
95
+ TCGReg base;
96
97
data_regl = *args++;
98
data_regh = (TCG_TARGET_REG_BITS == 32 && is_64 ? *args++ : 0);
99
@@ -XXX,XX +XXX,XX @@ static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, bool is_64)
100
opc = get_memop(oi);
101
102
#if defined(CONFIG_SOFTMMU)
103
- tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
104
+ base = tcg_out_tlb_load(s, addr_regl, addr_regh, oi, label_ptr, 0);
105
tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
106
add_qemu_ldst_label(s, 0, oi,
107
(is_64 ? TCG_TYPE_I64 : TCG_TYPE_I32),
108
data_regl, data_regh, addr_regl, addr_regh,
109
s->code_ptr, label_ptr);
110
#else
111
- if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
112
- tcg_out_ext32u(s, base, addr_regl);
113
- addr_regl = base;
114
- }
115
a_bits = get_alignment_bits(opc);
116
if (a_bits) {
117
tcg_out_test_alignment(s, false, addr_regl, a_bits);
118
}
119
+ base = addr_regl;
120
+ if (TCG_TARGET_REG_BITS > TARGET_LONG_BITS) {
121
+ tcg_out_ext32u(s, TCG_REG_TMP0, base);
122
+ base = TCG_REG_TMP0;
123
+ }
124
if (guest_base != 0) {
125
- tcg_out_opc_reg(s, OPC_ADD, base, TCG_GUEST_BASE_REG, addr_regl);
126
+ tcg_out_opc_reg(s, OPC_ADD, TCG_REG_TMP0, TCG_GUEST_BASE_REG, base);
127
+ base = TCG_REG_TMP0;
128
}
129
tcg_out_qemu_st_direct(s, data_regl, data_regh, base, opc);
130
#endif
131
--
132
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
This patch updates the OpenTitan model to match
4
the specified register layout as per [1]. Which is also the latest
5
commit of OpenTitan supported by TockOS.
6
7
Note: Pinmux and Padctrl has been merged into Pinmux [2][3], this patch removes
8
any references to Padctrl. Note: OpenTitan doc [2] has not yet specified
9
much detail regarding this, except for a note that states `TODO: this
10
section needs to be updated to reflect the pinmux/padctrl merger`
11
12
[1] https://github.com/lowRISC/opentitan/blob/d072ac505f82152678d6e04be95c72b728a347b8/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
13
[2] https://docs.opentitan.org/hw/top_earlgrey/doc/design/
14
[3] https://docs.opentitan.org/hw/ip/pinmux/doc/#overview
15
16
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
19
Message-Id: <20221025043335.339815-2-wilfred.mallawa@opensource.wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
include/hw/riscv/opentitan.h | 9 ++++-----
23
hw/riscv/opentitan.c | 21 +++++++++++++--------
24
2 files changed, 17 insertions(+), 13 deletions(-)
25
26
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/riscv/opentitan.h
29
+++ b/include/hw/riscv/opentitan.h
30
@@ -XXX,XX +XXX,XX @@ enum {
31
IBEX_DEV_RSTMGR,
32
IBEX_DEV_CLKMGR,
33
IBEX_DEV_PINMUX,
34
- IBEX_DEV_PADCTRL,
35
IBEX_DEV_USBDEV,
36
IBEX_DEV_FLASH_CTRL,
37
IBEX_DEV_PLIC,
38
@@ -XXX,XX +XXX,XX @@ enum {
39
IBEX_UART0_RX_TIMEOUT_IRQ = 7,
40
IBEX_UART0_RX_PARITY_ERR_IRQ = 8,
41
IBEX_TIMER_TIMEREXPIRED0_0 = 127,
42
- IBEX_SPI_HOST0_ERR_IRQ = 151,
43
- IBEX_SPI_HOST0_SPI_EVENT_IRQ = 152,
44
- IBEX_SPI_HOST1_ERR_IRQ = 153,
45
- IBEX_SPI_HOST1_SPI_EVENT_IRQ = 154,
46
+ IBEX_SPI_HOST0_ERR_IRQ = 134,
47
+ IBEX_SPI_HOST0_SPI_EVENT_IRQ = 135,
48
+ IBEX_SPI_HOST1_ERR_IRQ = 136,
49
+ IBEX_SPI_HOST1_SPI_EVENT_IRQ = 137,
50
};
51
52
#endif
53
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
54
index XXXXXXX..XXXXXXX 100644
55
--- a/hw/riscv/opentitan.c
56
+++ b/hw/riscv/opentitan.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "qemu/units.h"
59
#include "sysemu/sysemu.h"
60
61
+/*
62
+ * This version of the OpenTitan machine currently supports
63
+ * OpenTitan RTL version:
64
+ * <lowRISC/opentitan@d072ac505f82152678d6e04be95c72b728a347b8>
65
+ *
66
+ * MMIO mapping as per (specified commit):
67
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
68
+ */
69
static const MemMapEntry ibex_memmap[] = {
70
- [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
71
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
72
[IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
73
[IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
74
[IBEX_DEV_UART] = { 0x40000000, 0x1000 },
75
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
76
[IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
77
[IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
78
[IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
79
- [IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
80
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
81
[IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
82
- [IBEX_DEV_USBDEV] = { 0x40150000, 0x1000 },
83
+ [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x1000 },
84
[IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
85
[IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
86
+ [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
87
[IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
88
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
89
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
90
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
91
- [IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
92
+ [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
93
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
94
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
95
[IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
96
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
97
[IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
98
[IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
99
[IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
100
- [IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
101
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
102
[IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
103
- [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
104
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
105
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
106
};
107
108
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
109
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
110
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
111
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
112
- create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
113
- memmap[IBEX_DEV_PADCTRL].base, memmap[IBEX_DEV_PADCTRL].size);
114
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
115
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
116
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
117
--
118
2.38.1
diff view generated by jsdifflib
New patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
2
3
Adds the updated `aon_timer` base as an unimplemented device. This is
4
used by TockOS, patch ensures the guest doesn't hit load faults.
5
6
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221025043335.339815-3-wilfred.mallawa@opensource.wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
include/hw/riscv/opentitan.h | 1 +
13
hw/riscv/opentitan.c | 3 +++
14
2 files changed, 4 insertions(+)
15
16
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/riscv/opentitan.h
19
+++ b/include/hw/riscv/opentitan.h
20
@@ -XXX,XX +XXX,XX @@ enum {
21
IBEX_DEV_RSTMGR,
22
IBEX_DEV_CLKMGR,
23
IBEX_DEV_PINMUX,
24
+ IBEX_DEV_AON_TIMER,
25
IBEX_DEV_USBDEV,
26
IBEX_DEV_FLASH_CTRL,
27
IBEX_DEV_PLIC,
28
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/riscv/opentitan.c
31
+++ b/hw/riscv/opentitan.c
32
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
33
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
34
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
35
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
36
+ [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x1000 },
37
[IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
38
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
39
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
40
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
41
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
42
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
43
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
44
+ create_unimplemented_device("riscv.lowrisc.ibex.aon_timer",
45
+ memmap[IBEX_DEV_AON_TIMER].base, memmap[IBEX_DEV_AON_TIMER].size);
46
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
47
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
48
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
49
--
50
2.38.1
diff view generated by jsdifflib
New patch
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
2
3
Smstateen extension specifies a mechanism to close
4
the potential covert channels that could cause security issues.
5
6
This patch adds the CSRs defined in the specification and
7
the corresponding predicates and read/write functions.
8
9
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-Id: <20221016124726.102129-2-mchitale@ventanamicro.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/cpu.h | 4 +
16
target/riscv/cpu_bits.h | 37 +++++
17
target/riscv/csr.c | 316 ++++++++++++++++++++++++++++++++++++++++
18
target/riscv/machine.c | 21 +++
19
4 files changed, 378 insertions(+)
20
21
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu.h
24
+++ b/target/riscv/cpu.h
25
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
26
27
/* CSRs for execution enviornment configuration */
28
uint64_t menvcfg;
29
+ uint64_t mstateen[SMSTATEEN_MAX_COUNT];
30
+ uint64_t hstateen[SMSTATEEN_MAX_COUNT];
31
+ uint64_t sstateen[SMSTATEEN_MAX_COUNT];
32
target_ulong senvcfg;
33
uint64_t henvcfg;
34
#endif
35
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
36
bool ext_ifencei;
37
bool ext_icsr;
38
bool ext_zihintpause;
39
+ bool ext_smstateen;
40
bool ext_sstc;
41
bool ext_svinval;
42
bool ext_svnapot;
43
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu_bits.h
46
+++ b/target/riscv/cpu_bits.h
47
@@ -XXX,XX +XXX,XX @@
48
/* Supervisor Configuration CSRs */
49
#define CSR_SENVCFG 0x10A
50
51
+/* Supervisor state CSRs */
52
+#define CSR_SSTATEEN0 0x10C
53
+#define CSR_SSTATEEN1 0x10D
54
+#define CSR_SSTATEEN2 0x10E
55
+#define CSR_SSTATEEN3 0x10F
56
+
57
/* Supervisor Trap Handling */
58
#define CSR_SSCRATCH 0x140
59
#define CSR_SEPC 0x141
60
@@ -XXX,XX +XXX,XX @@
61
#define CSR_HENVCFG 0x60A
62
#define CSR_HENVCFGH 0x61A
63
64
+/* Hypervisor state CSRs */
65
+#define CSR_HSTATEEN0 0x60C
66
+#define CSR_HSTATEEN0H 0x61C
67
+#define CSR_HSTATEEN1 0x60D
68
+#define CSR_HSTATEEN1H 0x61D
69
+#define CSR_HSTATEEN2 0x60E
70
+#define CSR_HSTATEEN2H 0x61E
71
+#define CSR_HSTATEEN3 0x60F
72
+#define CSR_HSTATEEN3H 0x61F
73
+
74
/* Virtual CSRs */
75
#define CSR_VSSTATUS 0x200
76
#define CSR_VSIE 0x204
77
@@ -XXX,XX +XXX,XX @@
78
#define CSR_MENVCFG 0x30A
79
#define CSR_MENVCFGH 0x31A
80
81
+/* Machine state CSRs */
82
+#define CSR_MSTATEEN0 0x30C
83
+#define CSR_MSTATEEN0H 0x31C
84
+#define CSR_MSTATEEN1 0x30D
85
+#define CSR_MSTATEEN1H 0x31D
86
+#define CSR_MSTATEEN2 0x30E
87
+#define CSR_MSTATEEN2H 0x31E
88
+#define CSR_MSTATEEN3 0x30F
89
+#define CSR_MSTATEEN3H 0x31F
90
+
91
+/* Common defines for all smstateen */
92
+#define SMSTATEEN_MAX_COUNT 4
93
+#define SMSTATEEN0_CS (1ULL << 0)
94
+#define SMSTATEEN0_FCSR (1ULL << 1)
95
+#define SMSTATEEN0_HSCONTXT (1ULL << 57)
96
+#define SMSTATEEN0_IMSIC (1ULL << 58)
97
+#define SMSTATEEN0_AIA (1ULL << 59)
98
+#define SMSTATEEN0_SVSLCT (1ULL << 60)
99
+#define SMSTATEEN0_HSENVCFG (1ULL << 62)
100
+#define SMSTATEEN_STATEEN (1ULL << 63)
101
+
102
/* Enhanced Physical Memory Protection (ePMP) */
103
#define CSR_MSECCFG 0x747
104
#define CSR_MSECCFGH 0x757
105
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
106
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/csr.c
108
+++ b/target/riscv/csr.c
109
@@ -XXX,XX +XXX,XX @@ static RISCVException umode32(CPURISCVState *env, int csrno)
110
return umode(env, csrno);
111
}
112
113
+static RISCVException mstateen(CPURISCVState *env, int csrno)
114
+{
115
+ CPUState *cs = env_cpu(env);
116
+ RISCVCPU *cpu = RISCV_CPU(cs);
117
+
118
+ if (!cpu->cfg.ext_smstateen) {
119
+ return RISCV_EXCP_ILLEGAL_INST;
120
+ }
121
+
122
+ return any(env, csrno);
123
+}
124
+
125
+static RISCVException hstateen_pred(CPURISCVState *env, int csrno, int base)
126
+{
127
+ CPUState *cs = env_cpu(env);
128
+ RISCVCPU *cpu = RISCV_CPU(cs);
129
+
130
+ if (!cpu->cfg.ext_smstateen) {
131
+ return RISCV_EXCP_ILLEGAL_INST;
132
+ }
133
+
134
+ if (env->priv < PRV_M) {
135
+ if (!(env->mstateen[csrno - base] & SMSTATEEN_STATEEN)) {
136
+ return RISCV_EXCP_ILLEGAL_INST;
137
+ }
138
+ }
139
+
140
+ return hmode(env, csrno);
141
+}
142
+
143
+static RISCVException hstateen(CPURISCVState *env, int csrno)
144
+{
145
+ return hstateen_pred(env, csrno, CSR_HSTATEEN0);
146
+}
147
+
148
+static RISCVException hstateenh(CPURISCVState *env, int csrno)
149
+{
150
+ return hstateen_pred(env, csrno, CSR_HSTATEEN0H);
151
+}
152
+
153
+static RISCVException sstateen(CPURISCVState *env, int csrno)
154
+{
155
+ bool virt = riscv_cpu_virt_enabled(env);
156
+ int index = csrno - CSR_SSTATEEN0;
157
+ CPUState *cs = env_cpu(env);
158
+ RISCVCPU *cpu = RISCV_CPU(cs);
159
+
160
+ if (!cpu->cfg.ext_smstateen) {
161
+ return RISCV_EXCP_ILLEGAL_INST;
162
+ }
163
+
164
+ if (env->priv < PRV_M) {
165
+ if (!(env->mstateen[index] & SMSTATEEN_STATEEN)) {
166
+ return RISCV_EXCP_ILLEGAL_INST;
167
+ }
168
+
169
+ if (virt) {
170
+ if (!(env->hstateen[index] & SMSTATEEN_STATEEN)) {
171
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
172
+ }
173
+ }
174
+ }
175
+
176
+ return smode(env, csrno);
177
+}
178
+
179
/* Checks if PointerMasking registers could be accessed */
180
static RISCVException pointer_masking(CPURISCVState *env, int csrno)
181
{
182
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
183
return RISCV_EXCP_NONE;
184
}
185
186
+static RISCVException read_mstateen(CPURISCVState *env, int csrno,
187
+ target_ulong *val)
188
+{
189
+ *val = env->mstateen[csrno - CSR_MSTATEEN0];
190
+
191
+ return RISCV_EXCP_NONE;
192
+}
193
+
194
+static RISCVException write_mstateen(CPURISCVState *env, int csrno,
195
+ uint64_t wr_mask, target_ulong new_val)
196
+{
197
+ uint64_t *reg;
198
+
199
+ reg = &env->mstateen[csrno - CSR_MSTATEEN0];
200
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
201
+
202
+ return RISCV_EXCP_NONE;
203
+}
204
+
205
+static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
206
+ target_ulong new_val)
207
+{
208
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
209
+
210
+ return write_mstateen(env, csrno, wr_mask, new_val);
211
+}
212
+
213
+static RISCVException write_mstateen_1_3(CPURISCVState *env, int csrno,
214
+ target_ulong new_val)
215
+{
216
+ return write_mstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
217
+}
218
+
219
+static RISCVException read_mstateenh(CPURISCVState *env, int csrno,
220
+ target_ulong *val)
221
+{
222
+ *val = env->mstateen[csrno - CSR_MSTATEEN0H] >> 32;
223
+
224
+ return RISCV_EXCP_NONE;
225
+}
226
+
227
+static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
228
+ uint64_t wr_mask, target_ulong new_val)
229
+{
230
+ uint64_t *reg, val;
231
+
232
+ reg = &env->mstateen[csrno - CSR_MSTATEEN0H];
233
+ val = (uint64_t)new_val << 32;
234
+ val |= *reg & 0xFFFFFFFF;
235
+ *reg = (*reg & ~wr_mask) | (val & wr_mask);
236
+
237
+ return RISCV_EXCP_NONE;
238
+}
239
+
240
+static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
241
+ target_ulong new_val)
242
+{
243
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
244
+
245
+ return write_mstateenh(env, csrno, wr_mask, new_val);
246
+}
247
+
248
+static RISCVException write_mstateenh_1_3(CPURISCVState *env, int csrno,
249
+ target_ulong new_val)
250
+{
251
+ return write_mstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
252
+}
253
+
254
+static RISCVException read_hstateen(CPURISCVState *env, int csrno,
255
+ target_ulong *val)
256
+{
257
+ int index = csrno - CSR_HSTATEEN0;
258
+
259
+ *val = env->hstateen[index] & env->mstateen[index];
260
+
261
+ return RISCV_EXCP_NONE;
262
+}
263
+
264
+static RISCVException write_hstateen(CPURISCVState *env, int csrno,
265
+ uint64_t mask, target_ulong new_val)
266
+{
267
+ int index = csrno - CSR_HSTATEEN0;
268
+ uint64_t *reg, wr_mask;
269
+
270
+ reg = &env->hstateen[index];
271
+ wr_mask = env->mstateen[index] & mask;
272
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
273
+
274
+ return RISCV_EXCP_NONE;
275
+}
276
+
277
+static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
278
+ target_ulong new_val)
279
+{
280
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
281
+
282
+ return write_hstateen(env, csrno, wr_mask, new_val);
283
+}
284
+
285
+static RISCVException write_hstateen_1_3(CPURISCVState *env, int csrno,
286
+ target_ulong new_val)
287
+{
288
+ return write_hstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
289
+}
290
+
291
+static RISCVException read_hstateenh(CPURISCVState *env, int csrno,
292
+ target_ulong *val)
293
+{
294
+ int index = csrno - CSR_HSTATEEN0H;
295
+
296
+ *val = (env->hstateen[index] >> 32) & (env->mstateen[index] >> 32);
297
+
298
+ return RISCV_EXCP_NONE;
299
+}
300
+
301
+static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
302
+ uint64_t mask, target_ulong new_val)
303
+{
304
+ int index = csrno - CSR_HSTATEEN0H;
305
+ uint64_t *reg, wr_mask, val;
306
+
307
+ reg = &env->hstateen[index];
308
+ val = (uint64_t)new_val << 32;
309
+ val |= *reg & 0xFFFFFFFF;
310
+ wr_mask = env->mstateen[index] & mask;
311
+ *reg = (*reg & ~wr_mask) | (val & wr_mask);
312
+
313
+ return RISCV_EXCP_NONE;
314
+}
315
+
316
+static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
317
+ target_ulong new_val)
318
+{
319
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
320
+
321
+ return write_hstateenh(env, csrno, wr_mask, new_val);
322
+}
323
+
324
+static RISCVException write_hstateenh_1_3(CPURISCVState *env, int csrno,
325
+ target_ulong new_val)
326
+{
327
+ return write_hstateenh(env, csrno, SMSTATEEN_STATEEN, new_val);
328
+}
329
+
330
+static RISCVException read_sstateen(CPURISCVState *env, int csrno,
331
+ target_ulong *val)
332
+{
333
+ bool virt = riscv_cpu_virt_enabled(env);
334
+ int index = csrno - CSR_SSTATEEN0;
335
+
336
+ *val = env->sstateen[index] & env->mstateen[index];
337
+ if (virt) {
338
+ *val &= env->hstateen[index];
339
+ }
340
+
341
+ return RISCV_EXCP_NONE;
342
+}
343
+
344
+static RISCVException write_sstateen(CPURISCVState *env, int csrno,
345
+ uint64_t mask, target_ulong new_val)
346
+{
347
+ bool virt = riscv_cpu_virt_enabled(env);
348
+ int index = csrno - CSR_SSTATEEN0;
349
+ uint64_t wr_mask;
350
+ uint64_t *reg;
351
+
352
+ wr_mask = env->mstateen[index] & mask;
353
+ if (virt) {
354
+ wr_mask &= env->hstateen[index];
355
+ }
356
+
357
+ reg = &env->sstateen[index];
358
+ *reg = (*reg & ~wr_mask) | (new_val & wr_mask);
359
+
360
+ return RISCV_EXCP_NONE;
361
+}
362
+
363
+static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
364
+ target_ulong new_val)
365
+{
366
+ uint64_t wr_mask = SMSTATEEN_STATEEN;
367
+
368
+ return write_sstateen(env, csrno, wr_mask, new_val);
369
+}
370
+
371
+static RISCVException write_sstateen_1_3(CPURISCVState *env, int csrno,
372
+ target_ulong new_val)
373
+{
374
+ return write_sstateen(env, csrno, SMSTATEEN_STATEEN, new_val);
375
+}
376
+
377
static RISCVException rmw_mip64(CPURISCVState *env, int csrno,
378
uint64_t *ret_val,
379
uint64_t new_val, uint64_t wr_mask)
380
@@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
381
[CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh,
382
.min_priv_ver = PRIV_VERSION_1_12_0 },
383
384
+ /* Smstateen extension CSRs */
385
+ [CSR_MSTATEEN0] = { "mstateen0", mstateen, read_mstateen, write_mstateen0,
386
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
387
+ [CSR_MSTATEEN0H] = { "mstateen0h", mstateen, read_mstateenh,
388
+ write_mstateen0h,
389
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
390
+ [CSR_MSTATEEN1] = { "mstateen1", mstateen, read_mstateen,
391
+ write_mstateen_1_3,
392
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
393
+ [CSR_MSTATEEN1H] = { "mstateen1h", mstateen, read_mstateenh,
394
+ write_mstateenh_1_3,
395
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
396
+ [CSR_MSTATEEN2] = { "mstateen2", mstateen, read_mstateen,
397
+ write_mstateen_1_3,
398
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
399
+ [CSR_MSTATEEN2H] = { "mstateen2h", mstateen, read_mstateenh,
400
+ write_mstateenh_1_3,
401
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
402
+ [CSR_MSTATEEN3] = { "mstateen3", mstateen, read_mstateen,
403
+ write_mstateen_1_3,
404
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
405
+ [CSR_MSTATEEN3H] = { "mstateen3h", mstateen, read_mstateenh,
406
+ write_mstateenh_1_3,
407
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
408
+ [CSR_HSTATEEN0] = { "hstateen0", hstateen, read_hstateen, write_hstateen0,
409
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
410
+ [CSR_HSTATEEN0H] = { "hstateen0h", hstateenh, read_hstateenh,
411
+ write_hstateen0h,
412
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
413
+ [CSR_HSTATEEN1] = { "hstateen1", hstateen, read_hstateen,
414
+ write_hstateen_1_3,
415
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
416
+ [CSR_HSTATEEN1H] = { "hstateen1h", hstateenh, read_hstateenh,
417
+ write_hstateenh_1_3,
418
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
419
+ [CSR_HSTATEEN2] = { "hstateen2", hstateen, read_hstateen,
420
+ write_hstateen_1_3,
421
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
422
+ [CSR_HSTATEEN2H] = { "hstateen2h", hstateenh, read_hstateenh,
423
+ write_hstateenh_1_3,
424
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
425
+ [CSR_HSTATEEN3] = { "hstateen3", hstateen, read_hstateen,
426
+ write_hstateen_1_3,
427
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
428
+ [CSR_HSTATEEN3H] = { "hstateen3h", hstateenh, read_hstateenh,
429
+ write_hstateenh_1_3,
430
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
431
+ [CSR_SSTATEEN0] = { "sstateen0", sstateen, read_sstateen, write_sstateen0,
432
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
433
+ [CSR_SSTATEEN1] = { "sstateen1", sstateen, read_sstateen,
434
+ write_sstateen_1_3,
435
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
436
+ [CSR_SSTATEEN2] = { "sstateen2", sstateen, read_sstateen,
437
+ write_sstateen_1_3,
438
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
439
+ [CSR_SSTATEEN3] = { "sstateen3", sstateen, read_sstateen,
440
+ write_sstateen_1_3,
441
+ .min_priv_ver = PRIV_VERSION_1_12_0 },
442
+
443
/* Supervisor Trap Setup */
444
[CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus,
445
NULL, read_sstatus_i128 },
446
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
447
index XXXXXXX..XXXXXXX 100644
448
--- a/target/riscv/machine.c
449
+++ b/target/riscv/machine.c
450
@@ -XXX,XX +XXX,XX @@ static int riscv_cpu_post_load(void *opaque, int version_id)
451
return 0;
452
}
453
454
+static bool smstateen_needed(void *opaque)
455
+{
456
+ RISCVCPU *cpu = opaque;
457
+
458
+ return cpu->cfg.ext_smstateen;
459
+}
460
+
461
+static const VMStateDescription vmstate_smstateen = {
462
+ .name = "cpu/smtateen",
463
+ .version_id = 1,
464
+ .minimum_version_id = 1,
465
+ .needed = smstateen_needed,
466
+ .fields = (VMStateField[]) {
467
+ VMSTATE_UINT64_ARRAY(env.mstateen, RISCVCPU, 4),
468
+ VMSTATE_UINT64_ARRAY(env.hstateen, RISCVCPU, 4),
469
+ VMSTATE_UINT64_ARRAY(env.sstateen, RISCVCPU, 4),
470
+ VMSTATE_END_OF_LIST()
471
+ }
472
+};
473
+
474
static bool envcfg_needed(void *opaque)
475
{
476
RISCVCPU *cpu = opaque;
477
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = {
478
&vmstate_kvmtimer,
479
&vmstate_envcfg,
480
&vmstate_debug,
481
+ &vmstate_smstateen,
482
NULL
483
}
484
};
485
--
486
2.38.1
diff view generated by jsdifflib
New patch
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
2
3
Accesses to henvcfg, henvcfgh and senvcfg are allowed only if the corresponding
4
bit in mstateen0/hstateen0 is enabled. Otherwise an illegal instruction trap is
5
generated.
6
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
8
Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221016124726.102129-3-mchitale@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/csr.c | 87 ++++++++++++++++++++++++++++++++++++++++++----
14
1 file changed, 80 insertions(+), 7 deletions(-)
15
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
19
+++ b/target/riscv/csr.c
20
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
21
}
22
23
/* Predicates */
24
+#if !defined(CONFIG_USER_ONLY)
25
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
26
+ uint64_t bit)
27
+{
28
+ bool virt = riscv_cpu_virt_enabled(env);
29
+ CPUState *cs = env_cpu(env);
30
+ RISCVCPU *cpu = RISCV_CPU(cs);
31
+
32
+ if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
33
+ return RISCV_EXCP_NONE;
34
+ }
35
+
36
+ if (!(env->mstateen[index] & bit)) {
37
+ return RISCV_EXCP_ILLEGAL_INST;
38
+ }
39
+
40
+ if (virt) {
41
+ if (!(env->hstateen[index] & bit)) {
42
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
43
+ }
44
+
45
+ if (env->priv == PRV_U && !(env->sstateen[index] & bit)) {
46
+ return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
47
+ }
48
+ }
49
+
50
+ if (env->priv == PRV_U && riscv_has_ext(env, RVS)) {
51
+ if (!(env->sstateen[index] & bit)) {
52
+ return RISCV_EXCP_ILLEGAL_INST;
53
+ }
54
+ }
55
+
56
+ return RISCV_EXCP_NONE;
57
+}
58
+#endif
59
+
60
static RISCVException fs(CPURISCVState *env, int csrno)
61
{
62
#if !defined(CONFIG_USER_ONLY)
63
@@ -XXX,XX +XXX,XX @@ static RISCVException write_menvcfgh(CPURISCVState *env, int csrno,
64
static RISCVException read_senvcfg(CPURISCVState *env, int csrno,
65
target_ulong *val)
66
{
67
+ RISCVException ret;
68
+
69
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
70
+ if (ret != RISCV_EXCP_NONE) {
71
+ return ret;
72
+ }
73
+
74
*val = env->senvcfg;
75
return RISCV_EXCP_NONE;
76
}
77
@@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
78
target_ulong val)
79
{
80
uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE;
81
+ RISCVException ret;
82
83
- env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
84
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
85
+ if (ret != RISCV_EXCP_NONE) {
86
+ return ret;
87
+ }
88
89
+ env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
90
return RISCV_EXCP_NONE;
91
}
92
93
static RISCVException read_henvcfg(CPURISCVState *env, int csrno,
94
target_ulong *val)
95
{
96
+ RISCVException ret;
97
+
98
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
99
+ if (ret != RISCV_EXCP_NONE) {
100
+ return ret;
101
+ }
102
+
103
*val = env->henvcfg;
104
return RISCV_EXCP_NONE;
105
}
106
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
107
target_ulong val)
108
{
109
uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE;
110
+ RISCVException ret;
111
+
112
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
113
+ if (ret != RISCV_EXCP_NONE) {
114
+ return ret;
115
+ }
116
117
if (riscv_cpu_mxl(env) == MXL_RV64) {
118
mask |= HENVCFG_PBMTE | HENVCFG_STCE;
119
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfg(CPURISCVState *env, int csrno,
120
static RISCVException read_henvcfgh(CPURISCVState *env, int csrno,
121
target_ulong *val)
122
{
123
+ RISCVException ret;
124
+
125
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
126
+ if (ret != RISCV_EXCP_NONE) {
127
+ return ret;
128
+ }
129
+
130
*val = env->henvcfg >> 32;
131
return RISCV_EXCP_NONE;
132
}
133
@@ -XXX,XX +XXX,XX @@ static RISCVException write_henvcfgh(CPURISCVState *env, int csrno,
134
{
135
uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE;
136
uint64_t valh = (uint64_t)val << 32;
137
+ RISCVException ret;
138
139
- env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
140
+ ret = smstateen_acc_ok(env, 0, SMSTATEEN0_HSENVCFG);
141
+ if (ret != RISCV_EXCP_NONE) {
142
+ return ret;
143
+ }
144
145
+ env->henvcfg = (env->henvcfg & ~mask) | (valh & mask);
146
return RISCV_EXCP_NONE;
147
}
148
149
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateen(CPURISCVState *env, int csrno,
150
static RISCVException write_mstateen0(CPURISCVState *env, int csrno,
151
target_ulong new_val)
152
{
153
- uint64_t wr_mask = SMSTATEEN_STATEEN;
154
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
155
156
return write_mstateen(env, csrno, wr_mask, new_val);
157
}
158
@@ -XXX,XX +XXX,XX @@ static RISCVException write_mstateenh(CPURISCVState *env, int csrno,
159
static RISCVException write_mstateen0h(CPURISCVState *env, int csrno,
160
target_ulong new_val)
161
{
162
- uint64_t wr_mask = SMSTATEEN_STATEEN;
163
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
164
165
return write_mstateenh(env, csrno, wr_mask, new_val);
166
}
167
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateen(CPURISCVState *env, int csrno,
168
static RISCVException write_hstateen0(CPURISCVState *env, int csrno,
169
target_ulong new_val)
170
{
171
- uint64_t wr_mask = SMSTATEEN_STATEEN;
172
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
173
174
return write_hstateen(env, csrno, wr_mask, new_val);
175
}
176
@@ -XXX,XX +XXX,XX @@ static RISCVException write_hstateenh(CPURISCVState *env, int csrno,
177
static RISCVException write_hstateen0h(CPURISCVState *env, int csrno,
178
target_ulong new_val)
179
{
180
- uint64_t wr_mask = SMSTATEEN_STATEEN;
181
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
182
183
return write_hstateenh(env, csrno, wr_mask, new_val);
184
}
185
@@ -XXX,XX +XXX,XX @@ static RISCVException write_sstateen(CPURISCVState *env, int csrno,
186
static RISCVException write_sstateen0(CPURISCVState *env, int csrno,
187
target_ulong new_val)
188
{
189
- uint64_t wr_mask = SMSTATEEN_STATEEN;
190
+ uint64_t wr_mask = SMSTATEEN_STATEEN | SMSTATEEN0_HSENVCFG;
191
192
return write_sstateen(env, csrno, wr_mask, new_val);
193
}
194
--
195
2.38.1
diff view generated by jsdifflib
New patch
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
2
3
This patch adds a mechanism to generate a virtual instruction
4
instruction exception instead of an illegal instruction exception
5
during instruction decode when virt is enabled.
6
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221016124726.102129-4-mchitale@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/translate.c | 8 +++++++-
14
1 file changed, 7 insertions(+), 1 deletion(-)
15
16
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/translate.c
19
+++ b/target/riscv/translate.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
21
to reset this known value. */
22
int frm;
23
RISCVMXL ol;
24
+ bool virt_inst_excp;
25
bool virt_enabled;
26
const RISCVCPUConfig *cfg_ptr;
27
bool hlsx;
28
@@ -XXX,XX +XXX,XX @@ static void gen_exception_illegal(DisasContext *ctx)
29
{
30
tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
31
offsetof(CPURISCVState, bins));
32
- generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
33
+ if (ctx->virt_inst_excp) {
34
+ generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
35
+ } else {
36
+ generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
37
+ }
38
}
39
40
static void gen_exception_inst_addr_mis(DisasContext *ctx)
41
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
42
{ has_XVentanaCondOps_p, decode_XVentanaCodeOps },
43
};
44
45
+ ctx->virt_inst_excp = false;
46
/* Check for compressed insn */
47
if (insn_len(opcode) == 2) {
48
if (!has_ext(ctx, RVC)) {
49
--
50
2.38.1
diff view generated by jsdifflib
New patch
1
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
2
3
When icount is not enabled, there is no API in QEMU that can get the
4
guest instruction number.
5
6
Translate the guest code in a way that each TB only has one instruction.
7
After executing the instruction, decrease the count by 1 until it reaches 0
8
where the itrigger fires.
9
10
Note that only when priviledge matches the itrigger configuration,
11
the count will decrease.
12
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20221013062946.7530-2-zhiwei_liu@linux.alibaba.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu.h | 2 +
19
target/riscv/debug.h | 12 ++++
20
target/riscv/helper.h | 2 +
21
target/riscv/cpu_helper.c | 6 ++
22
target/riscv/debug.c | 71 +++++++++++++++++++
23
target/riscv/translate.c | 33 ++++++++-
24
.../riscv/insn_trans/trans_privileged.c.inc | 4 +-
25
target/riscv/insn_trans/trans_rvi.c.inc | 8 +--
26
target/riscv/insn_trans/trans_rvv.c.inc | 4 +-
27
9 files changed, 131 insertions(+), 11 deletions(-)
28
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.h
32
+++ b/target/riscv/cpu.h
33
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
34
FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
35
FIELD(TB_FLAGS, VTA, 24, 1)
36
FIELD(TB_FLAGS, VMA, 25, 1)
37
+/* Native debug itrigger */
38
+FIELD(TB_FLAGS, ITRIGGER, 26, 1)
39
40
#ifdef TARGET_RISCV32
41
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
42
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/debug.h
45
+++ b/target/riscv/debug.h
46
@@ -XXX,XX +XXX,XX @@ enum {
47
SIZE_NUM = 16
48
};
49
50
+/* itrigger filed masks */
51
+#define ITRIGGER_ACTION 0x3f
52
+#define ITRIGGER_U BIT(6)
53
+#define ITRIGGER_S BIT(7)
54
+#define ITRIGGER_PENDING BIT(8)
55
+#define ITRIGGER_M BIT(9)
56
+#define ITRIGGER_COUNT (0x3fff << 10)
57
+#define ITRIGGER_HIT BIT(24)
58
+#define ITRIGGER_VU BIT(25)
59
+#define ITRIGGER_VS BIT(26)
60
+
61
bool tdata_available(CPURISCVState *env, int tdata_index);
62
63
target_ulong tselect_csr_read(CPURISCVState *env);
64
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
65
66
void riscv_trigger_init(CPURISCVState *env);
67
68
+bool riscv_itrigger_enabled(CPURISCVState *env);
69
#endif /* RISCV_DEBUG_H */
70
diff --git a/target/riscv/helper.h b/target/riscv/helper.h
71
index XXXXXXX..XXXXXXX 100644
72
--- a/target/riscv/helper.h
73
+++ b/target/riscv/helper.h
74
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_1(sret, tl, env)
75
DEF_HELPER_1(mret, tl, env)
76
DEF_HELPER_1(wfi, void, env)
77
DEF_HELPER_1(tlb_flush, void, env)
78
+/* Native Debug */
79
+DEF_HELPER_1(itrigger_match, void, env)
80
#endif
81
82
/* Hypervisor functions */
83
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
84
index XXXXXXX..XXXXXXX 100644
85
--- a/target/riscv/cpu_helper.c
86
+++ b/target/riscv/cpu_helper.c
87
@@ -XXX,XX +XXX,XX @@
88
#include "tcg/tcg-op.h"
89
#include "trace.h"
90
#include "semihosting/common-semi.h"
91
+#include "sysemu/cpu-timers.h"
92
#include "cpu_bits.h"
93
+#include "debug.h"
94
95
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
96
{
97
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
98
flags = FIELD_DP32(flags, TB_FLAGS, MSTATUS_HS_VS,
99
get_field(env->mstatus_hs, MSTATUS_VS));
100
}
101
+ if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
102
+ flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
103
+ riscv_itrigger_enabled(env));
104
+ }
105
#endif
106
107
flags = FIELD_DP32(flags, TB_FLAGS, XL, env->xl);
108
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
109
index XXXXXXX..XXXXXXX 100644
110
--- a/target/riscv/debug.c
111
+++ b/target/riscv/debug.c
112
@@ -XXX,XX +XXX,XX @@
113
#include "cpu.h"
114
#include "trace.h"
115
#include "exec/exec-all.h"
116
+#include "exec/helper-proto.h"
117
118
/*
119
* The following M-mode trigger CSRs are implemented:
120
@@ -XXX,XX +XXX,XX @@ static void type6_reg_write(CPURISCVState *env, target_ulong index,
121
return;
122
}
123
124
+/* icount trigger type */
125
+static inline int
126
+itrigger_get_count(CPURISCVState *env, int index)
127
+{
128
+ return get_field(env->tdata1[index], ITRIGGER_COUNT);
129
+}
130
+
131
+static inline void
132
+itrigger_set_count(CPURISCVState *env, int index, int value)
133
+{
134
+ env->tdata1[index] = set_field(env->tdata1[index],
135
+ ITRIGGER_COUNT, value);
136
+}
137
+
138
+static bool check_itrigger_priv(CPURISCVState *env, int index)
139
+{
140
+ target_ulong tdata1 = env->tdata1[index];
141
+ if (riscv_cpu_virt_enabled(env)) {
142
+ /* check VU/VS bit against current privilege level */
143
+ return (get_field(tdata1, ITRIGGER_VS) == env->priv) ||
144
+ (get_field(tdata1, ITRIGGER_VU) == env->priv);
145
+ } else {
146
+ /* check U/S/M bit against current privilege level */
147
+ return (get_field(tdata1, ITRIGGER_M) == env->priv) ||
148
+ (get_field(tdata1, ITRIGGER_S) == env->priv) ||
149
+ (get_field(tdata1, ITRIGGER_U) == env->priv);
150
+ }
151
+}
152
+
153
+bool riscv_itrigger_enabled(CPURISCVState *env)
154
+{
155
+ int count;
156
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
157
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
158
+ continue;
159
+ }
160
+ if (check_itrigger_priv(env, i)) {
161
+ continue;
162
+ }
163
+ count = itrigger_get_count(env, i);
164
+ if (!count) {
165
+ continue;
166
+ }
167
+ return true;
168
+ }
169
+
170
+ return false;
171
+}
172
+
173
+void helper_itrigger_match(CPURISCVState *env)
174
+{
175
+ int count;
176
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
177
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
178
+ continue;
179
+ }
180
+ if (check_itrigger_priv(env, i)) {
181
+ continue;
182
+ }
183
+ count = itrigger_get_count(env, i);
184
+ if (!count) {
185
+ continue;
186
+ }
187
+ itrigger_set_count(env, i, count--);
188
+ if (!count) {
189
+ do_trigger_action(env, i);
190
+ }
191
+ }
192
+}
193
+
194
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
195
{
196
switch (tdata_index) {
197
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
198
index XXXXXXX..XXXXXXX 100644
199
--- a/target/riscv/translate.c
200
+++ b/target/riscv/translate.c
201
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
202
/* PointerMasking extension */
203
bool pm_mask_enabled;
204
bool pm_base_enabled;
205
+ /* Use icount trigger for native debug */
206
+ bool itrigger;
207
/* TCG of the current insn_start */
208
TCGOp *insn_start;
209
} DisasContext;
210
@@ -XXX,XX +XXX,XX @@ static void gen_exception_inst_addr_mis(DisasContext *ctx)
211
generate_exception(ctx, RISCV_EXCP_INST_ADDR_MIS);
212
}
213
214
+static void lookup_and_goto_ptr(DisasContext *ctx)
215
+{
216
+#ifndef CONFIG_USER_ONLY
217
+ if (ctx->itrigger) {
218
+ gen_helper_itrigger_match(cpu_env);
219
+ }
220
+#endif
221
+ tcg_gen_lookup_and_goto_ptr();
222
+}
223
+
224
+static void exit_tb(DisasContext *ctx)
225
+{
226
+#ifndef CONFIG_USER_ONLY
227
+ if (ctx->itrigger) {
228
+ gen_helper_itrigger_match(cpu_env);
229
+ }
230
+#endif
231
+ tcg_gen_exit_tb(NULL, 0);
232
+}
233
+
234
static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
235
{
236
- if (translator_use_goto_tb(&ctx->base, dest)) {
237
+ /*
238
+ * Under itrigger, instruction executes one by one like singlestep,
239
+ * direct block chain benefits will be small.
240
+ */
241
+ if (translator_use_goto_tb(&ctx->base, dest) && !ctx->itrigger) {
242
tcg_gen_goto_tb(n);
243
gen_set_pc_imm(ctx, dest);
244
tcg_gen_exit_tb(ctx->base.tb, n);
245
} else {
246
gen_set_pc_imm(ctx, dest);
247
- tcg_gen_lookup_and_goto_ptr();
248
+ lookup_and_goto_ptr(ctx);
249
}
250
}
251
252
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
253
memset(ctx->ftemp, 0, sizeof(ctx->ftemp));
254
ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
255
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
256
+ ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
257
ctx->zero = tcg_constant_tl(0);
258
}
259
260
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
261
262
/* Only the first insn within a TB is allowed to cross a page boundary. */
263
if (ctx->base.is_jmp == DISAS_NEXT) {
264
- if (!is_same_page(&ctx->base, ctx->base.pc_next)) {
265
+ if (ctx->itrigger || !is_same_page(&ctx->base, ctx->base.pc_next)) {
266
ctx->base.is_jmp = DISAS_TOO_MANY;
267
} else {
268
unsigned page_ofs = ctx->base.pc_next & ~TARGET_PAGE_MASK;
269
diff --git a/target/riscv/insn_trans/trans_privileged.c.inc b/target/riscv/insn_trans/trans_privileged.c.inc
270
index XXXXXXX..XXXXXXX 100644
271
--- a/target/riscv/insn_trans/trans_privileged.c.inc
272
+++ b/target/riscv/insn_trans/trans_privileged.c.inc
273
@@ -XXX,XX +XXX,XX @@ static bool trans_sret(DisasContext *ctx, arg_sret *a)
274
if (has_ext(ctx, RVS)) {
275
decode_save_opc(ctx);
276
gen_helper_sret(cpu_pc, cpu_env);
277
- tcg_gen_exit_tb(NULL, 0); /* no chaining */
278
+ exit_tb(ctx); /* no chaining */
279
ctx->base.is_jmp = DISAS_NORETURN;
280
} else {
281
return false;
282
@@ -XXX,XX +XXX,XX @@ static bool trans_mret(DisasContext *ctx, arg_mret *a)
283
#ifndef CONFIG_USER_ONLY
284
decode_save_opc(ctx);
285
gen_helper_mret(cpu_pc, cpu_env);
286
- tcg_gen_exit_tb(NULL, 0); /* no chaining */
287
+ exit_tb(ctx); /* no chaining */
288
ctx->base.is_jmp = DISAS_NORETURN;
289
return true;
290
#else
291
diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
292
index XXXXXXX..XXXXXXX 100644
293
--- a/target/riscv/insn_trans/trans_rvi.c.inc
294
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
295
@@ -XXX,XX +XXX,XX @@ static bool trans_jalr(DisasContext *ctx, arg_jalr *a)
296
}
297
298
gen_set_gpri(ctx, a->rd, ctx->pc_succ_insn);
299
- tcg_gen_lookup_and_goto_ptr();
300
+ lookup_and_goto_ptr(ctx);
301
302
if (misaligned) {
303
gen_set_label(misaligned);
304
@@ -XXX,XX +XXX,XX @@ static bool trans_pause(DisasContext *ctx, arg_pause *a)
305
* end the TB and return to main loop
306
*/
307
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
308
- tcg_gen_exit_tb(NULL, 0);
309
+ exit_tb(ctx);
310
ctx->base.is_jmp = DISAS_NORETURN;
311
312
return true;
313
@@ -XXX,XX +XXX,XX @@ static bool trans_fence_i(DisasContext *ctx, arg_fence_i *a)
314
* however we need to end the translation block
315
*/
316
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
317
- tcg_gen_exit_tb(NULL, 0);
318
+ exit_tb(ctx);
319
ctx->base.is_jmp = DISAS_NORETURN;
320
return true;
321
}
322
@@ -XXX,XX +XXX,XX @@ static bool do_csr_post(DisasContext *ctx)
323
decode_save_opc(ctx);
324
/* We may have changed important cpu state -- exit to main loop. */
325
gen_set_pc_imm(ctx, ctx->pc_succ_insn);
326
- tcg_gen_exit_tb(NULL, 0);
327
+ exit_tb(ctx);
328
ctx->base.is_jmp = DISAS_NORETURN;
329
return true;
330
}
331
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc
332
index XXXXXXX..XXXXXXX 100644
333
--- a/target/riscv/insn_trans/trans_rvv.c.inc
334
+++ b/target/riscv/insn_trans/trans_rvv.c.inc
335
@@ -XXX,XX +XXX,XX @@ static bool do_vsetvl(DisasContext *s, int rd, int rs1, TCGv s2)
336
mark_vs_dirty(s);
337
338
gen_set_pc_imm(s, s->pc_succ_insn);
339
- tcg_gen_lookup_and_goto_ptr();
340
+ lookup_and_goto_ptr(s);
341
s->base.is_jmp = DISAS_NORETURN;
342
343
if (rd == 0 && rs1 == 0) {
344
@@ -XXX,XX +XXX,XX @@ static bool do_vsetivli(DisasContext *s, int rd, TCGv s1, TCGv s2)
345
gen_set_gpr(s, rd, dst);
346
mark_vs_dirty(s);
347
gen_set_pc_imm(s, s->pc_succ_insn);
348
- tcg_gen_lookup_and_goto_ptr();
349
+ lookup_and_goto_ptr(s);
350
s->base.is_jmp = DISAS_NORETURN;
351
352
return true;
353
--
354
2.38.1
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
The max count in itrigger can be 0x3FFF, which will cause a no trivial
4
translation and execution overload.
5
6
When icount is enabled, QEMU provides API that can fetch guest
7
instruction number. Thus, we can set an timer for itrigger with
8
the count as deadline.
9
10
Only when timer expires or priviledge mode changes, do lazy update
11
to count.
12
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20221013062946.7530-3-zhiwei_liu@linux.alibaba.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu.h | 2 ++
19
target/riscv/debug.h | 1 +
20
target/riscv/cpu_helper.c | 3 ++
21
target/riscv/debug.c | 59 +++++++++++++++++++++++++++++++++++++++
22
4 files changed, 65 insertions(+)
23
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
+++ b/target/riscv/cpu.h
28
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
29
target_ulong tdata3[RV_MAX_TRIGGERS];
30
struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
31
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
32
+ QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
33
+ int64_t last_icount;
34
35
/* machine specific rdtime callback */
36
uint64_t (*rdtime_fn)(void *);
37
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
38
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/debug.h
40
+++ b/target/riscv/debug.h
41
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
42
void riscv_trigger_init(CPURISCVState *env);
43
44
bool riscv_itrigger_enabled(CPURISCVState *env);
45
+void riscv_itrigger_update_priv(CPURISCVState *env);
46
#endif /* RISCV_DEBUG_H */
47
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/cpu_helper.c
50
+++ b/target/riscv/cpu_helper.c
51
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
52
if (newpriv == PRV_H) {
53
newpriv = PRV_U;
54
}
55
+ if (icount_enabled() && newpriv != env->priv) {
56
+ riscv_itrigger_update_priv(env);
57
+ }
58
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
59
env->priv = newpriv;
60
env->xl = cpu_recompute_xl(env);
61
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/riscv/debug.c
64
+++ b/target/riscv/debug.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "trace.h"
67
#include "exec/exec-all.h"
68
#include "exec/helper-proto.h"
69
+#include "sysemu/cpu-timers.h"
70
71
/*
72
* The following M-mode trigger CSRs are implemented:
73
@@ -XXX,XX +XXX,XX @@ void helper_itrigger_match(CPURISCVState *env)
74
}
75
}
76
77
+static void riscv_itrigger_update_count(CPURISCVState *env)
78
+{
79
+ int count, executed;
80
+ /*
81
+ * Record last icount, so that we can evaluate the executed instructions
82
+ * since last priviledge mode change or timer expire.
83
+ */
84
+ int64_t last_icount = env->last_icount, current_icount;
85
+ current_icount = env->last_icount = icount_get_raw();
86
+
87
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
88
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
89
+ continue;
90
+ }
91
+ count = itrigger_get_count(env, i);
92
+ if (!count) {
93
+ continue;
94
+ }
95
+ /*
96
+ * Only when priviledge is changed or itrigger timer expires,
97
+ * the count field in itrigger tdata1 register is updated.
98
+ * And the count field in itrigger only contains remaining value.
99
+ */
100
+ if (check_itrigger_priv(env, i)) {
101
+ /*
102
+ * If itrigger enabled in this priviledge mode, the number of
103
+ * executed instructions since last priviledge change
104
+ * should be reduced from current itrigger count.
105
+ */
106
+ executed = current_icount - last_icount;
107
+ itrigger_set_count(env, i, count - executed);
108
+ if (count == executed) {
109
+ do_trigger_action(env, i);
110
+ }
111
+ } else {
112
+ /*
113
+ * If itrigger is not enabled in this priviledge mode,
114
+ * the number of executed instructions will be discard and
115
+ * the count field in itrigger will not change.
116
+ */
117
+ timer_mod(env->itrigger_timer[i],
118
+ current_icount + count);
119
+ }
120
+ }
121
+}
122
+
123
+static void riscv_itrigger_timer_cb(void *opaque)
124
+{
125
+ riscv_itrigger_update_count((CPURISCVState *)opaque);
126
+}
127
+
128
+void riscv_itrigger_update_priv(CPURISCVState *env)
129
+{
130
+ riscv_itrigger_update_count(env);
131
+}
132
+
133
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
134
{
135
switch (tdata_index) {
136
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
137
env->tdata3[i] = 0;
138
env->cpu_breakpoint[i] = NULL;
139
env->cpu_watchpoint[i] = NULL;
140
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
141
+ riscv_itrigger_timer_cb, env);
142
}
143
}
144
--
145
2.38.1
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
When QEMU is not in icount mode, execute instruction one by one. The
4
tdata1 can be read directly.
5
6
When QEMU is in icount mode, use a timer to simulate the itrigger. The
7
tdata1 may be not right because of lazy update of count in tdata1. Thus,
8
We should pack the adjusted count into tdata1 before read it back.
9
10
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-Id: <20221013062946.7530-4-zhiwei_liu@linux.alibaba.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
15
target/riscv/debug.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
16
1 file changed, 72 insertions(+)
17
18
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/debug.c
21
+++ b/target/riscv/debug.c
22
@@ -XXX,XX +XXX,XX @@ void riscv_itrigger_update_priv(CPURISCVState *env)
23
riscv_itrigger_update_count(env);
24
}
25
26
+static target_ulong itrigger_validate(CPURISCVState *env,
27
+ target_ulong ctrl)
28
+{
29
+ target_ulong val;
30
+
31
+ /* validate the generic part first */
32
+ val = tdata1_validate(env, ctrl, TRIGGER_TYPE_INST_CNT);
33
+
34
+ /* validate unimplemented (always zero) bits */
35
+ warn_always_zero_bit(ctrl, ITRIGGER_ACTION, "action");
36
+ warn_always_zero_bit(ctrl, ITRIGGER_HIT, "hit");
37
+ warn_always_zero_bit(ctrl, ITRIGGER_PENDING, "pending");
38
+
39
+ /* keep the mode and attribute bits */
40
+ val |= ctrl & (ITRIGGER_VU | ITRIGGER_VS | ITRIGGER_U | ITRIGGER_S |
41
+ ITRIGGER_M | ITRIGGER_COUNT);
42
+
43
+ return val;
44
+}
45
+
46
+static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
47
+ int tdata_index, target_ulong val)
48
+{
49
+ target_ulong new_val;
50
+
51
+ switch (tdata_index) {
52
+ case TDATA1:
53
+ /* set timer for icount */
54
+ new_val = itrigger_validate(env, val);
55
+ if (new_val != env->tdata1[index]) {
56
+ env->tdata1[index] = new_val;
57
+ if (icount_enabled()) {
58
+ env->last_icount = icount_get_raw();
59
+ /* set the count to timer */
60
+ timer_mod(env->itrigger_timer[index],
61
+ env->last_icount + itrigger_get_count(env, index));
62
+ }
63
+ }
64
+ break;
65
+ case TDATA2:
66
+ qemu_log_mask(LOG_UNIMP,
67
+ "tdata2 is not supported for icount trigger\n");
68
+ break;
69
+ case TDATA3:
70
+ qemu_log_mask(LOG_UNIMP,
71
+ "tdata3 is not supported for icount trigger\n");
72
+ break;
73
+ default:
74
+ g_assert_not_reached();
75
+ }
76
+
77
+ return;
78
+}
79
+
80
+static int itrigger_get_adjust_count(CPURISCVState *env)
81
+{
82
+ int count = itrigger_get_count(env, env->trigger_cur), executed;
83
+ if ((count != 0) && check_itrigger_priv(env, env->trigger_cur)) {
84
+ executed = icount_get_raw() - env->last_icount;
85
+ count += executed;
86
+ }
87
+ return count;
88
+}
89
+
90
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
91
{
92
+ int trigger_type;
93
switch (tdata_index) {
94
case TDATA1:
95
+ trigger_type = extract_trigger_type(env, env->tdata1[env->trigger_cur]);
96
+ if ((trigger_type == TRIGGER_TYPE_INST_CNT) && icount_enabled()) {
97
+ return deposit64(env->tdata1[env->trigger_cur], 10, 14,
98
+ itrigger_get_adjust_count(env));
99
+ }
100
return env->tdata1[env->trigger_cur];
101
case TDATA2:
102
return env->tdata2[env->trigger_cur];
103
@@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val)
104
type6_reg_write(env, env->trigger_cur, tdata_index, val);
105
break;
106
case TRIGGER_TYPE_INST_CNT:
107
+ itrigger_reg_write(env, env->trigger_cur, tdata_index, val);
108
+ break;
109
case TRIGGER_TYPE_INT:
110
case TRIGGER_TYPE_EXCP:
111
case TRIGGER_TYPE_EXT_SRC:
112
--
113
2.38.1
diff view generated by jsdifflib
New patch
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
2
3
Avoid calling riscv_itrigger_enabled() when calculate the tbflags.
4
As the itrigger enable status can only be changed when write
5
tdata1, migration load or itrigger fire, update env->itrigger_enabled
6
at these places.
7
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221013062946.7530-5-zhiwei_liu@linux.alibaba.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu.h | 1 +
14
target/riscv/cpu_helper.c | 3 +--
15
target/riscv/debug.c | 3 +++
16
target/riscv/machine.c | 15 +++++++++++++++
17
4 files changed, 20 insertions(+), 2 deletions(-)
18
19
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/cpu.h
22
+++ b/target/riscv/cpu.h
23
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
24
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
25
QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
26
int64_t last_icount;
27
+ bool itrigger_enabled;
28
29
/* machine specific rdtime callback */
30
uint64_t (*rdtime_fn)(void *);
31
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_helper.c
34
+++ b/target/riscv/cpu_helper.c
35
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
36
get_field(env->mstatus_hs, MSTATUS_VS));
37
}
38
if (riscv_feature(env, RISCV_FEATURE_DEBUG) && !icount_enabled()) {
39
- flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER,
40
- riscv_itrigger_enabled(env));
41
+ flags = FIELD_DP32(flags, TB_FLAGS, ITRIGGER, env->itrigger_enabled);
42
}
43
#endif
44
45
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
46
index XXXXXXX..XXXXXXX 100644
47
--- a/target/riscv/debug.c
48
+++ b/target/riscv/debug.c
49
@@ -XXX,XX +XXX,XX @@ void helper_itrigger_match(CPURISCVState *env)
50
}
51
itrigger_set_count(env, i, count--);
52
if (!count) {
53
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
54
do_trigger_action(env, i);
55
}
56
}
57
@@ -XXX,XX +XXX,XX @@ static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
58
/* set the count to timer */
59
timer_mod(env->itrigger_timer[index],
60
env->last_icount + itrigger_get_count(env, index));
61
+ } else {
62
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
63
}
64
}
65
break;
66
diff --git a/target/riscv/machine.c b/target/riscv/machine.c
67
index XXXXXXX..XXXXXXX 100644
68
--- a/target/riscv/machine.c
69
+++ b/target/riscv/machine.c
70
@@ -XXX,XX +XXX,XX @@
71
#include "qemu/error-report.h"
72
#include "sysemu/kvm.h"
73
#include "migration/cpu.h"
74
+#include "sysemu/cpu-timers.h"
75
+#include "debug.h"
76
77
static bool pmp_needed(void *opaque)
78
{
79
@@ -XXX,XX +XXX,XX @@ static bool debug_needed(void *opaque)
80
return riscv_feature(env, RISCV_FEATURE_DEBUG);
81
}
82
83
+static int debug_post_load(void *opaque, int version_id)
84
+{
85
+ RISCVCPU *cpu = opaque;
86
+ CPURISCVState *env = &cpu->env;
87
+
88
+ if (icount_enabled()) {
89
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
90
+ }
91
+
92
+ return 0;
93
+}
94
+
95
static const VMStateDescription vmstate_debug = {
96
.name = "cpu/debug",
97
.version_id = 2,
98
.minimum_version_id = 2,
99
.needed = debug_needed,
100
+ .post_load = debug_post_load,
101
.fields = (VMStateField[]) {
102
VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
103
VMSTATE_UINTTL_ARRAY(env.tdata1, RISCVCPU, RV_MAX_TRIGGERS),
104
--
105
2.38.1
diff view generated by jsdifflib
New patch
1
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
1
2
3
Commit 40244040a7a changed the way the S irqs are numbered. This breaks when
4
using numa configuration, e.g.:
5
./qemu-system-riscv64 -nographic -machine virt,dumpdtb=numa-tree.dtb \
6
-m 2G -smp cpus=16 \
7
         -object memory-backend-ram,id=mem0,size=512M \
8
         -object memory-backend-ram,id=mem1,size=512M \
9
         -object memory-backend-ram,id=mem2,size=512M \
10
         -object memory-backend-ram,id=mem3,size=512M \
11
         -numa node,cpus=0-3,memdev=mem0,nodeid=0 \
12
         -numa node,cpus=4-7,memdev=mem1,nodeid=1 \
13
         -numa node,cpus=8-11,memdev=mem2,nodeid=2 \
14
         -numa node,cpus=12-15,memdev=mem3,nodeid=3
15
leads to:
16
Unexpected error in object_property_find_err() at ../qom/object.c:1304:
17
qemu-system-riscv64: Property 'riscv.sifive.plic.unnamed-gpio-out[8]' not
18
found
19
20
This patch makes the nubering of the S irqs identical to what it was before.
21
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
24
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
25
Message-Id: <20221114135122.1668703-1-frederic.petrot@univ-grenoble-alpes.fr>
26
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
27
---
28
hw/intc/sifive_plic.c | 4 ++--
29
1 file changed, 2 insertions(+), 2 deletions(-)
30
31
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/intc/sifive_plic.c
34
+++ b/hw/intc/sifive_plic.c
35
@@ -XXX,XX +XXX,XX @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
36
CPUState *cpu = qemu_get_cpu(cpu_num);
37
38
if (plic->addr_config[i].mode == PLICMode_M) {
39
- qdev_connect_gpio_out(dev, num_harts - plic->hartid_base + cpu_num,
40
+ qdev_connect_gpio_out(dev, cpu_num - hartid_base + num_harts,
41
qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
42
}
43
if (plic->addr_config[i].mode == PLICMode_S) {
44
- qdev_connect_gpio_out(dev, cpu_num,
45
+ qdev_connect_gpio_out(dev, cpu_num - hartid_base,
46
qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
47
}
48
}
49
--
50
2.38.1
diff view generated by jsdifflib
New patch
1
From: Anup Patel <apatel@ventanamicro.com>
1
2
3
We should use "&&" instead of "&" when checking hcounteren.TM and
4
henvcfg.STCE bits.
5
6
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221108125703.1463577-2-apatel@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/csr.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
20
}
21
22
if (riscv_cpu_virt_enabled(env)) {
23
- if (!(get_field(env->hcounteren, COUNTEREN_TM) &
24
+ if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
25
get_field(env->henvcfg, HENVCFG_STCE))) {
26
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
27
}
28
--
29
2.38.1
diff view generated by jsdifflib
New patch
1
From: Atish Patra <atishp@rivosinc.com>
1
2
3
The imsic DT binding[1] has changed and no longer require an ipi-id.
4
The latest IMSIC driver dynamically allocates ipi id if slow-ipi
5
is not defined.
6
7
Get rid of the unused dt property which may lead to confusion.
8
9
[1] https://lore.kernel.org/lkml/20221111044207.1478350-5-apatel@ventanamicro.com/
10
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20221122080529.1692533-1-atishp@rivosinc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
include/hw/riscv/virt.h | 1 -
17
hw/riscv/virt.c | 4 ----
18
2 files changed, 5 deletions(-)
19
20
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/virt.h
23
+++ b/include/hw/riscv/virt.h
24
@@ -XXX,XX +XXX,XX @@ enum {
25
26
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
27
28
-#define VIRT_IRQCHIP_IPI_MSI 1
29
#define VIRT_IRQCHIP_NUM_MSIS 255
30
#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
31
#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
32
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
33
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/riscv/virt.c
35
+++ b/hw/riscv/virt.c
36
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
37
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
38
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
39
VIRT_IRQCHIP_NUM_MSIS);
40
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
41
- VIRT_IRQCHIP_IPI_MSI);
42
if (riscv_socket_count(mc) > 1) {
43
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
44
imsic_num_bits(imsic_max_hart_per_socket));
45
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
46
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
47
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
48
VIRT_IRQCHIP_NUM_MSIS);
49
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
50
- VIRT_IRQCHIP_IPI_MSI);
51
if (imsic_guest_bits) {
52
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
53
imsic_guest_bits);
54
--
55
2.38.1
diff view generated by jsdifflib
New patch
1
From: Jim Shu <jim.shu@sifive.com>
1
2
3
let tlb_fill() function also increments PMU counter when it is from
4
two-stage translation, so QEMU could also monitor these PMU events when
5
CPU runs in VS/VU mode (like running guest OS).
6
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221123090635.6574-1-jim.shu@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu_helper.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
+++ b/target/riscv/cpu_helper.c
19
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
20
}
21
}
22
23
+ pmu_tlb_fill_incr_ctr(cpu, access_type);
24
if (riscv_cpu_virt_enabled(env) ||
25
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
26
access_type != MMU_INST_FETCH)) {
27
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
28
}
29
}
30
} else {
31
- pmu_tlb_fill_incr_ctr(cpu, access_type);
32
/* Single stage lookup */
33
ret = get_physical_address(env, &pa, &prot, address, NULL,
34
access_type, mmu_idx, true, false, false);
35
--
36
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
sstatus register dump is currently missing in riscv_cpu_dump_state().
4
As sstatus is a copy of mstatus, which is described in the priv spec,
5
it seems redundant to print the same information twice.
6
7
Add some comments for this to let people know this is intentional.
8
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221125050354.3166023-1-bmeng@tinylab.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/cpu.c | 4 ++++
15
1 file changed, 4 insertions(+)
16
17
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
22
CSR_MHARTID,
23
CSR_MSTATUS,
24
CSR_MSTATUSH,
25
+ /*
26
+ * CSR_SSTATUS is intentionally omitted here as its value
27
+ * can be figured out by looking at CSR_MSTATUS
28
+ */
29
CSR_HSTATUS,
30
CSR_VSSTATUS,
31
CSR_MIP,
32
--
33
2.38.1
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
On PolarFire SoC, some peripherals (eg the PCI root port) are clocked by
4
"Clock Conditioning Circuitry" in the FPGA. The specific clock depends
5
on the FPGA bitstream & can be locked to one particular {D,P}LL - in the
6
Icicle Kit Reference Design v2022.09 or later this is/will be the case.
7
8
Linux v6.1+ will have a driver for this peripheral and devicetrees that
9
previously relied on "fixed-frequency" clock nodes have been switched
10
over to clock-controller nodes. The IOSCB region is represented in QEMU,
11
but the specific region of it that the CCCs occupy has not so v6.1-rcN
12
kernels fail to boot in QEMU.
13
14
Add the regions as unimplemented so that the status-quo in terms of boot
15
is maintained.
16
17
Acked-by: Alistair Francis <alistair.francis@wdc.com>
18
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
19
Message-Id: <20221117225518.4102575-2-conor@kernel.org>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
include/hw/misc/mchp_pfsoc_ioscb.h | 1 +
23
hw/misc/mchp_pfsoc_ioscb.c | 6 ++++++
24
2 files changed, 7 insertions(+)
25
26
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
29
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
30
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
31
MemoryRegion lane23;
32
MemoryRegion ctrl;
33
MemoryRegion cfg;
34
+ MemoryRegion ccc;
35
MemoryRegion pll_mss;
36
MemoryRegion cfm_mss;
37
MemoryRegion pll_ddr;
38
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
39
index XXXXXXX..XXXXXXX 100644
40
--- a/hw/misc/mchp_pfsoc_ioscb.c
41
+++ b/hw/misc/mchp_pfsoc_ioscb.c
42
@@ -XXX,XX +XXX,XX @@
43
*/
44
#define IOSCB_WHOLE_REG_SIZE 0x10000000
45
#define IOSCB_SUBMOD_REG_SIZE 0x1000
46
+#define IOSCB_CCC_REG_SIZE 0x2000000
47
48
/*
49
* There are many sub-modules in the IOSCB module.
50
@@ -XXX,XX +XXX,XX @@
51
#define IOSCB_LANE23_BASE 0x06510000
52
#define IOSCB_CTRL_BASE 0x07020000
53
#define IOSCB_CFG_BASE 0x07080000
54
+#define IOSCB_CCC_BASE 0x08000000
55
#define IOSCB_PLL_MSS_BASE 0x0E001000
56
#define IOSCB_CFM_MSS_BASE 0x0E002000
57
#define IOSCB_PLL_DDR_BASE 0x0E010000
58
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
59
"mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
60
memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
61
62
+ memory_region_init_io(&s->ccc, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
63
+ "mchp.pfsoc.ioscb.ccc", IOSCB_CCC_REG_SIZE);
64
+ memory_region_add_subregion(&s->container, IOSCB_CCC_BASE, &s->ccc);
65
+
66
memory_region_init_io(&s->pll_mss, OBJECT(s), &mchp_pfsoc_pll_ops, s,
67
"mchp.pfsoc.ioscb.pll_mss", IOSCB_SUBMOD_REG_SIZE);
68
memory_region_add_subregion(&s->container, IOSCB_PLL_MSS_BASE, &s->pll_mss);
69
--
70
2.38.1
diff view generated by jsdifflib
New patch
1
From: Conor Dooley <conor.dooley@microchip.com>
1
2
3
The Fabric Interconnect Controllers provide interfaces between the FPGA
4
fabric and the core complex. There are 5 FICs on PolarFire SoC, numbered
5
0 through 4. FIC2 is an AXI4 slave interface from the FPGA fabric and
6
does not show up on the MSS memory map. FIC4 is dedicated to the User
7
Crypto Processor and does not show up on the MSS memory map either.
8
9
FIC 0, 1 & 3 do show up in the MSS memory map and neither FICs 0 or 1
10
are represented in QEMU, leading to load access violations while booting
11
Linux for Icicle if PCIe is enabled as the root port is connected via
12
either FIC 0 or 1.
13
14
Acked-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
16
Message-Id: <20221117225518.4102575-3-conor@kernel.org>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/riscv/microchip_pfsoc.h | 2 +
20
hw/riscv/microchip_pfsoc.c | 115 ++++++++++++++++-------------
21
2 files changed, 65 insertions(+), 52 deletions(-)
22
23
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/microchip_pfsoc.h
26
+++ b/include/hw/riscv/microchip_pfsoc.h
27
@@ -XXX,XX +XXX,XX @@ enum {
28
MICROCHIP_PFSOC_USB,
29
MICROCHIP_PFSOC_QSPI_XIP,
30
MICROCHIP_PFSOC_IOSCB,
31
+ MICROCHIP_PFSOC_FABRIC_FIC0,
32
+ MICROCHIP_PFSOC_FABRIC_FIC1,
33
MICROCHIP_PFSOC_FABRIC_FIC3,
34
MICROCHIP_PFSOC_DRAM_LO,
35
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
36
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
37
index XXXXXXX..XXXXXXX 100644
38
--- a/hw/riscv/microchip_pfsoc.c
39
+++ b/hw/riscv/microchip_pfsoc.c
40
@@ -XXX,XX +XXX,XX @@
41
* describes the complete IOSCB modules memory maps
42
*/
43
static const MemMapEntry microchip_pfsoc_memmap[] = {
44
- [MICROCHIP_PFSOC_RSVD0] = { 0x0, 0x100 },
45
- [MICROCHIP_PFSOC_DEBUG] = { 0x100, 0xf00 },
46
- [MICROCHIP_PFSOC_E51_DTIM] = { 0x1000000, 0x2000 },
47
- [MICROCHIP_PFSOC_BUSERR_UNIT0] = { 0x1700000, 0x1000 },
48
- [MICROCHIP_PFSOC_BUSERR_UNIT1] = { 0x1701000, 0x1000 },
49
- [MICROCHIP_PFSOC_BUSERR_UNIT2] = { 0x1702000, 0x1000 },
50
- [MICROCHIP_PFSOC_BUSERR_UNIT3] = { 0x1703000, 0x1000 },
51
- [MICROCHIP_PFSOC_BUSERR_UNIT4] = { 0x1704000, 0x1000 },
52
- [MICROCHIP_PFSOC_CLINT] = { 0x2000000, 0x10000 },
53
- [MICROCHIP_PFSOC_L2CC] = { 0x2010000, 0x1000 },
54
- [MICROCHIP_PFSOC_DMA] = { 0x3000000, 0x100000 },
55
- [MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
56
- [MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
57
- [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
58
- [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
59
- [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
60
- [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
61
- [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
62
- [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
63
- [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
64
- [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
65
- [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
66
- [MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 },
67
- [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
68
- [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
69
- [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
70
- [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
71
- [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
72
- [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
73
- [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
74
- [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
75
- [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
76
- [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
77
- [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
78
- [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
79
- [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
80
- [MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
81
- [MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
82
- [MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
83
- [MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
84
- [MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
85
- [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
86
- [MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
87
- [MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
88
- [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
89
- [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
90
- [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
91
- [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
92
- [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
93
- [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
94
- [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
95
- [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
96
+ [MICROCHIP_PFSOC_RSVD0] = { 0x0, 0x100 },
97
+ [MICROCHIP_PFSOC_DEBUG] = { 0x100, 0xf00 },
98
+ [MICROCHIP_PFSOC_E51_DTIM] = { 0x1000000, 0x2000 },
99
+ [MICROCHIP_PFSOC_BUSERR_UNIT0] = { 0x1700000, 0x1000 },
100
+ [MICROCHIP_PFSOC_BUSERR_UNIT1] = { 0x1701000, 0x1000 },
101
+ [MICROCHIP_PFSOC_BUSERR_UNIT2] = { 0x1702000, 0x1000 },
102
+ [MICROCHIP_PFSOC_BUSERR_UNIT3] = { 0x1703000, 0x1000 },
103
+ [MICROCHIP_PFSOC_BUSERR_UNIT4] = { 0x1704000, 0x1000 },
104
+ [MICROCHIP_PFSOC_CLINT] = { 0x2000000, 0x10000 },
105
+ [MICROCHIP_PFSOC_L2CC] = { 0x2010000, 0x1000 },
106
+ [MICROCHIP_PFSOC_DMA] = { 0x3000000, 0x100000 },
107
+ [MICROCHIP_PFSOC_L2LIM] = { 0x8000000, 0x2000000 },
108
+ [MICROCHIP_PFSOC_PLIC] = { 0xc000000, 0x4000000 },
109
+ [MICROCHIP_PFSOC_MMUART0] = { 0x20000000, 0x1000 },
110
+ [MICROCHIP_PFSOC_WDOG0] = { 0x20001000, 0x1000 },
111
+ [MICROCHIP_PFSOC_SYSREG] = { 0x20002000, 0x2000 },
112
+ [MICROCHIP_PFSOC_AXISW] = { 0x20004000, 0x1000 },
113
+ [MICROCHIP_PFSOC_MPUCFG] = { 0x20005000, 0x1000 },
114
+ [MICROCHIP_PFSOC_FMETER] = { 0x20006000, 0x1000 },
115
+ [MICROCHIP_PFSOC_DDR_SGMII_PHY] = { 0x20007000, 0x1000 },
116
+ [MICROCHIP_PFSOC_EMMC_SD] = { 0x20008000, 0x1000 },
117
+ [MICROCHIP_PFSOC_DDR_CFG] = { 0x20080000, 0x40000 },
118
+ [MICROCHIP_PFSOC_MMUART1] = { 0x20100000, 0x1000 },
119
+ [MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
120
+ [MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
121
+ [MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
122
+ [MICROCHIP_PFSOC_WDOG1] = { 0x20101000, 0x1000 },
123
+ [MICROCHIP_PFSOC_WDOG2] = { 0x20103000, 0x1000 },
124
+ [MICROCHIP_PFSOC_WDOG3] = { 0x20105000, 0x1000 },
125
+ [MICROCHIP_PFSOC_WDOG4] = { 0x20106000, 0x1000 },
126
+ [MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
127
+ [MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
128
+ [MICROCHIP_PFSOC_I2C0] = { 0x2010a000, 0x1000 },
129
+ [MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
130
+ [MICROCHIP_PFSOC_CAN0] = { 0x2010c000, 0x1000 },
131
+ [MICROCHIP_PFSOC_CAN1] = { 0x2010d000, 0x1000 },
132
+ [MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
133
+ [MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
134
+ [MICROCHIP_PFSOC_GPIO0] = { 0x20120000, 0x1000 },
135
+ [MICROCHIP_PFSOC_GPIO1] = { 0x20121000, 0x1000 },
136
+ [MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
137
+ [MICROCHIP_PFSOC_RTC] = { 0x20124000, 0x1000 },
138
+ [MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
139
+ [MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
140
+ [MICROCHIP_PFSOC_USB] = { 0x20201000, 0x1000 },
141
+ [MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
142
+ [MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
143
+ [MICROCHIP_PFSOC_FABRIC_FIC0] = { 0x2000000000, 0x1000000000 },
144
+ [MICROCHIP_PFSOC_FABRIC_FIC1] = { 0x3000000000, 0x1000000000 },
145
+ [MICROCHIP_PFSOC_FABRIC_FIC3] = { 0x40000000, 0x20000000 },
146
+ [MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
147
+ [MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
148
+ [MICROCHIP_PFSOC_DRAM_HI] = { 0x1000000000, 0x0 },
149
+ [MICROCHIP_PFSOC_DRAM_HI_ALIAS] = { 0x1400000000, 0x0 },
150
+
151
};
152
153
static void microchip_pfsoc_soc_instance_init(Object *obj)
154
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
155
create_unimplemented_device("microchip.pfsoc.fabricfic3",
156
memmap[MICROCHIP_PFSOC_FABRIC_FIC3].base,
157
memmap[MICROCHIP_PFSOC_FABRIC_FIC3].size);
158
+ /* FPGA Fabric */
159
+ create_unimplemented_device("microchip.pfsoc.fabricfic0",
160
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC0].base,
161
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC0].size);
162
+ /* FPGA Fabric */
163
+ create_unimplemented_device("microchip.pfsoc.fabricfic1",
164
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC1].base,
165
+ memmap[MICROCHIP_PFSOC_FABRIC_FIC1].size);
166
167
/* QSPI Flash */
168
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
169
--
170
2.38.1
diff view generated by jsdifflib
New patch
1
1
From: Conor Dooley <conor.dooley@microchip.com>
2
3
The system controller on PolarFire SoC is access via a mailbox. The
4
control registers for this mailbox lie in the "IOSCB" region & the
5
interrupt is cleared via write to the "SYSREG" region. It also has a
6
QSPI controller, usually connected to a flash chip, that is used for
7
storing FPGA bitstreams and used for In-Application Programming (IAP).
8
9
Linux has an implementation of the system controller, through which the
10
hwrng is accessed, leading to load/store access faults.
11
12
Add the QSPI as unimplemented and a very basic (effectively
13
unimplemented) version of the system controller's mailbox. Rather than
14
purely marking the regions as unimplemented, service the mailbox
15
requests by reporting failures and raising the interrupt so a guest can
16
better handle the lack of support.
17
18
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
19
Acked-by: Alistair Francis <alistair.francis@wdc.com>
20
Message-Id: <20221117225518.4102575-4-conor@kernel.org>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
23
include/hw/misc/mchp_pfsoc_ioscb.h | 3 ++
24
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
25
include/hw/riscv/microchip_pfsoc.h | 1 +
26
hw/misc/mchp_pfsoc_ioscb.c | 72 ++++++++++++++++++++++++++++-
27
hw/misc/mchp_pfsoc_sysreg.c | 18 ++++++--
28
hw/riscv/microchip_pfsoc.c | 6 +++
29
6 files changed, 95 insertions(+), 6 deletions(-)
30
31
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
34
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
35
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
36
MemoryRegion lane01;
37
MemoryRegion lane23;
38
MemoryRegion ctrl;
39
+ MemoryRegion qspixip;
40
+ MemoryRegion mailbox;
41
MemoryRegion cfg;
42
MemoryRegion ccc;
43
MemoryRegion pll_mss;
44
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
45
MemoryRegion cfm_sgmii;
46
MemoryRegion bc_sgmii;
47
MemoryRegion io_calib_sgmii;
48
+ qemu_irq irq;
49
} MchpPfSoCIoscbState;
50
51
#define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb"
52
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h
53
index XXXXXXX..XXXXXXX 100644
54
--- a/include/hw/misc/mchp_pfsoc_sysreg.h
55
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
56
@@ -XXX,XX +XXX,XX @@
57
typedef struct MchpPfSoCSysregState {
58
SysBusDevice parent;
59
MemoryRegion sysreg;
60
+ qemu_irq irq;
61
} MchpPfSoCSysregState;
62
63
#define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
64
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
65
index XXXXXXX..XXXXXXX 100644
66
--- a/include/hw/riscv/microchip_pfsoc.h
67
+++ b/include/hw/riscv/microchip_pfsoc.h
68
@@ -XXX,XX +XXX,XX @@ enum {
69
MICROCHIP_PFSOC_MMUART2_IRQ = 92,
70
MICROCHIP_PFSOC_MMUART3_IRQ = 93,
71
MICROCHIP_PFSOC_MMUART4_IRQ = 94,
72
+ MICROCHIP_PFSOC_MAILBOX_IRQ = 96,
73
};
74
75
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
76
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/misc/mchp_pfsoc_ioscb.c
79
+++ b/hw/misc/mchp_pfsoc_ioscb.c
80
@@ -XXX,XX +XXX,XX @@
81
#include "qemu/bitops.h"
82
#include "qemu/log.h"
83
#include "qapi/error.h"
84
+#include "hw/irq.h"
85
#include "hw/sysbus.h"
86
#include "hw/misc/mchp_pfsoc_ioscb.h"
87
88
@@ -XXX,XX +XXX,XX @@
89
#define IOSCB_WHOLE_REG_SIZE 0x10000000
90
#define IOSCB_SUBMOD_REG_SIZE 0x1000
91
#define IOSCB_CCC_REG_SIZE 0x2000000
92
+#define IOSCB_CTRL_REG_SIZE 0x800
93
+#define IOSCB_QSPIXIP_REG_SIZE 0x200
94
+
95
96
/*
97
* There are many sub-modules in the IOSCB module.
98
@@ -XXX,XX +XXX,XX @@
99
#define IOSCB_LANE01_BASE 0x06500000
100
#define IOSCB_LANE23_BASE 0x06510000
101
#define IOSCB_CTRL_BASE 0x07020000
102
+#define IOSCB_QSPIXIP_BASE 0x07020100
103
+#define IOSCB_MAILBOX_BASE 0x07020800
104
#define IOSCB_CFG_BASE 0x07080000
105
#define IOSCB_CCC_BASE 0x08000000
106
#define IOSCB_PLL_MSS_BASE 0x0E001000
107
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps mchp_pfsoc_io_calib_ddr_ops = {
108
.endianness = DEVICE_LITTLE_ENDIAN,
109
};
110
111
+#define SERVICES_CR 0x50
112
+#define SERVICES_SR 0x54
113
+#define SERVICES_STATUS_SHIFT 16
114
+
115
+static uint64_t mchp_pfsoc_ctrl_read(void *opaque, hwaddr offset,
116
+ unsigned size)
117
+{
118
+ uint32_t val = 0;
119
+
120
+ switch (offset) {
121
+ case SERVICES_SR:
122
+ /*
123
+ * Although some services have no error codes, most do. All services
124
+ * that do implement errors, begin their error codes at 1. Treat all
125
+ * service requests as failures & return 1.
126
+ * See the "PolarFire® FPGA and PolarFire SoC FPGA System Services"
127
+ * user guide for more information on service error codes.
128
+ */
129
+ val = 1u << SERVICES_STATUS_SHIFT;
130
+ break;
131
+ default:
132
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read "
133
+ "(size %d, offset 0x%" HWADDR_PRIx ")\n",
134
+ __func__, size, offset);
135
+ }
136
+
137
+ return val;
138
+}
139
+
140
+static void mchp_pfsoc_ctrl_write(void *opaque, hwaddr offset,
141
+ uint64_t value, unsigned size)
142
+{
143
+ MchpPfSoCIoscbState *s = opaque;
144
+
145
+ switch (offset) {
146
+ case SERVICES_CR:
147
+ qemu_irq_raise(s->irq);
148
+ break;
149
+ default:
150
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
151
+ "(size %d, value 0x%" PRIx64
152
+ ", offset 0x%" HWADDR_PRIx ")\n",
153
+ __func__, size, value, offset);
154
+ }
155
+}
156
+
157
+static const MemoryRegionOps mchp_pfsoc_ctrl_ops = {
158
+ .read = mchp_pfsoc_ctrl_read,
159
+ .write = mchp_pfsoc_ctrl_write,
160
+ .endianness = DEVICE_LITTLE_ENDIAN,
161
+};
162
+
163
static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
164
{
165
MchpPfSoCIoscbState *s = MCHP_PFSOC_IOSCB(dev);
166
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
167
"mchp.pfsoc.ioscb.lane23", IOSCB_SUBMOD_REG_SIZE);
168
memory_region_add_subregion(&s->container, IOSCB_LANE23_BASE, &s->lane23);
169
170
- memory_region_init_io(&s->ctrl, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
171
- "mchp.pfsoc.ioscb.ctrl", IOSCB_SUBMOD_REG_SIZE);
172
+ memory_region_init_io(&s->ctrl, OBJECT(s), &mchp_pfsoc_ctrl_ops, s,
173
+ "mchp.pfsoc.ioscb.ctrl", IOSCB_CTRL_REG_SIZE);
174
memory_region_add_subregion(&s->container, IOSCB_CTRL_BASE, &s->ctrl);
175
176
+ memory_region_init_io(&s->qspixip, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
177
+ "mchp.pfsoc.ioscb.qspixip", IOSCB_QSPIXIP_REG_SIZE);
178
+ memory_region_add_subregion(&s->container, IOSCB_QSPIXIP_BASE, &s->qspixip);
179
+
180
+ memory_region_init_io(&s->mailbox, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
181
+ "mchp.pfsoc.ioscb.mailbox", IOSCB_SUBMOD_REG_SIZE);
182
+ memory_region_add_subregion(&s->container, IOSCB_MAILBOX_BASE, &s->mailbox);
183
+
184
memory_region_init_io(&s->cfg, OBJECT(s), &mchp_pfsoc_dummy_ops, s,
185
"mchp.pfsoc.ioscb.cfg", IOSCB_SUBMOD_REG_SIZE);
186
memory_region_add_subregion(&s->container, IOSCB_CFG_BASE, &s->cfg);
187
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
188
IOSCB_SUBMOD_REG_SIZE);
189
memory_region_add_subregion(&s->container, IOSCB_IO_CALIB_SGMII_BASE,
190
&s->io_calib_sgmii);
191
+
192
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
193
}
194
195
static void mchp_pfsoc_ioscb_class_init(ObjectClass *klass, void *data)
196
diff --git a/hw/misc/mchp_pfsoc_sysreg.c b/hw/misc/mchp_pfsoc_sysreg.c
197
index XXXXXXX..XXXXXXX 100644
198
--- a/hw/misc/mchp_pfsoc_sysreg.c
199
+++ b/hw/misc/mchp_pfsoc_sysreg.c
200
@@ -XXX,XX +XXX,XX @@
201
#include "qemu/bitops.h"
202
#include "qemu/log.h"
203
#include "qapi/error.h"
204
+#include "hw/irq.h"
205
#include "hw/sysbus.h"
206
#include "hw/misc/mchp_pfsoc_sysreg.h"
207
208
#define ENVM_CR 0xb8
209
+#define MESSAGE_INT 0x118c
210
211
static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
212
unsigned size)
213
@@ -XXX,XX +XXX,XX @@ static uint64_t mchp_pfsoc_sysreg_read(void *opaque, hwaddr offset,
214
static void mchp_pfsoc_sysreg_write(void *opaque, hwaddr offset,
215
uint64_t value, unsigned size)
216
{
217
- qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
218
- "(size %d, value 0x%" PRIx64
219
- ", offset 0x%" HWADDR_PRIx ")\n",
220
- __func__, size, value, offset);
221
+ MchpPfSoCSysregState *s = opaque;
222
+ switch (offset) {
223
+ case MESSAGE_INT:
224
+ qemu_irq_lower(s->irq);
225
+ break;
226
+ default:
227
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
228
+ "(size %d, value 0x%" PRIx64
229
+ ", offset 0x%" HWADDR_PRIx ")\n",
230
+ __func__, size, value, offset);
231
+ }
232
}
233
234
static const MemoryRegionOps mchp_pfsoc_sysreg_ops = {
235
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_sysreg_realize(DeviceState *dev, Error **errp)
236
"mchp.pfsoc.sysreg",
237
MCHP_PFSOC_SYSREG_REG_SIZE);
238
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sysreg);
239
+ sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq);
240
}
241
242
static void mchp_pfsoc_sysreg_class_init(ObjectClass *klass, void *data)
243
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
244
index XXXXXXX..XXXXXXX 100644
245
--- a/hw/riscv/microchip_pfsoc.c
246
+++ b/hw/riscv/microchip_pfsoc.c
247
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
248
sysbus_realize(SYS_BUS_DEVICE(&s->sysreg), errp);
249
sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysreg), 0,
250
memmap[MICROCHIP_PFSOC_SYSREG].base);
251
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->sysreg), 0,
252
+ qdev_get_gpio_in(DEVICE(s->plic),
253
+ MICROCHIP_PFSOC_MAILBOX_IRQ));
254
255
/* AXISW */
256
create_unimplemented_device("microchip.pfsoc.axisw",
257
@@ -XXX,XX +XXX,XX @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
258
sysbus_realize(SYS_BUS_DEVICE(&s->ioscb), errp);
259
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
260
memmap[MICROCHIP_PFSOC_IOSCB].base);
261
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->ioscb), 0,
262
+ qdev_get_gpio_in(DEVICE(s->plic),
263
+ MICROCHIP_PFSOC_MAILBOX_IRQ));
264
265
/* FPGA Fabric */
266
create_unimplemented_device("microchip.pfsoc.fabricfic3",
267
--
268
2.38.1
diff view generated by jsdifflib
New patch
1
From: Jim Shu <jim.shu@sifive.com>
1
2
3
If the number of interrupt is not multiple of 32, PLIC will have
4
out-of-bound access to source_priority array. Compute the number of
5
interrupt in the last word to avoid this out-of-bound access of array.
6
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Bin Meng <bmeng@tinylab.org>
9
Message-Id: <20221127165753.30533-1-jim.shu@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/intc/sifive_plic.c | 12 +++++++++++-
13
1 file changed, 11 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/sifive_plic.c
18
+++ b/hw/intc/sifive_plic.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
20
uint32_t max_irq = 0;
21
uint32_t max_prio = plic->target_priority[addrid];
22
int i, j;
23
+ int num_irq_in_word = 32;
24
25
for (i = 0; i < plic->bitfield_words; i++) {
26
uint32_t pending_enabled_not_claimed =
27
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
28
continue;
29
}
30
31
- for (j = 0; j < 32; j++) {
32
+ if (i == (plic->bitfield_words - 1)) {
33
+ /*
34
+ * If plic->num_sources is not multiple of 32, num-of-irq in last
35
+ * word is not 32. Compute the num-of-irq of last word to avoid
36
+ * out-of-bound access of source_priority array.
37
+ */
38
+ num_irq_in_word = plic->num_sources - ((plic->bitfield_words - 1) << 5);
39
+ }
40
+
41
+ for (j = 0; j < num_irq_in_word; j++) {
42
int irq = (i << 5) + j;
43
uint32_t prio = plic->source_priority[irq];
44
int enabled = pending_enabled_not_claimed & (1 << j);
45
--
46
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
The priv spec v1.12 says:
4
5
If no PMP entry matches an M-mode access, the access succeeds. If
6
no PMP entry matches an S-mode or U-mode access, but at least one
7
PMP entry is implemented, the access fails. Failed accesses generate
8
an instruction, load, or store access-fault exception.
9
10
At present the exception cause is set to 'illegal instruction' but
11
should have been 'instruction access fault'.
12
13
Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is configured")
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
15
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-Id: <20221205065303.204095-1-bmeng@tinylab.org>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
20
target/riscv/op_helper.c | 2 +-
21
1 file changed, 1 insertion(+), 1 deletion(-)
22
23
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/op_helper.c
26
+++ b/target/riscv/op_helper.c
27
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
28
29
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
30
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
31
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
32
+ riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
33
}
34
35
target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
36
--
37
2.38.1
diff view generated by jsdifflib
New patch
1
From: Richard Henderson <richard.henderson@linaro.org>
1
2
3
Failure to set pc_succ_insn may result in a TB covering zero bytes,
4
which triggers an assert within the code generator.
5
6
Cc: qemu-stable@nongnu.org
7
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1224
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-Id: <20221203175744.151365-1-richard.henderson@linaro.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
target/riscv/translate.c | 12 ++++--------
15
tests/tcg/Makefile.target | 2 ++
16
tests/tcg/riscv64/Makefile.target | 5 +++++
17
tests/tcg/riscv64/test-noc.S | 32 +++++++++++++++++++++++++++++++
18
4 files changed, 43 insertions(+), 8 deletions(-)
19
create mode 100644 tests/tcg/riscv64/test-noc.S
20
21
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/translate.c
24
+++ b/target/riscv/translate.c
25
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
26
ctx->virt_inst_excp = false;
27
/* Check for compressed insn */
28
if (insn_len(opcode) == 2) {
29
- if (!has_ext(ctx, RVC)) {
30
- gen_exception_illegal(ctx);
31
- } else {
32
- ctx->opcode = opcode;
33
- ctx->pc_succ_insn = ctx->base.pc_next + 2;
34
- if (decode_insn16(ctx, opcode)) {
35
- return;
36
- }
37
+ ctx->opcode = opcode;
38
+ ctx->pc_succ_insn = ctx->base.pc_next + 2;
39
+ if (has_ext(ctx, RVC) && decode_insn16(ctx, opcode)) {
40
+ return;
41
}
42
} else {
43
uint32_t opcode32 = opcode;
44
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
45
index XXXXXXX..XXXXXXX 100644
46
--- a/tests/tcg/Makefile.target
47
+++ b/tests/tcg/Makefile.target
48
@@ -XXX,XX +XXX,XX @@ endif
49
50
%: %.c
51
    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
52
+%: %.S
53
+    $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS)
54
else
55
# For softmmu targets we include a different Makefile fragement as the
56
# build options for bare programs are usually pretty different. They
57
diff --git a/tests/tcg/riscv64/Makefile.target b/tests/tcg/riscv64/Makefile.target
58
index XXXXXXX..XXXXXXX 100644
59
--- a/tests/tcg/riscv64/Makefile.target
60
+++ b/tests/tcg/riscv64/Makefile.target
61
@@ -XXX,XX +XXX,XX @@
62
VPATH += $(SRC_PATH)/tests/tcg/riscv64
63
TESTS += test-div
64
TESTS += noexec
65
+
66
+# Disable compressed instructions for test-noc
67
+TESTS += test-noc
68
+test-noc: LDFLAGS = -nostdlib -static
69
+run-test-noc: QEMU_OPTS += -cpu rv64,c=false
70
diff --git a/tests/tcg/riscv64/test-noc.S b/tests/tcg/riscv64/test-noc.S
71
new file mode 100644
72
index XXXXXXX..XXXXXXX
73
--- /dev/null
74
+++ b/tests/tcg/riscv64/test-noc.S
75
@@ -XXX,XX +XXX,XX @@
76
+#include <asm/unistd.h>
77
+
78
+    .text
79
+    .globl _start
80
+_start:
81
+    .option    norvc
82
+    li    a0, 4        /* SIGILL */
83
+    la    a1, sa
84
+    li    a2, 0
85
+    li    a3, 8
86
+    li    a7, __NR_rt_sigaction
87
+    scall
88
+
89
+    .option    rvc
90
+    li    a0, 1
91
+    j    exit
92
+    .option    norvc
93
+
94
+pass:
95
+    li    a0, 0
96
+exit:
97
+    li    a7, __NR_exit
98
+    scall
99
+
100
+    .data
101
+    /* struct kernel_sigaction sa = { .sa_handler = pass }; */
102
+    .type    sa, @object
103
+    .size    sa, 32
104
+sa:
105
+    .dword    pass
106
+    .zero    24
107
+
108
--
109
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
There are 2 paths in helper_sret() and the same mstatus update codes
4
are replicated. Extract the common parts to simplify it a little bit.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221207090037.281452-1-bmeng@tinylab.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/op_helper.c | 20 ++++++--------------
12
1 file changed, 6 insertions(+), 14 deletions(-)
13
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/op_helper.c
17
+++ b/target/riscv/op_helper.c
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
19
}
20
21
mstatus = env->mstatus;
22
+ prev_priv = get_field(mstatus, MSTATUS_SPP);
23
+ mstatus = set_field(mstatus, MSTATUS_SIE,
24
+ get_field(mstatus, MSTATUS_SPIE));
25
+ mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
26
+ mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
27
+ env->mstatus = mstatus;
28
29
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
30
/* We support Hypervisor extensions and virtulisation is disabled */
31
target_ulong hstatus = env->hstatus;
32
33
- prev_priv = get_field(mstatus, MSTATUS_SPP);
34
prev_virt = get_field(hstatus, HSTATUS_SPV);
35
36
hstatus = set_field(hstatus, HSTATUS_SPV, 0);
37
- mstatus = set_field(mstatus, MSTATUS_SPP, 0);
38
- mstatus = set_field(mstatus, SSTATUS_SIE,
39
- get_field(mstatus, SSTATUS_SPIE));
40
- mstatus = set_field(mstatus, SSTATUS_SPIE, 1);
41
42
- env->mstatus = mstatus;
43
env->hstatus = hstatus;
44
45
if (prev_virt) {
46
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
47
}
48
49
riscv_cpu_set_virt_enabled(env, prev_virt);
50
- } else {
51
- prev_priv = get_field(mstatus, MSTATUS_SPP);
52
-
53
- mstatus = set_field(mstatus, MSTATUS_SIE,
54
- get_field(mstatus, MSTATUS_SPIE));
55
- mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
56
- mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
57
- env->mstatus = mstatus;
58
}
59
60
riscv_cpu_set_mode(env, prev_priv);
61
--
62
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
Since priv spec v1.12, MRET and SRET now clear mstatus.MPRV when
4
leaving M-mode.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221207090037.281452-2-bmeng@tinylab.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/op_helper.c | 6 ++++++
12
1 file changed, 6 insertions(+)
13
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/op_helper.c
17
+++ b/target/riscv/op_helper.c
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
19
get_field(mstatus, MSTATUS_SPIE));
20
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
21
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
22
+ if (env->priv_ver >= PRIV_VERSION_1_12_0) {
23
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
24
+ }
25
env->mstatus = mstatus;
26
27
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
28
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
29
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
30
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
31
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
32
+ if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
33
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
34
+ }
35
env->mstatus = mstatus;
36
riscv_cpu_set_mode(env, prev_priv);
37
38
--
39
2.38.1
diff view generated by jsdifflib
New patch
1
From: Christoph Muellner <christoph.muellner@vrull.eu>
1
2
3
This patch adds support for the Zawrs ISA extension.
4
Given the current (incomplete) implementation of reservation sets
5
there seems to be no way to provide a full emulation of the WRS
6
instruction (wake on reservation set invalidation or timeout or
7
interrupt). Therefore, we just exit the TB and return to the main loop.
8
9
The specification can be found here:
10
https://github.com/riscv/riscv-zawrs/blob/main/zawrs.adoc
11
12
Note, that the Zawrs extension is frozen, but not ratified yet.
13
14
Changes since v3:
15
* Remove "RFC" since the extension is frozen
16
* Rebase on master and fix integration issues
17
* Fix entry ordering in extension list
18
19
Changes since v2:
20
* Rebase on master and resolve conflicts
21
* Adjustments according to a specification change
22
* Inline REQUIRE_ZAWRS() since it has only one user
23
24
Changes since v1:
25
* Adding zawrs to the ISA string that is passed to the kernel
26
27
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
28
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
29
Message-Id: <20221005144948.3421504-1-christoph.muellner@vrull.eu>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
32
target/riscv/cpu.h | 1 +
33
target/riscv/insn32.decode | 4 ++
34
target/riscv/cpu.c | 7 +++
35
target/riscv/translate.c | 1 +
36
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 +++++++++++++++++++++
37
5 files changed, 64 insertions(+)
38
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
39
40
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/cpu.h
43
+++ b/target/riscv/cpu.h
44
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
45
bool ext_svnapot;
46
bool ext_svpbmt;
47
bool ext_zdinx;
48
+ bool ext_zawrs;
49
bool ext_zfh;
50
bool ext_zfhmin;
51
bool ext_zfinx;
52
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
53
index XXXXXXX..XXXXXXX 100644
54
--- a/target/riscv/insn32.decode
55
+++ b/target/riscv/insn32.decode
56
@@ -XXX,XX +XXX,XX @@ vsetvli 0 ........... ..... 111 ..... 1010111 @r2_zimm11
57
vsetivli 11 .......... ..... 111 ..... 1010111 @r2_zimm10
58
vsetvl 1000000 ..... ..... 111 ..... 1010111 @r
59
60
+# *** Zawrs Standard Extension ***
61
+wrs_nto 000000001101 00000 000 00000 1110011
62
+wrs_sto 000000011101 00000 000 00000 1110011
63
+
64
# *** RV32 Zba Standard Extension ***
65
sh1add 0010000 .......... 010 ..... 0110011 @r
66
sh2add 0010000 .......... 100 ..... 0110011 @r
67
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/target/riscv/cpu.c
70
+++ b/target/riscv/cpu.c
71
@@ -XXX,XX +XXX,XX @@ static const struct isa_ext_data isa_edata_arr[] = {
72
ISA_EXT_DATA_ENTRY(zicsr, true, PRIV_VERSION_1_10_0, ext_icsr),
73
ISA_EXT_DATA_ENTRY(zifencei, true, PRIV_VERSION_1_10_0, ext_ifencei),
74
ISA_EXT_DATA_ENTRY(zihintpause, true, PRIV_VERSION_1_10_0, ext_zihintpause),
75
+ ISA_EXT_DATA_ENTRY(zawrs, true, PRIV_VERSION_1_12_0, ext_zawrs),
76
ISA_EXT_DATA_ENTRY(zfh, true, PRIV_VERSION_1_12_0, ext_zfh),
77
ISA_EXT_DATA_ENTRY(zfhmin, true, PRIV_VERSION_1_12_0, ext_zfhmin),
78
ISA_EXT_DATA_ENTRY(zfinx, true, PRIV_VERSION_1_12_0, ext_zfinx),
79
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
80
return;
81
}
82
83
+ if ((cpu->cfg.ext_zawrs) && !cpu->cfg.ext_a) {
84
+ error_setg(errp, "Zawrs extension requires A extension");
85
+ return;
86
+ }
87
+
88
if ((cpu->cfg.ext_zfh || cpu->cfg.ext_zfhmin) && !cpu->cfg.ext_f) {
89
error_setg(errp, "Zfh/Zfhmin extensions require F extension");
90
return;
91
@@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_extensions[] = {
92
DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
93
DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
94
DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause, true),
95
+ DEFINE_PROP_BOOL("Zawrs", RISCVCPU, cfg.ext_zawrs, true),
96
DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
97
DEFINE_PROP_BOOL("Zfhmin", RISCVCPU, cfg.ext_zfhmin, false),
98
DEFINE_PROP_BOOL("Zve32f", RISCVCPU, cfg.ext_zve32f, false),
99
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/target/riscv/translate.c
102
+++ b/target/riscv/translate.c
103
@@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc)
104
#include "insn_trans/trans_rvh.c.inc"
105
#include "insn_trans/trans_rvv.c.inc"
106
#include "insn_trans/trans_rvb.c.inc"
107
+#include "insn_trans/trans_rvzawrs.c.inc"
108
#include "insn_trans/trans_rvzfh.c.inc"
109
#include "insn_trans/trans_rvk.c.inc"
110
#include "insn_trans/trans_privileged.c.inc"
111
diff --git a/target/riscv/insn_trans/trans_rvzawrs.c.inc b/target/riscv/insn_trans/trans_rvzawrs.c.inc
112
new file mode 100644
113
index XXXXXXX..XXXXXXX
114
--- /dev/null
115
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
116
@@ -XXX,XX +XXX,XX @@
117
+/*
118
+ * RISC-V translation routines for the RISC-V Zawrs Extension.
119
+ *
120
+ * Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.io
121
+ *
122
+ * This program is free software; you can redistribute it and/or modify it
123
+ * under the terms and conditions of the GNU General Public License,
124
+ * version 2 or later, as published by the Free Software Foundation.
125
+ *
126
+ * This program is distributed in the hope it will be useful, but WITHOUT
127
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
128
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
129
+ * more details.
130
+ *
131
+ * You should have received a copy of the GNU General Public License along with
132
+ * this program. If not, see <http://www.gnu.org/licenses/>.
133
+ */
134
+
135
+static bool trans_wrs(DisasContext *ctx)
136
+{
137
+ if (!ctx->cfg_ptr->ext_zawrs) {
138
+ return false;
139
+ }
140
+
141
+ /*
142
+ * The specification says:
143
+ * While stalled, an implementation is permitted to occasionally
144
+ * terminate the stall and complete execution for any reason.
145
+ *
146
+ * So let's just exit TB and return to the main loop.
147
+ */
148
+
149
+ /* Clear the load reservation (if any). */
150
+ tcg_gen_movi_tl(load_res, -1);
151
+
152
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
153
+ tcg_gen_exit_tb(NULL, 0);
154
+ ctx->base.is_jmp = DISAS_NORETURN;
155
+
156
+ return true;
157
+}
158
+
159
+#define GEN_TRANS_WRS(insn) \
160
+static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
161
+{ \
162
+ (void)a; \
163
+ return trans_wrs(ctx); \
164
+}
165
+
166
+GEN_TRANS_WRS(wrs_nto)
167
+GEN_TRANS_WRS(wrs_sto)
168
--
169
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
4
controllers regardless of how MSI is implemented. msi_nonbroken is
5
initialized to true in sifive_plic_realize().
6
7
Let SIFIVE_PLIC select MSI_NONBROKEN and drop the selection from
8
RISC-V machines.
9
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
14
Message-Id: <20221211030829.802437-1-bmeng@tinylab.org>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
hw/intc/Kconfig | 1 +
18
hw/riscv/Kconfig | 5 -----
19
2 files changed, 1 insertion(+), 5 deletions(-)
20
21
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/intc/Kconfig
24
+++ b/hw/intc/Kconfig
25
@@ -XXX,XX +XXX,XX @@ config RISCV_IMSIC
26
27
config SIFIVE_PLIC
28
bool
29
+ select MSI_NONBROKEN
30
31
config GOLDFISH_PIC
32
bool
33
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/riscv/Kconfig
36
+++ b/hw/riscv/Kconfig
37
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
38
select MCHP_PFSOC_IOSCB
39
select MCHP_PFSOC_MMUART
40
select MCHP_PFSOC_SYSREG
41
- select MSI_NONBROKEN
42
select RISCV_ACLINT
43
select SIFIVE_PDMA
44
select SIFIVE_PLIC
45
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
46
imply TPM_TIS_SYSBUS
47
select RISCV_NUMA
48
select GOLDFISH_RTC
49
- select MSI_NONBROKEN
50
select PCI
51
select PCI_EXPRESS_GENERIC_BRIDGE
52
select PFLASH_CFI01
53
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
54
55
config SIFIVE_E
56
bool
57
- select MSI_NONBROKEN
58
select RISCV_ACLINT
59
select SIFIVE_GPIO
60
select SIFIVE_PLIC
61
@@ -XXX,XX +XXX,XX @@ config SIFIVE_E
62
config SIFIVE_U
63
bool
64
select CADENCE
65
- select MSI_NONBROKEN
66
select RISCV_ACLINT
67
select SIFIVE_GPIO
68
select SIFIVE_PDMA
69
@@ -XXX,XX +XXX,XX @@ config SPIKE
70
bool
71
select RISCV_NUMA
72
select HTIF
73
- select MSI_NONBROKEN
74
select RISCV_ACLINT
75
select SIFIVE_PLIC
76
--
77
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
4
controllers regardless of how MSI is implemented. msi_nonbroken is
5
initialized to true in both riscv_aplic_realize() and
6
riscv_imsic_realize().
7
8
Select MSI_NONBROKEN in RISCV_APLIC and RISCV_IMSIC.
9
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-Id: <20221211030829.802437-2-bmeng@tinylab.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
hw/intc/Kconfig | 2 ++
17
1 file changed, 2 insertions(+)
18
19
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/Kconfig
22
+++ b/hw/intc/Kconfig
23
@@ -XXX,XX +XXX,XX @@ config RISCV_ACLINT
24
25
config RISCV_APLIC
26
bool
27
+ select MSI_NONBROKEN
28
29
config RISCV_IMSIC
30
bool
31
+ select MSI_NONBROKEN
32
33
config SIFIVE_PLIC
34
bool
35
--
36
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
Since commit ef6310064820 ("hw/riscv: opentitan: Update to the latest build")
4
the IBEX PLIC model was replaced with the SiFive PLIC model in the
5
'opentitan' machine but we forgot the add the dependency there.
6
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221211030829.802437-3-bmeng@tinylab.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/riscv/Kconfig | 1 +
14
1 file changed, 1 insertion(+)
15
16
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/Kconfig
19
+++ b/hw/riscv/Kconfig
20
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
21
config OPENTITAN
22
bool
23
select IBEX
24
+ select SIFIVE_PLIC
25
select UNIMP
26
27
config SHAKTI_C
28
--
29
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
SHAKTI_C machine Kconfig option was inserted in disorder. Fix it.
4
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Message-Id: <20221211030829.802437-4-bmeng@tinylab.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/riscv/Kconfig | 16 +++++++++-------
13
1 file changed, 9 insertions(+), 7 deletions(-)
14
15
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/Kconfig
18
+++ b/hw/riscv/Kconfig
19
@@ -XXX,XX +XXX,XX @@ config RISCV_NUMA
20
config IBEX
21
bool
22
23
+# RISC-V machines in alphabetical order
24
+
25
config MICROCHIP_PFSOC
26
bool
27
select CADENCE_SDHCI
28
@@ -XXX,XX +XXX,XX @@ config OPENTITAN
29
select SIFIVE_PLIC
30
select UNIMP
31
32
-config SHAKTI_C
33
- bool
34
- select UNIMP
35
- select SHAKTI_UART
36
- select RISCV_ACLINT
37
- select SIFIVE_PLIC
38
-
39
config RISCV_VIRT
40
bool
41
imply PCI_DEVICES
42
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
43
select FW_CFG_DMA
44
select PLATFORM_BUS
45
46
+config SHAKTI_C
47
+ bool
48
+ select RISCV_ACLINT
49
+ select SHAKTI_UART
50
+ select SIFIVE_PLIC
51
+ select UNIMP
52
+
53
config SIFIVE_E
54
bool
55
select RISCV_ACLINT
56
--
57
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
PLIC is not included in the 'spike' machine.
4
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221211030829.802437-5-bmeng@tinylab.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
hw/riscv/spike.c | 1 -
12
1 file changed, 1 deletion(-)
13
14
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/spike.c
17
+++ b/hw/riscv/spike.c
18
@@ -XXX,XX +XXX,XX @@
19
*
20
* 0) HTIF Console and Poweroff
21
* 1) CLINT (Timer and IPI)
22
- * 2) PLIC (Platform Level Interrupt Controller)
23
*
24
* This program is free software; you can redistribute it and/or modify it
25
* under the terms and conditions of the GNU General Public License,
26
--
27
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
H-mode has been removed since priv spec 1.10. Drop it.
4
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221211030829.802437-6-bmeng@tinylab.org>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
include/hw/intc/sifive_plic.h | 1 -
12
hw/intc/sifive_plic.c | 1 -
13
2 files changed, 2 deletions(-)
14
15
diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/sifive_plic.h
18
+++ b/include/hw/intc/sifive_plic.h
19
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(SiFivePLICState, SIFIVE_PLIC,
20
typedef enum PLICMode {
21
PLICMode_U,
22
PLICMode_S,
23
- PLICMode_H,
24
PLICMode_M
25
} PLICMode;
26
27
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/sifive_plic.c
30
+++ b/hw/intc/sifive_plic.c
31
@@ -XXX,XX +XXX,XX @@ static PLICMode char_to_mode(char c)
32
switch (c) {
33
case 'U': return PLICMode_U;
34
case 'S': return PLICMode_S;
35
- case 'H': return PLICMode_H;
36
case 'M': return PLICMode_M;
37
default:
38
error_report("plic: invalid mode '%c'", c);
39
--
40
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
At present the PLIC config parser can only handle legal config string
4
like "MS,MS". However if a config string like ",MS,MS,,MS,MS,," is
5
given the parser won't get the correct configuration.
6
7
This commit improves the config parser to make it more robust.
8
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221211030829.802437-7-bmeng@tinylab.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
hw/intc/sifive_plic.c | 24 ++++++++++++++++--------
15
1 file changed, 16 insertions(+), 8 deletions(-)
16
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/sifive_plic.c
20
+++ b/hw/intc/sifive_plic.c
21
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_reset(DeviceState *dev)
22
*/
23
static void parse_hart_config(SiFivePLICState *plic)
24
{
25
- int addrid, hartid, modes;
26
+ int addrid, hartid, modes, m;
27
const char *p;
28
char c;
29
30
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
31
p = plic->hart_config;
32
while ((c = *p++)) {
33
if (c == ',') {
34
- addrid += ctpop8(modes);
35
- modes = 0;
36
- hartid++;
37
+ if (modes) {
38
+ addrid += ctpop8(modes);
39
+ hartid++;
40
+ modes = 0;
41
+ }
42
} else {
43
- int m = 1 << char_to_mode(c);
44
+ m = 1 << char_to_mode(c);
45
if (modes == (modes | m)) {
46
error_report("plic: duplicate mode '%c' in config: %s",
47
c, plic->hart_config);
48
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
49
}
50
if (modes) {
51
addrid += ctpop8(modes);
52
+ hartid++;
53
+ modes = 0;
54
}
55
- hartid++;
56
57
plic->num_addrs = addrid;
58
plic->num_harts = hartid;
59
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
60
p = plic->hart_config;
61
while ((c = *p++)) {
62
if (c == ',') {
63
- hartid++;
64
+ if (modes) {
65
+ hartid++;
66
+ modes = 0;
67
+ }
68
} else {
69
+ m = char_to_mode(c);
70
plic->addr_config[addrid].addrid = addrid;
71
plic->addr_config[addrid].hartid = hartid;
72
- plic->addr_config[addrid].mode = char_to_mode(c);
73
+ plic->addr_config[addrid].mode = m;
74
+ modes |= (1 << m);
75
addrid++;
76
}
77
}
78
--
79
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
The realize() callback has an errp for us to propagate the error up.
4
While we are here, correct the wrong multi-line comment format.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-Id: <20221211030829.802437-8-bmeng@tinylab.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/intc/sifive_plic.c | 7 ++++---
13
1 file changed, 4 insertions(+), 3 deletions(-)
14
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/sifive_plic.c
18
+++ b/hw/intc/sifive_plic.c
19
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
20
s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
21
qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
22
23
- /* We can't allow the supervisor to control SEIP as this would allow the
24
+ /*
25
+ * We can't allow the supervisor to control SEIP as this would allow the
26
* supervisor to clear a pending external interrupt which will result in
27
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
28
* hardware controlled when a PLIC is attached.
29
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
30
for (i = 0; i < s->num_harts; i++) {
31
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
32
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
33
- error_report("SEIP already claimed");
34
- exit(1);
35
+ error_setg(errp, "SEIP already claimed");
36
+ return;
37
}
38
}
39
40
--
41
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
At present the default value of "num-sources" property is zero,
4
which does not make a lot of sense, as in sifive_plic_realize()
5
we see s->bitfield_words is calculated by:
6
7
s->bitfield_words = (s->num_sources + 31) >> 5;
8
9
if the we don't configure "num-sources" property its default value
10
zero makes s->bitfield_words zero too, which isn't true because
11
interrupt source 0 still occupies one word.
12
13
Let's change the default value to 1 meaning that only interrupt
14
source 0 is supported by default and a sanity check in realize().
15
16
While we are here, add a comment to describe the exact meaning of
17
this property that the number should include interrupt source 0.
18
19
Signed-off-by: Bin Meng <bmeng@tinylab.org>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20221211030829.802437-9-bmeng@tinylab.org>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
hw/intc/sifive_plic.c | 8 +++++++-
25
1 file changed, 7 insertions(+), 1 deletion(-)
26
27
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/sifive_plic.c
30
+++ b/hw/intc/sifive_plic.c
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
32
33
parse_hart_config(s);
34
35
+ if (!s->num_sources) {
36
+ error_setg(errp, "plic: invalid number of interrupt sources");
37
+ return;
38
+ }
39
+
40
s->bitfield_words = (s->num_sources + 31) >> 5;
41
s->num_enables = s->bitfield_words * s->num_addrs;
42
s->source_priority = g_new0(uint32_t, s->num_sources);
43
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_sifive_plic = {
44
static Property sifive_plic_properties[] = {
45
DEFINE_PROP_STRING("hart-config", SiFivePLICState, hart_config),
46
DEFINE_PROP_UINT32("hartid-base", SiFivePLICState, hartid_base, 0),
47
- DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 0),
48
+ /* number of interrupt sources including interrupt source 0 */
49
+ DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
50
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
51
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
52
DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
53
--
54
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
Per chapter 6.5.2 in [1], the number of interupt sources including
4
interrupt source 0 should be 187.
5
6
[1] PolarFire SoC MSS TRM:
7
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/ReferenceManuals/PolarFire_SoC_FPGA_MSS_Technical_Reference_Manual_VC.pdf
8
9
Fixes: 56f6e31e7b7e ("hw/riscv: Initial support for Microchip PolarFire SoC Icicle Kit board")
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
14
Message-Id: <20221211030829.802437-10-bmeng@tinylab.org>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
include/hw/riscv/microchip_pfsoc.h | 2 +-
18
1 file changed, 1 insertion(+), 1 deletion(-)
19
20
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/microchip_pfsoc.h
23
+++ b/include/hw/riscv/microchip_pfsoc.h
24
@@ -XXX,XX +XXX,XX @@ enum {
25
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
26
#define MICROCHIP_PFSOC_COMPUTE_CPU_COUNT 4
27
28
-#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 185
29
+#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
30
#define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
31
#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04
32
#define MICROCHIP_PFSOC_PLIC_PENDING_BASE 0x1000
33
--
34
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
Per chapter 10 in Freedom E310 manuals [1][2][3], E310 G002 and G003
4
supports 52 interrupt sources while G000 supports 51 interrupt sources.
5
6
We use the value of G002 and G003, so it is 53 (including source 0).
7
8
[1] G000 manual:
9
https://sifive.cdn.prismic.io/sifive/4faf3e34-4a42-4c2f-be9e-c77baa4928c7_fe310-g000-manual-v3p2.pdf
10
11
[2] G002 manual:
12
https://sifive.cdn.prismic.io/sifive/034760b5-ac6a-4b1c-911c-f4148bb2c4a5_fe310-g002-v1p5.pdf
13
14
[3] G003 manual:
15
https://sifive.cdn.prismic.io/sifive/3af39c59-6498-471e-9dab-5355a0d539eb_fe310-g003-manual.pdf
16
17
Fixes: eb637edb1241 ("SiFive Freedom E Series RISC-V Machine")
18
Signed-off-by: Bin Meng <bmeng@tinylab.org>
19
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20221211030829.802437-11-bmeng@tinylab.org>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
include/hw/riscv/sifive_e.h | 7 ++++++-
25
1 file changed, 6 insertions(+), 1 deletion(-)
26
27
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
28
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/riscv/sifive_e.h
30
+++ b/include/hw/riscv/sifive_e.h
31
@@ -XXX,XX +XXX,XX @@ enum {
32
};
33
34
#define SIFIVE_E_PLIC_HART_CONFIG "M"
35
-#define SIFIVE_E_PLIC_NUM_SOURCES 127
36
+/*
37
+ * Freedom E310 G002 and G003 supports 52 interrupt sources while
38
+ * Freedom E310 G000 supports 51 interrupt sources. We use the value
39
+ * of G002 and G003, so it is 53 (including interrupt source 0).
40
+ */
41
+#define SIFIVE_E_PLIC_NUM_SOURCES 53
42
#define SIFIVE_E_PLIC_NUM_PRIORITIES 7
43
#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
44
#define SIFIVE_E_PLIC_PENDING_BASE 0x1000
45
--
46
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
At present magic number is used to create "riscv,ndev" property
4
in the dtb. Let's use the macro SIFIVE_U_PLIC_NUM_SOURCES that
5
is used to instantiate the PLIC model instead.
6
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221211030829.802437-12-bmeng@tinylab.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
hw/riscv/sifive_u.c | 3 ++-
14
1 file changed, 2 insertions(+), 1 deletion(-)
15
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
19
+++ b/hw/riscv/sifive_u.c
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
21
qemu_fdt_setprop_cells(fdt, nodename, "reg",
22
0x0, memmap[SIFIVE_U_DEV_PLIC].base,
23
0x0, memmap[SIFIVE_U_DEV_PLIC].size);
24
- qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
25
+ qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev",
26
+ SIFIVE_U_PLIC_NUM_SOURCES - 1);
27
qemu_fdt_setprop_cell(fdt, nodename, "phandle", plic_phandle);
28
plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
29
g_free(cells);
30
--
31
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
Commit 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
4
changed the value of VIRT_IRQCHIP_NUM_SOURCES from 127 to 53, which
5
is VIRTIO_NDEV and also used as the value of "riscv,ndev" property
6
in the dtb. Unfortunately this is wrong as VIRT_IRQCHIP_NUM_SOURCES
7
should include interrupt source 0 but "riscv,ndev" does not.
8
9
While we are here, we also fix the comments of platform bus irq range
10
which is now "64 to 96", but should be "64 to 95", introduced since
11
commit 1832b7cb3f64 ("hw/riscv: virt: Create a platform bus").
12
13
Fixes: 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-Id: <20221211030829.802437-13-bmeng@tinylab.org>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/riscv/virt.h | 5 ++---
20
hw/riscv/virt.c | 3 ++-
21
2 files changed, 4 insertions(+), 4 deletions(-)
22
23
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
24
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/virt.h
26
+++ b/include/hw/riscv/virt.h
27
@@ -XXX,XX +XXX,XX @@ enum {
28
VIRTIO_IRQ = 1, /* 1 to 8 */
29
VIRTIO_COUNT = 8,
30
PCIE_IRQ = 0x20, /* 32 to 35 */
31
- VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */
32
- VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */
33
+ VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
34
};
35
36
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
37
38
#define VIRT_IRQCHIP_NUM_MSIS 255
39
-#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
40
+#define VIRT_IRQCHIP_NUM_SOURCES 96
41
#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
42
#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
43
#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
44
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
45
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/riscv/virt.c
47
+++ b/hw/riscv/virt.c
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
49
plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
50
qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
51
0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
52
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev", VIRTIO_NDEV);
53
+ qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
54
+ VIRT_IRQCHIP_NUM_SOURCES - 1);
55
riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
56
qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
57
plic_phandles[socket]);
58
--
59
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
At present the SiFive PLIC model "priority-base" expects interrupt
4
priority register base starting from source 1 instead source 0,
5
that's why on most platforms "priority-base" is set to 0x04 except
6
'opentitan' machine. 'opentitan' should have set "priority-base"
7
to 0x04 too.
8
9
Note the irq number calculation in sifive_plic_{read,write} is
10
correct as the codes make up for the irq number by adding 1.
11
12
Let's simply update "priority-base" to start from interrupt source
13
0 and add a comment to make it crystal clear.
14
15
Signed-off-by: Bin Meng <bmeng@tinylab.org>
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
18
Message-Id: <20221211030829.802437-14-bmeng@tinylab.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
21
include/hw/riscv/microchip_pfsoc.h | 2 +-
22
include/hw/riscv/shakti_c.h | 2 +-
23
include/hw/riscv/sifive_e.h | 2 +-
24
include/hw/riscv/sifive_u.h | 2 +-
25
include/hw/riscv/virt.h | 2 +-
26
hw/intc/sifive_plic.c | 5 +++--
27
6 files changed, 8 insertions(+), 7 deletions(-)
28
29
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/riscv/microchip_pfsoc.h
32
+++ b/include/hw/riscv/microchip_pfsoc.h
33
@@ -XXX,XX +XXX,XX @@ enum {
34
35
#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
36
#define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
37
-#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04
38
+#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x00
39
#define MICROCHIP_PFSOC_PLIC_PENDING_BASE 0x1000
40
#define MICROCHIP_PFSOC_PLIC_ENABLE_BASE 0x2000
41
#define MICROCHIP_PFSOC_PLIC_ENABLE_STRIDE 0x80
42
diff --git a/include/hw/riscv/shakti_c.h b/include/hw/riscv/shakti_c.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/include/hw/riscv/shakti_c.h
45
+++ b/include/hw/riscv/shakti_c.h
46
@@ -XXX,XX +XXX,XX @@ enum {
47
#define SHAKTI_C_PLIC_NUM_SOURCES 28
48
/* Excluding Priority 0 */
49
#define SHAKTI_C_PLIC_NUM_PRIORITIES 2
50
-#define SHAKTI_C_PLIC_PRIORITY_BASE 0x04
51
+#define SHAKTI_C_PLIC_PRIORITY_BASE 0x00
52
#define SHAKTI_C_PLIC_PENDING_BASE 0x1000
53
#define SHAKTI_C_PLIC_ENABLE_BASE 0x2000
54
#define SHAKTI_C_PLIC_ENABLE_STRIDE 0x80
55
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/include/hw/riscv/sifive_e.h
58
+++ b/include/hw/riscv/sifive_e.h
59
@@ -XXX,XX +XXX,XX @@ enum {
60
*/
61
#define SIFIVE_E_PLIC_NUM_SOURCES 53
62
#define SIFIVE_E_PLIC_NUM_PRIORITIES 7
63
-#define SIFIVE_E_PLIC_PRIORITY_BASE 0x04
64
+#define SIFIVE_E_PLIC_PRIORITY_BASE 0x00
65
#define SIFIVE_E_PLIC_PENDING_BASE 0x1000
66
#define SIFIVE_E_PLIC_ENABLE_BASE 0x2000
67
#define SIFIVE_E_PLIC_ENABLE_STRIDE 0x80
68
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
69
index XXXXXXX..XXXXXXX 100644
70
--- a/include/hw/riscv/sifive_u.h
71
+++ b/include/hw/riscv/sifive_u.h
72
@@ -XXX,XX +XXX,XX @@ enum {
73
74
#define SIFIVE_U_PLIC_NUM_SOURCES 54
75
#define SIFIVE_U_PLIC_NUM_PRIORITIES 7
76
-#define SIFIVE_U_PLIC_PRIORITY_BASE 0x04
77
+#define SIFIVE_U_PLIC_PRIORITY_BASE 0x00
78
#define SIFIVE_U_PLIC_PENDING_BASE 0x1000
79
#define SIFIVE_U_PLIC_ENABLE_BASE 0x2000
80
#define SIFIVE_U_PLIC_ENABLE_STRIDE 0x80
81
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
82
index XXXXXXX..XXXXXXX 100644
83
--- a/include/hw/riscv/virt.h
84
+++ b/include/hw/riscv/virt.h
85
@@ -XXX,XX +XXX,XX @@ enum {
86
#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
87
#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
88
89
-#define VIRT_PLIC_PRIORITY_BASE 0x04
90
+#define VIRT_PLIC_PRIORITY_BASE 0x00
91
#define VIRT_PLIC_PENDING_BASE 0x1000
92
#define VIRT_PLIC_ENABLE_BASE 0x2000
93
#define VIRT_PLIC_ENABLE_STRIDE 0x80
94
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
95
index XXXXXXX..XXXXXXX 100644
96
--- a/hw/intc/sifive_plic.c
97
+++ b/hw/intc/sifive_plic.c
98
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
99
SiFivePLICState *plic = opaque;
100
101
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
102
- uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
103
+ uint32_t irq = (addr - plic->priority_base) >> 2;
104
105
return plic->source_priority[irq];
106
} else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
107
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
108
SiFivePLICState *plic = opaque;
109
110
if (addr_between(addr, plic->priority_base, plic->num_sources << 2)) {
111
- uint32_t irq = ((addr - plic->priority_base) >> 2) + 1;
112
+ uint32_t irq = (addr - plic->priority_base) >> 2;
113
114
if (((plic->num_priorities + 1) & plic->num_priorities) == 0) {
115
/*
116
@@ -XXX,XX +XXX,XX @@ static Property sifive_plic_properties[] = {
117
/* number of interrupt sources including interrupt source 0 */
118
DEFINE_PROP_UINT32("num-sources", SiFivePLICState, num_sources, 1),
119
DEFINE_PROP_UINT32("num-priorities", SiFivePLICState, num_priorities, 0),
120
+ /* interrupt priority register base starting from source 0 */
121
DEFINE_PROP_UINT32("priority-base", SiFivePLICState, priority_base, 0),
122
DEFINE_PROP_UINT32("pending-base", SiFivePLICState, pending_base, 0),
123
DEFINE_PROP_UINT32("enable-base", SiFivePLICState, enable_base, 0),
124
--
125
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
"hartid-base" and "priority-base" are zero by default. There is no
4
need to initialize them to zero again.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221211030829.802437-15-bmeng@tinylab.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
hw/riscv/opentitan.c | 2 --
13
1 file changed, 2 deletions(-)
14
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/opentitan.c
18
+++ b/hw/riscv/opentitan.c
19
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
20
21
/* PLIC */
22
qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
23
- qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
24
qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
25
qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
26
- qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
27
qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
28
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
29
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 32);
30
--
31
2.38.1
diff view generated by jsdifflib
New patch
1
From: Bin Meng <bmeng@tinylab.org>
1
2
3
The pending register upper limit is currently set to
4
plic->num_sources >> 3, which is wrong, e.g.: considering
5
plic->num_sources is 7, the upper limit becomes 0 which fails
6
the range check if reading the pending register at pending_base.
7
8
Fixes: 1e24429e40df ("SiFive RISC-V PLIC Block")
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221211030829.802437-16-bmeng@tinylab.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
hw/intc/sifive_plic.c | 5 +++--
15
1 file changed, 3 insertions(+), 2 deletions(-)
16
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/sifive_plic.c
20
+++ b/hw/intc/sifive_plic.c
21
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
22
uint32_t irq = (addr - plic->priority_base) >> 2;
23
24
return plic->source_priority[irq];
25
- } else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
26
+ } else if (addr_between(addr, plic->pending_base,
27
+ (plic->num_sources + 31) >> 3)) {
28
uint32_t word = (addr - plic->pending_base) >> 2;
29
30
return plic->pending[word];
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
32
sifive_plic_update(plic);
33
}
34
} else if (addr_between(addr, plic->pending_base,
35
- plic->num_sources >> 3)) {
36
+ (plic->num_sources + 31) >> 3)) {
37
qemu_log_mask(LOG_GUEST_ERROR,
38
"%s: invalid pending write: 0x%" HWADDR_PRIx "",
39
__func__, addr);
40
--
41
2.38.1
diff view generated by jsdifflib