1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit 3e9793ab01904144c204589811e0e879109a9713:
2
2
3
The following changes since commit 562d4af32ec2213061f844b3838223fd7711b56a:
3
Merge tag 'qga-pull-2024-12-18' of https://github.com/kostyanf14/qemu into staging (2024-12-18 20:24:59 -0500)
4
5
Merge tag 'pull-loongarch-20221215' of https://gitlab.com/gaosong/qemu into staging (2022-12-18 13:53:29 +0000)
6
4
7
are available in the Git repository at:
5
are available in the Git repository at:
8
6
9
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20221219-3
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20241220
10
8
11
for you to fetch changes up to e59b3c6ece6a1351aeca6b916cd9674e23d15e89:
9
for you to fetch changes up to 2fc8f50eadad5dcc99bc5de1333808b9de47a097:
12
10
13
hw/intc: sifive_plic: Fix the pending register range check (2022-12-19 10:42:14 +1000)
11
target/riscv: add support for RV64 Xiangshan Nanhu CPU (2024-12-20 11:22:47 +1000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
First RISC-V PR for QEMU 8.0
14
RISC-V PR for 10.0
17
15
18
* Fix PMP propagation for tlb
16
* Correct the validness check of iova
19
* Collection of bug fixes
17
* Fix APLIC in_clrip and clripnum write emulation
20
* Add the `FIELDx_1CLEAR()` macro
18
* Support riscv-iommu-sys device
21
* Bump the OpenTitan supported version
19
* Add Tenstorrent Ascalon CPU
22
* Add smstateen support
20
* Add AIA userspace irqchip_split support
23
* Support native debug icount trigger
21
* Add Microblaze V generic board
24
* Remove the redundant ipi-id property in the virt machine
22
* Upgrade ACPI SPCR table to support SPCR table revision 4 format
25
* Support cache-related PMU events in virtual mode
23
* Remove tswap64() calls from HTIF
26
* Add some missing PolarFire SoC io regions
24
* Support 64-bit address of initrd
27
* Fix mret exception cause when no pmp rule is configured
25
* Introduce svukte ISA extension
28
* Fix bug where disabling compressed instructions would crash QEMU
26
* Support ssstateen extension
29
* Add Zawrs ISA extension support
27
* Support for RV64 Xiangshan Nanhu CPU
30
* A range of code refactoring and cleanups
31
28
32
----------------------------------------------------------------
29
----------------------------------------------------------------
33
Anup Patel (1):
30
Anton Blanchard (1):
34
target/riscv: Typo fix in sstc() predicate
31
target/riscv: Add Tenstorrent Ascalon CPU
35
32
36
Atish Patra (1):
33
Daniel Henrique Barboza (15):
37
hw/riscv: virt: Remove the redundant ipi-id property
34
hw/riscv/riscv-iommu.c: add riscv_iommu_instance_init()
35
hw/riscv/riscv-iommu: parametrize CAP.IGS
36
hw/riscv/virt.c, riscv-iommu-sys.c: add MSIx support
37
hw/riscv/riscv-iommu: implement reset protocol
38
docs/specs: add riscv-iommu-sys information
39
hw/intc/riscv_aplic: rename is_kvm_aia()
40
hw/riscv/virt.c: reduce virt_use_kvm_aia() usage
41
hw/riscv/virt.c: rename helper to virt_use_kvm_aia_aplic_imsic()
42
target/riscv/kvm: consider irqchip_split() in aia_create()
43
hw/riscv/virt.c, riscv_aplic.c: add 'emulated_aplic' helpers
44
hw/intc/riscv_aplic: add kvm_msicfgaddr for split mode aplic-imsic
45
target/riscv/kvm: remove irqchip_split() restriction
46
docs: update riscv/virt.rst with kernel-irqchip=split support
47
target/riscv/tcg: hide warn for named feats when disabling via priv_ver
48
target/riscv: add ssstateen
38
49
39
Bin Meng (20):
50
Fea.Wang (6):
40
target/riscv: Add some comments for sstatus CSR in riscv_cpu_dump_state()
51
target/riscv: Add svukte extension capability variable
41
target/riscv: Fix mret exception cause when no pmp rule is configured
52
target/riscv: Support senvcfg[UKTE] bit when svukte extension is enabled
42
target/riscv: Simplify helper_sret() a little bit
53
target/riscv: Support hstatus[HUKTE] bit when svukte extension is enabled
43
target/riscv: Clear mstatus.MPRV when leaving M-mode for priv spec 1.12+
54
target/riscv: Check memory access to meet svukte rule
44
hw/riscv: Select MSI_NONBROKEN in SIFIVE_PLIC
55
target/riscv: Expose svukte ISA extension
45
hw/intc: Select MSI_NONBROKEN in RISC-V AIA interrupt controllers
56
target/riscv: Check svukte is not enabled in RV32
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
60
57
61
Christoph Muellner (1):
58
Jason Chien (1):
62
RISC-V: Add Zawrs ISA extension support
59
hw/riscv/riscv-iommu.c: Correct the validness check of iova
63
60
64
Conor Dooley (3):
61
Jim Shu (3):
65
hw/misc: pfsoc: add fabric clocks to ioscb
62
hw/riscv: Support to load DTB after 3GB memory on 64-bit system.
66
hw/riscv: pfsoc: add missing FICs as unimplemented
63
hw/riscv: Add a new struct RISCVBootInfo
67
hw/{misc, riscv}: pfsoc: add system controller as unimplemented
64
hw/riscv: Add the checking if DTB overlaps to kernel or initrd
68
65
69
Frédéric Pétrot (1):
66
MollyChen (1):
70
hw/intc: sifive_plic: Renumber the S irqs for numa support
67
target/riscv: add support for RV64 Xiangshan Nanhu CPU
71
68
72
Jim Shu (2):
69
Philippe Mathieu-Daudé (5):
73
target/riscv: support cache-related PMU events in virtual mode
70
MAINTAINERS: Cover RISC-V HTIF interface
74
hw/intc: sifive_plic: fix out-of-bound access of source_priority array
71
hw/char/riscv_htif: Explicit little-endian implementation
72
hw/char/riscv_htif: Clarify MemoryRegionOps expect 32-bit accesses
73
target/riscv: Include missing headers in 'vector_internals.h'
74
target/riscv: Include missing headers in 'internals.h'
75
75
76
LIU Zhiwei (5):
76
Sai Pavan Boddu (1):
77
target/riscv: Fix PMP propagation for tlb
77
hw/riscv: Add Microblaze V generic board
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
78
83
Mayuresh Chitale (3):
79
Sia Jee Heng (3):
84
target/riscv: Add smstateen support
80
qtest: allow SPCR acpi table changes
85
target/riscv: smstateen check for h/s/envcfg
81
hw/acpi: Upgrade ACPI SPCR table to support SPCR table revision 4 format
86
target/riscv: generate virtual instruction exception
82
tests/qtest/bios-tables-test: Update virt SPCR golden reference for RISC-V
87
83
88
Richard Henderson (4):
84
Sunil V L (1):
89
tcg/riscv: Fix range matched by TCG_CT_CONST_M12
85
hw/riscv/virt: Add IOMMU as platform device if the option is set
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
86
94
Wilfred Mallawa (4):
87
Tomasz Jeznach (1):
95
hw/registerfields: add `FIELDx_1CLEAR()` macro
88
hw/riscv: add riscv-iommu-sys platform device
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
89
100
include/hw/intc/sifive_plic.h | 1 -
90
Yong-Xuan Wang (1):
101
include/hw/misc/mchp_pfsoc_ioscb.h | 4 +
91
hw/intc/riscv_aplic: Fix APLIC in_clrip and clripnum write emulation
102
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
92
103
include/hw/registerfields.h | 22 ++
93
MAINTAINERS | 8 +
104
include/hw/riscv/microchip_pfsoc.h | 7 +-
94
docs/specs/index.rst | 1 +
105
include/hw/riscv/opentitan.h | 10 +-
95
docs/specs/riscv-aia.rst | 83 ++++++++++
106
include/hw/riscv/shakti_c.h | 2 +-
96
docs/specs/riscv-iommu.rst | 30 +++-
107
include/hw/riscv/sifive_e.h | 9 +-
97
docs/system/riscv/microblaze-v-generic.rst | 42 +++++
108
include/hw/riscv/sifive_u.h | 2 +-
98
docs/system/riscv/virt.rst | 17 ++
109
include/hw/riscv/virt.h | 8 +-
99
docs/system/target-riscv.rst | 1 +
110
target/riscv/cpu.h | 10 +
100
hw/riscv/riscv-iommu-bits.h | 6 +
111
target/riscv/cpu_bits.h | 37 +++
101
hw/riscv/riscv-iommu.h | 5 +
112
target/riscv/debug.h | 13 +
102
include/hw/acpi/acpi-defs.h | 7 +-
113
target/riscv/helper.h | 2 +
103
include/hw/acpi/aml-build.h | 2 +-
114
target/riscv/pmp.h | 6 +-
104
include/hw/intc/riscv_aplic.h | 8 +
115
target/riscv/insn32.decode | 4 +
105
include/hw/riscv/boot.h | 28 +++-
116
hw/intc/sifive_plic.c | 66 +++--
106
include/hw/riscv/iommu.h | 10 +-
117
hw/misc/mchp_pfsoc_ioscb.c | 78 ++++-
107
include/hw/riscv/virt.h | 6 +-
118
hw/misc/mchp_pfsoc_sysreg.c | 18 +-
108
target/riscv/cpu-qom.h | 2 +
119
hw/riscv/microchip_pfsoc.c | 121 ++++----
109
target/riscv/cpu_bits.h | 2 +
120
hw/riscv/opentitan.c | 26 +-
110
target/riscv/cpu_cfg.h | 2 +
121
hw/riscv/sifive_u.c | 3 +-
111
target/riscv/internals.h | 3 +
122
hw/riscv/spike.c | 1 -
112
target/riscv/vector_internals.h | 1 +
123
hw/riscv/virt.c | 7 +-
113
hw/acpi/aml-build.c | 20 ++-
124
hw/ssi/ibex_spi_host.c | 21 +-
114
hw/arm/virt-acpi-build.c | 8 +-
125
target/riscv/cpu.c | 11 +
115
hw/char/riscv_htif.c | 15 +-
126
target/riscv/cpu_helper.c | 26 +-
116
hw/intc/riscv_aplic.c | 74 +++++++--
127
target/riscv/csr.c | 393 ++++++++++++++++++++++++-
117
hw/loongarch/acpi-build.c | 6 +-
128
target/riscv/debug.c | 205 +++++++++++++
118
hw/riscv/boot.c | 100 +++++++----
129
target/riscv/machine.c | 36 +++
119
hw/riscv/microblaze-v-generic.c | 184 +++++++++++++++++++++
130
target/riscv/op_helper.c | 28 +-
120
hw/riscv/microchip_pfsoc.c | 13 +-
131
target/riscv/pmp.c | 90 ++----
121
hw/riscv/opentitan.c | 4 +-
132
target/riscv/translate.c | 54 +++-
122
hw/riscv/riscv-iommu-pci.c | 21 +++
133
target/riscv/insn_trans/trans_privileged.c.inc | 4 +-
123
hw/riscv/riscv-iommu-sys.c | 256 +++++++++++++++++++++++++++++
134
target/riscv/insn_trans/trans_rvi.c.inc | 8 +-
124
hw/riscv/riscv-iommu.c | 137 ++++++++++-----
135
target/riscv/insn_trans/trans_rvv.c.inc | 4 +-
125
hw/riscv/sifive_e.c | 4 +-
136
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 ++++
126
hw/riscv/sifive_u.c | 18 +-
137
tcg/riscv/tcg-target.c.inc | 68 +++--
127
hw/riscv/spike.c | 14 +-
138
hw/intc/Kconfig | 3 +
128
hw/riscv/virt-acpi-build.c | 12 +-
139
hw/riscv/Kconfig | 22 +-
129
hw/riscv/virt.c | 159 +++++++++++++++---
140
tests/tcg/Makefile.target | 2 +
130
target/riscv/cpu.c | 101 ++++++++++++
141
tests/tcg/riscv64/Makefile.target | 5 +
131
target/riscv/cpu_helper.c | 55 +++++++
142
tests/tcg/riscv64/test-noc.S | 32 ++
132
target/riscv/csr.c | 7 +
143
43 files changed, 1255 insertions(+), 266 deletions(-)
133
target/riscv/kvm/kvm-cpu.c | 43 ++---
144
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
134
target/riscv/tcg/tcg-cpu.c | 27 ++-
145
create mode 100644 tests/tcg/riscv64/test-noc.S
135
hw/riscv/Kconfig | 8 +
136
hw/riscv/meson.build | 3 +-
137
hw/riscv/trace-events | 4 +
138
tests/data/acpi/riscv64/virt/SPCR | Bin 80 -> 90 bytes
139
46 files changed, 1380 insertions(+), 177 deletions(-)
140
create mode 100644 docs/specs/riscv-aia.rst
141
create mode 100644 docs/system/riscv/microblaze-v-generic.rst
142
create mode 100644 hw/riscv/microblaze-v-generic.c
143
create mode 100644 hw/riscv/riscv-iommu-sys.c
144
diff view generated by jsdifflib
1
From: Jim Shu <jim.shu@sifive.com>
1
From: Jason Chien <jason.chien@sifive.com>
2
2
3
If the number of interrupt is not multiple of 32, PLIC will have
3
From RISCV IOMMU spec section 2.1.3:
4
out-of-bound access to source_priority array. Compute the number of
4
When SXL is 1, the following rules apply:
5
interrupt in the last word to avoid this out-of-bound access of array.
5
- If the first-stage is not Bare, then a page fault corresponding to the
6
original access type occurs if the IOVA has bits beyond bit 31 set to 1.
7
- If the second-stage is not Bare, then a guest page fault corresponding
8
to the original access type occurs if the incoming GPA has bits beyond bit
9
33 set to 1.
6
10
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
11
From RISCV IOMMU spec section 2.3 step 17:
8
Reviewed-by: Bin Meng <bmeng@tinylab.org>
12
Use the process specified in Section "Two-Stage Address Translation" of
9
Message-Id: <20221127165753.30533-1-jim.shu@sifive.com>
13
the RISC-V Privileged specification to determine the GPA accessed by the
14
transaction.
15
16
From RISCV IOMMU spec section 2.3 step 19:
17
Use the second-stage address translation process specified in Section
18
"Two-Stage Address Translation" of the RISC-V Privileged specification
19
to translate the GPA A to determine the SPA accessed by the transaction.
20
21
This commit adds the iova check with the following rules:
22
- For Sv32, Sv32x4, Sv39x4, Sv48x4 and Sv57x4, the iova must be zero
23
extended.
24
- For Sv39, Sv48 and Sv57, the iova must be signed extended with most
25
significant bit.
26
27
Signed-off-by: Jason Chien <jason.chien@sifive.com>
28
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
29
Message-ID: <20241114065617.25133-1-jason.chien@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
31
---
12
hw/intc/sifive_plic.c | 12 +++++++++++-
32
hw/riscv/riscv-iommu.c | 23 ++++++++++++++++++++---
13
1 file changed, 11 insertions(+), 1 deletion(-)
33
1 file changed, 20 insertions(+), 3 deletions(-)
14
34
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
35
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
16
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/sifive_plic.c
37
--- a/hw/riscv/riscv-iommu.c
18
+++ b/hw/intc/sifive_plic.c
38
+++ b/hw/riscv/riscv-iommu.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
39
@@ -XXX,XX +XXX,XX @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
20
uint32_t max_irq = 0;
40
21
uint32_t max_prio = plic->target_priority[addrid];
41
/* Address range check before first level lookup */
22
int i, j;
42
if (!sc[pass].step) {
23
+ int num_irq_in_word = 32;
43
- const uint64_t va_mask = (1ULL << (va_skip + va_bits)) - 1;
24
44
- if ((addr & va_mask) != addr) {
25
for (i = 0; i < plic->bitfield_words; i++) {
45
- return RISCV_IOMMU_FQ_CAUSE_DMA_DISABLED;
26
uint32_t pending_enabled_not_claimed =
46
+ const uint64_t va_len = va_skip + va_bits;
27
@@ -XXX,XX +XXX,XX @@ static uint32_t sifive_plic_claimed(SiFivePLICState *plic, uint32_t addrid)
47
+ const uint64_t va_mask = (1ULL << va_len) - 1;
28
continue;
48
+
49
+ if (pass == S_STAGE && va_len > 32) {
50
+ target_ulong mask, masked_msbs;
51
+
52
+ mask = (1L << (TARGET_LONG_BITS - (va_len - 1))) - 1;
53
+ masked_msbs = (addr >> (va_len - 1)) & mask;
54
+
55
+ if (masked_msbs != 0 && masked_msbs != mask) {
56
+ return (iotlb->perm & IOMMU_WO) ?
57
+ RISCV_IOMMU_FQ_CAUSE_WR_FAULT_S :
58
+ RISCV_IOMMU_FQ_CAUSE_RD_FAULT_S;
59
+ }
60
+ } else {
61
+ if ((addr & va_mask) != addr) {
62
+ return (iotlb->perm & IOMMU_WO) ?
63
+ RISCV_IOMMU_FQ_CAUSE_WR_FAULT_VS :
64
+ RISCV_IOMMU_FQ_CAUSE_RD_FAULT_VS;
65
+ }
66
}
29
}
67
}
30
68
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
--
69
--
46
2.38.1
70
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
2
2
3
At present the PLIC config parser can only handle legal config string
3
In the section "4.7 Precise effects on interrupt-pending bits"
4
like "MS,MS". However if a config string like ",MS,MS,,MS,MS,," is
4
of the RISC-V AIA specification defines that:
5
given the parser won't get the correct configuration.
6
5
7
This commit improves the config parser to make it more robust.
6
"If the source mode is Level1 or Level0 and the interrupt domain
7
is configured in MSI delivery mode (domaincfg.DM = 1):
8
The pending bit is cleared whenever the rectified input value is
9
low, when the interrupt is forwarded by MSI, or by a relevant
10
write to an in_clrip register or to clripnum."
8
11
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
12
Update the riscv_aplic_set_pending() to match the spec.
13
14
Fixes: bf31cf06eb ("hw/intc/riscv_aplic: Fix setipnum_le write emulation for APLIC MSI-mode")
15
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
16
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221211030829.802437-7-bmeng@tinylab.org>
17
Message-ID: <20241029085349.30412-1-yongxuan.wang@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
19
---
14
hw/intc/sifive_plic.c | 24 ++++++++++++++++--------
20
hw/intc/riscv_aplic.c | 6 +++++-
15
1 file changed, 16 insertions(+), 8 deletions(-)
21
1 file changed, 5 insertions(+), 1 deletion(-)
16
22
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
23
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
18
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/sifive_plic.c
25
--- a/hw/intc/riscv_aplic.c
20
+++ b/hw/intc/sifive_plic.c
26
+++ b/hw/intc/riscv_aplic.c
21
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_reset(DeviceState *dev)
27
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic,
22
*/
28
23
static void parse_hart_config(SiFivePLICState *plic)
29
if ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) ||
24
{
30
(sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
25
- int addrid, hartid, modes;
31
- if (!aplic->msimode || (aplic->msimode && !pending)) {
26
+ int addrid, hartid, modes, m;
32
+ if (!aplic->msimode) {
27
const char *p;
33
return;
28
char c;
34
}
29
35
+ if (aplic->msimode && !pending) {
30
@@ -XXX,XX +XXX,XX @@ static void parse_hart_config(SiFivePLICState *plic)
36
+ goto noskip_write_pending;
31
p = plic->hart_config;
37
+ }
32
while ((c = *p++)) {
38
if ((aplic->state[irq] & APLIC_ISTATE_INPUT) &&
33
if (c == ',') {
39
(sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
34
- addrid += ctpop8(modes);
40
return;
35
- modes = 0;
41
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic,
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
}
42
}
77
}
43
}
44
45
+noskip_write_pending:
46
riscv_aplic_set_pending_raw(aplic, irq, pending);
47
}
48
78
--
49
--
79
2.38.1
50
2.47.1
diff view generated by jsdifflib
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This patch updates the OpenTitan model to match
3
Move all the static initializion of the device to an init() function,
4
the specified register layout as per [1]. Which is also the latest
4
leaving only the dynamic initialization to be done during realize.
5
commit of OpenTitan supported by TockOS.
6
5
7
Note: Pinmux and Padctrl has been merged into Pinmux [2][3], this patch removes
6
With this change s->cap is initialized with RISCV_IOMMU_CAP_DBG during
8
any references to Padctrl. Note: OpenTitan doc [2] has not yet specified
7
init(), and realize() will increment s->cap with the extra caps.
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
8
12
[1] https://github.com/lowRISC/opentitan/blob/d072ac505f82152678d6e04be95c72b728a347b8/hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
9
This will allow callers to add IOMMU capabilities before the
13
[2] https://docs.opentitan.org/hw/top_earlgrey/doc/design/
10
realization.
14
[3] https://docs.opentitan.org/hw/ip/pinmux/doc/#overview
15
11
16
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
14
Message-ID: <20241106133407.604587-2-dbarboza@ventanamicro.com>
19
Message-Id: <20221025043335.339815-2-wilfred.mallawa@opensource.wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
16
---
22
include/hw/riscv/opentitan.h | 9 ++++-----
17
hw/riscv/riscv-iommu.c | 71 +++++++++++++++++++++++-------------------
23
hw/riscv/opentitan.c | 21 +++++++++++++--------
18
1 file changed, 39 insertions(+), 32 deletions(-)
24
2 files changed, 17 insertions(+), 13 deletions(-)
25
19
26
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
20
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
27
index XXXXXXX..XXXXXXX 100644
21
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/riscv/opentitan.h
22
--- a/hw/riscv/riscv-iommu.c
29
+++ b/include/hw/riscv/opentitan.h
23
+++ b/hw/riscv/riscv-iommu.c
30
@@ -XXX,XX +XXX,XX @@ enum {
24
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps riscv_iommu_trap_ops = {
31
IBEX_DEV_RSTMGR,
25
}
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
};
26
};
51
27
52
#endif
28
+static void riscv_iommu_instance_init(Object *obj)
53
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
29
+{
54
index XXXXXXX..XXXXXXX 100644
30
+ RISCVIOMMUState *s = RISCV_IOMMU(obj);
55
--- a/hw/riscv/opentitan.c
31
+
56
+++ b/hw/riscv/opentitan.c
32
+ /* Enable translation debug interface */
57
@@ -XXX,XX +XXX,XX @@
33
+ s->cap = RISCV_IOMMU_CAP_DBG;
58
#include "qemu/units.h"
34
+
59
#include "sysemu/sysemu.h"
35
+ /* Report QEMU target physical address space limits */
60
36
+ s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS,
61
+/*
37
+ TARGET_PHYS_ADDR_SPACE_BITS);
62
+ * This version of the OpenTitan machine currently supports
38
+
63
+ * OpenTitan RTL version:
39
+ /* TODO: method to report supported PID bits */
64
+ * <lowRISC/opentitan@d072ac505f82152678d6e04be95c72b728a347b8>
40
+ s->pid_bits = 8; /* restricted to size of MemTxAttrs.pid */
65
+ *
41
+ s->cap |= RISCV_IOMMU_CAP_PD8;
66
+ * MMIO mapping as per (specified commit):
42
+
67
+ * lowRISC/opentitan: hw/top_earlgrey/sw/autogen/top_earlgrey_memory.h
43
+ /* register storage */
68
+ */
44
+ s->regs_rw = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
69
static const MemMapEntry ibex_memmap[] = {
45
+ s->regs_ro = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
70
- [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
46
+ s->regs_wc = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
71
+ [IBEX_DEV_ROM] = { 0x00008000, 0x8000 },
47
+
72
[IBEX_DEV_RAM] = { 0x10000000, 0x20000 },
48
+ /* Mark all registers read-only */
73
[IBEX_DEV_FLASH] = { 0x20000000, 0x100000 },
49
+ memset(s->regs_ro, 0xff, RISCV_IOMMU_REG_SIZE);
74
[IBEX_DEV_UART] = { 0x40000000, 0x1000 },
50
+
75
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
51
+ /* Device translation context cache */
76
[IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
52
+ s->ctx_cache = g_hash_table_new_full(riscv_iommu_ctx_hash,
77
[IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
53
+ riscv_iommu_ctx_equal,
78
[IBEX_DEV_TIMER] = { 0x40100000, 0x1000 },
54
+ g_free, NULL);
79
- [IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
55
+
80
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
56
+ s->iot_cache = g_hash_table_new_full(riscv_iommu_iot_hash,
81
[IBEX_DEV_LC_CTRL] = { 0x40140000, 0x1000 },
57
+ riscv_iommu_iot_equal,
82
- [IBEX_DEV_USBDEV] = { 0x40150000, 0x1000 },
58
+ g_free, NULL);
83
+ [IBEX_DEV_ALERT_HANDLER] = { 0x40150000, 0x1000 },
59
+
84
[IBEX_DEV_SPI_HOST0] = { 0x40300000, 0x1000 },
60
+ s->iommus.le_next = NULL;
85
[IBEX_DEV_SPI_HOST1] = { 0x40310000, 0x1000 },
61
+ s->iommus.le_prev = NULL;
86
+ [IBEX_DEV_USBDEV] = { 0x40320000, 0x1000 },
62
+ QLIST_INIT(&s->spaces);
87
[IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
63
+}
88
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
64
+
89
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
65
static void riscv_iommu_realize(DeviceState *dev, Error **errp)
90
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
66
{
91
- [IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
67
RISCVIOMMUState *s = RISCV_IOMMU(dev);
92
+ [IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
68
93
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
69
- s->cap = s->version & RISCV_IOMMU_CAP_VERSION;
94
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
70
+ s->cap |= s->version & RISCV_IOMMU_CAP_VERSION;
95
[IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
71
if (s->enable_msi) {
96
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
72
s->cap |= RISCV_IOMMU_CAP_MSI_FLAT | RISCV_IOMMU_CAP_MSI_MRIF;
97
[IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
73
}
98
[IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
74
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp)
99
[IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
75
s->cap |= RISCV_IOMMU_CAP_SV32X4 | RISCV_IOMMU_CAP_SV39X4 |
100
- [IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
76
RISCV_IOMMU_CAP_SV48X4 | RISCV_IOMMU_CAP_SV57X4;
101
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
77
}
102
[IBEX_DEV_PERI] = { 0x411f0000, 0x10000 },
78
- /* Enable translation debug interface */
103
- [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
79
- s->cap |= RISCV_IOMMU_CAP_DBG;
104
+ [IBEX_DEV_PLIC] = { 0x48000000, 0x4005000 },
80
-
105
[IBEX_DEV_FLASH_VIRTUAL] = { 0x80000000, 0x80000 },
81
- /* Report QEMU target physical address space limits */
82
- s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS,
83
- TARGET_PHYS_ADDR_SPACE_BITS);
84
-
85
- /* TODO: method to report supported PID bits */
86
- s->pid_bits = 8; /* restricted to size of MemTxAttrs.pid */
87
- s->cap |= RISCV_IOMMU_CAP_PD8;
88
89
/* Out-of-reset translation mode: OFF (DMA disabled) BARE (passthrough) */
90
s->ddtp = set_field(0, RISCV_IOMMU_DDTP_MODE, s->enable_off ?
91
RISCV_IOMMU_DDTP_MODE_OFF : RISCV_IOMMU_DDTP_MODE_BARE);
92
93
- /* register storage */
94
- s->regs_rw = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
95
- s->regs_ro = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
96
- s->regs_wc = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
97
-
98
- /* Mark all registers read-only */
99
- memset(s->regs_ro, 0xff, RISCV_IOMMU_REG_SIZE);
100
-
101
/*
102
* Register complete MMIO space, including MSI/PBA registers.
103
* Note, PCIDevice implementation will add overlapping MR for MSI/PBA,
104
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp)
105
memory_region_init_io(&s->trap_mr, OBJECT(dev), &riscv_iommu_trap_ops, s,
106
"riscv-iommu-trap", ~0ULL);
107
address_space_init(&s->trap_as, &s->trap_mr, "riscv-iommu-trap-as");
108
-
109
- /* Device translation context cache */
110
- s->ctx_cache = g_hash_table_new_full(riscv_iommu_ctx_hash,
111
- riscv_iommu_ctx_equal,
112
- g_free, NULL);
113
-
114
- s->iot_cache = g_hash_table_new_full(riscv_iommu_iot_hash,
115
- riscv_iommu_iot_equal,
116
- g_free, NULL);
117
-
118
- s->iommus.le_next = NULL;
119
- s->iommus.le_prev = NULL;
120
- QLIST_INIT(&s->spaces);
121
}
122
123
static void riscv_iommu_unrealize(DeviceState *dev)
124
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_iommu_info = {
125
.name = TYPE_RISCV_IOMMU,
126
.parent = TYPE_DEVICE,
127
.instance_size = sizeof(RISCVIOMMUState),
128
+ .instance_init = riscv_iommu_instance_init,
129
.class_init = riscv_iommu_class_init,
106
};
130
};
107
131
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
--
132
--
118
2.38.1
133
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The pending register upper limit is currently set to
3
Interrupt Generation Support (IGS) is a capability that is tied to the
4
plic->num_sources >> 3, which is wrong, e.g.: considering
4
interrupt deliver mechanism, not with the core IOMMU emulation. We
5
plic->num_sources is 7, the upper limit becomes 0 which fails
5
should allow device implementations to set IGS as they wish.
6
the range check if reading the pending register at pending_base.
7
6
8
Fixes: 1e24429e40df ("SiFive RISC-V PLIC Block")
7
A new helper is added to make it easier for device impls to set IGS. Use
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
8
it in our existing IOMMU device (riscv-iommu-pci) to set
9
RISCV_IOMMU_CAPS_IGS_MSI.
10
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221211030829.802437-16-bmeng@tinylab.org>
13
Message-ID: <20241106133407.604587-3-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
15
---
14
hw/intc/sifive_plic.c | 5 +++--
16
hw/riscv/riscv-iommu-bits.h | 6 ++++++
15
1 file changed, 3 insertions(+), 2 deletions(-)
17
hw/riscv/riscv-iommu.h | 4 ++++
18
hw/riscv/riscv-iommu-pci.c | 1 +
19
hw/riscv/riscv-iommu.c | 5 +++++
20
4 files changed, 16 insertions(+)
16
21
17
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
22
diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
18
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/sifive_plic.c
24
--- a/hw/riscv/riscv-iommu-bits.h
20
+++ b/hw/intc/sifive_plic.c
25
+++ b/hw/riscv/riscv-iommu-bits.h
21
@@ -XXX,XX +XXX,XX @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, unsigned size)
26
@@ -XXX,XX +XXX,XX @@ struct riscv_iommu_pq_record {
22
uint32_t irq = (addr - plic->priority_base) >> 2;
27
#define RISCV_IOMMU_CAP_PD17 BIT_ULL(39)
23
28
#define RISCV_IOMMU_CAP_PD20 BIT_ULL(40)
24
return plic->source_priority[irq];
29
25
- } else if (addr_between(addr, plic->pending_base, plic->num_sources >> 3)) {
30
+enum riscv_iommu_igs_modes {
26
+ } else if (addr_between(addr, plic->pending_base,
31
+ RISCV_IOMMU_CAP_IGS_MSI = 0,
27
+ (plic->num_sources + 31) >> 3)) {
32
+ RISCV_IOMMU_CAP_IGS_WSI,
28
uint32_t word = (addr - plic->pending_base) >> 2;
33
+ RISCV_IOMMU_CAP_IGS_BOTH
29
34
+};
30
return plic->pending[word];
35
+
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_write(void *opaque, hwaddr addr, uint64_t value,
36
/* 5.4 Features control register (32bits) */
32
sifive_plic_update(plic);
37
#define RISCV_IOMMU_REG_FCTL 0x0008
33
}
38
#define RISCV_IOMMU_FCTL_BE BIT(0)
34
} else if (addr_between(addr, plic->pending_base,
39
diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h
35
- plic->num_sources >> 3)) {
40
index XXXXXXX..XXXXXXX 100644
36
+ (plic->num_sources + 31) >> 3)) {
41
--- a/hw/riscv/riscv-iommu.h
37
qemu_log_mask(LOG_GUEST_ERROR,
42
+++ b/hw/riscv/riscv-iommu.h
38
"%s: invalid pending write: 0x%" HWADDR_PRIx "",
43
@@ -XXX,XX +XXX,XX @@
39
__func__, addr);
44
45
#include "qom/object.h"
46
#include "hw/riscv/iommu.h"
47
+#include "hw/riscv/riscv-iommu-bits.h"
48
+
49
+typedef enum riscv_iommu_igs_modes riscv_iommu_igs_mode;
50
51
struct RISCVIOMMUState {
52
/*< private >*/
53
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUState {
54
55
void riscv_iommu_pci_setup_iommu(RISCVIOMMUState *iommu, PCIBus *bus,
56
Error **errp);
57
+void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode);
58
59
/* private helpers */
60
61
diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/riscv/riscv-iommu-pci.c
64
+++ b/hw/riscv/riscv-iommu-pci.c
65
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_pci_init(Object *obj)
66
qdev_alias_all_properties(DEVICE(iommu), obj);
67
68
iommu->icvec_avail_vectors = RISCV_IOMMU_PCI_ICVEC_VECTORS;
69
+ riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_MSI);
70
}
71
72
static const Property riscv_iommu_pci_properties[] = {
73
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/riscv/riscv-iommu.c
76
+++ b/hw/riscv/riscv-iommu.c
77
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps riscv_iommu_trap_ops = {
78
}
79
};
80
81
+void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode)
82
+{
83
+ s->cap = set_field(s->cap, RISCV_IOMMU_CAP_IGS, mode);
84
+}
85
+
86
static void riscv_iommu_instance_init(Object *obj)
87
{
88
RISCVIOMMUState *s = RISCV_IOMMU(obj);
40
--
89
--
41
2.38.1
90
2.47.1
diff view generated by jsdifflib
1
From: Christoph Muellner <christoph.muellner@vrull.eu>
1
From: Tomasz Jeznach <tjeznach@rivosinc.com>
2
2
3
This patch adds support for the Zawrs ISA extension.
3
This device models the RISC-V IOMMU as a sysbus device. The same design
4
Given the current (incomplete) implementation of reservation sets
4
decisions taken in the riscv-iommu-pci device were kept, namely the
5
there seems to be no way to provide a full emulation of the WRS
5
existence of 4 vectors are available for each interrupt cause.
6
instruction (wake on reservation set invalidation or timeout or
6
7
interrupt). Therefore, we just exit the TB and return to the main loop.
7
The WSIs are emitted using the input of the s->notify() callback as a
8
8
index to an IRQ list. The IRQ list starts at 'base_irq' and goes until
9
The specification can be found here:
9
base_irq + 3. This means that boards must have 4 contiguous IRQ lines
10
https://github.com/riscv/riscv-zawrs/blob/main/zawrs.adoc
10
available, starting from 'base_irq'.
11
11
12
Note, that the Zawrs extension is frozen, but not ratified yet.
12
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
13
13
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
29
Message-Id: <20221005144948.3421504-1-christoph.muellner@vrull.eu>
15
Message-ID: <20241106133407.604587-4-dbarboza@ventanamicro.com>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
17
---
32
target/riscv/cpu.h | 1 +
18
include/hw/riscv/iommu.h | 4 ++
33
target/riscv/insn32.decode | 4 ++
19
hw/riscv/riscv-iommu-sys.c | 128 +++++++++++++++++++++++++++++++++++++
34
target/riscv/cpu.c | 7 +++
20
hw/riscv/riscv-iommu.c | 3 +-
35
target/riscv/translate.c | 1 +
21
hw/riscv/meson.build | 2 +-
36
target/riscv/insn_trans/trans_rvzawrs.c.inc | 51 +++++++++++++++++++++
22
4 files changed, 134 insertions(+), 3 deletions(-)
37
5 files changed, 64 insertions(+)
23
create mode 100644 hw/riscv/riscv-iommu-sys.c
38
create mode 100644 target/riscv/insn_trans/trans_rvzawrs.c.inc
24
39
25
diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h
40
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
41
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
42
--- a/target/riscv/cpu.h
27
--- a/include/hw/riscv/iommu.h
43
+++ b/target/riscv/cpu.h
28
+++ b/include/hw/riscv/iommu.h
44
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
29
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUSpace RISCVIOMMUSpace;
45
bool ext_svnapot;
30
OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI)
46
bool ext_svpbmt;
31
typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci;
47
bool ext_zdinx;
32
48
+ bool ext_zawrs;
33
+#define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device"
49
bool ext_zfh;
34
+OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS)
50
bool ext_zfhmin;
35
+typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys;
51
bool ext_zfinx;
36
+
52
diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode
37
#endif
53
index XXXXXXX..XXXXXXX 100644
38
diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
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
39
new file mode 100644
113
index XXXXXXX..XXXXXXX
40
index XXXXXXX..XXXXXXX
114
--- /dev/null
41
--- /dev/null
115
+++ b/target/riscv/insn_trans/trans_rvzawrs.c.inc
42
+++ b/hw/riscv/riscv-iommu-sys.c
116
@@ -XXX,XX +XXX,XX @@
43
@@ -XXX,XX +XXX,XX @@
117
+/*
44
+/*
118
+ * RISC-V translation routines for the RISC-V Zawrs Extension.
45
+ * QEMU emulation of an RISC-V IOMMU Platform Device
119
+ *
46
+ *
120
+ * Copyright (c) 2022 Christoph Muellner, christoph.muellner@vrull.io
47
+ * Copyright (C) 2022-2023 Rivos Inc.
121
+ *
48
+ *
122
+ * This program is free software; you can redistribute it and/or modify it
49
+ * 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,
50
+ * under the terms and conditions of the GNU General Public License,
124
+ * version 2 or later, as published by the Free Software Foundation.
51
+ * version 2 or later, as published by the Free Software Foundation.
125
+ *
52
+ *
126
+ * This program is distributed in the hope it will be useful, but WITHOUT
53
+ * This program is distributed in the hope that it will be useful,
127
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
54
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
128
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
55
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
129
+ * more details.
56
+ * GNU General Public License for more details.
130
+ *
57
+ *
131
+ * You should have received a copy of the GNU General Public License along with
58
+ * You should have received a copy of the GNU General Public License along
132
+ * this program. If not, see <http://www.gnu.org/licenses/>.
59
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
133
+ */
60
+ */
134
+
61
+
135
+static bool trans_wrs(DisasContext *ctx)
62
+#include "qemu/osdep.h"
136
+{
63
+#include "hw/irq.h"
137
+ if (!ctx->cfg_ptr->ext_zawrs) {
64
+#include "hw/pci/pci_bus.h"
138
+ return false;
65
+#include "hw/qdev-properties.h"
139
+ }
66
+#include "hw/sysbus.h"
140
+
67
+#include "qapi/error.h"
141
+ /*
68
+#include "qemu/error-report.h"
142
+ * The specification says:
69
+#include "qemu/host-utils.h"
143
+ * While stalled, an implementation is permitted to occasionally
70
+#include "qemu/module.h"
144
+ * terminate the stall and complete execution for any reason.
71
+#include "qom/object.h"
145
+ *
72
+
146
+ * So let's just exit TB and return to the main loop.
73
+#include "riscv-iommu.h"
147
+ */
74
+
148
+
75
+#define RISCV_IOMMU_SYSDEV_ICVEC_VECTORS 0x3333
149
+ /* Clear the load reservation (if any). */
76
+
150
+ tcg_gen_movi_tl(load_res, -1);
77
+/* RISC-V IOMMU System Platform Device Emulation */
151
+
78
+
152
+ gen_set_pc_imm(ctx, ctx->pc_succ_insn);
79
+struct RISCVIOMMUStateSys {
153
+ tcg_gen_exit_tb(NULL, 0);
80
+ SysBusDevice parent;
154
+ ctx->base.is_jmp = DISAS_NORETURN;
81
+ uint64_t addr;
155
+
82
+ uint32_t base_irq;
156
+ return true;
83
+ DeviceState *irqchip;
157
+}
84
+ RISCVIOMMUState iommu;
158
+
85
+ qemu_irq irqs[RISCV_IOMMU_INTR_COUNT];
159
+#define GEN_TRANS_WRS(insn) \
86
+};
160
+static bool trans_ ## insn(DisasContext *ctx, arg_ ## insn *a) \
87
+
161
+{ \
88
+static void riscv_iommu_sysdev_notify(RISCVIOMMUState *iommu,
162
+ (void)a; \
89
+ unsigned vector)
163
+ return trans_wrs(ctx); \
90
+{
164
+}
91
+ RISCVIOMMUStateSys *s = container_of(iommu, RISCVIOMMUStateSys, iommu);
165
+
92
+ uint32_t fctl = riscv_iommu_reg_get32(iommu, RISCV_IOMMU_REG_FCTL);
166
+GEN_TRANS_WRS(wrs_nto)
93
+
167
+GEN_TRANS_WRS(wrs_sto)
94
+ /* We do not support MSIs yet */
95
+ if (!(fctl & RISCV_IOMMU_FCTL_WSI)) {
96
+ return;
97
+ }
98
+
99
+ qemu_irq_pulse(s->irqs[vector]);
100
+}
101
+
102
+static void riscv_iommu_sys_realize(DeviceState *dev, Error **errp)
103
+{
104
+ RISCVIOMMUStateSys *s = RISCV_IOMMU_SYS(dev);
105
+ SysBusDevice *sysdev = SYS_BUS_DEVICE(s);
106
+ PCIBus *pci_bus;
107
+ qemu_irq irq;
108
+
109
+ qdev_realize(DEVICE(&s->iommu), NULL, errp);
110
+ sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iommu.regs_mr);
111
+ if (s->addr) {
112
+ sysbus_mmio_map(SYS_BUS_DEVICE(s), 0, s->addr);
113
+ }
114
+
115
+ pci_bus = (PCIBus *) object_resolve_path_type("", TYPE_PCI_BUS, NULL);
116
+ if (pci_bus) {
117
+ riscv_iommu_pci_setup_iommu(&s->iommu, pci_bus, errp);
118
+ }
119
+
120
+ s->iommu.notify = riscv_iommu_sysdev_notify;
121
+
122
+ /* 4 IRQs are defined starting from s->base_irq */
123
+ for (int i = 0; i < RISCV_IOMMU_INTR_COUNT; i++) {
124
+ sysbus_init_irq(sysdev, &s->irqs[i]);
125
+ irq = qdev_get_gpio_in(s->irqchip, s->base_irq + i);
126
+ sysbus_connect_irq(sysdev, i, irq);
127
+ }
128
+}
129
+
130
+static void riscv_iommu_sys_init(Object *obj)
131
+{
132
+ RISCVIOMMUStateSys *s = RISCV_IOMMU_SYS(obj);
133
+ RISCVIOMMUState *iommu = &s->iommu;
134
+
135
+ object_initialize_child(obj, "iommu", iommu, TYPE_RISCV_IOMMU);
136
+ qdev_alias_all_properties(DEVICE(iommu), obj);
137
+
138
+ iommu->icvec_avail_vectors = RISCV_IOMMU_SYSDEV_ICVEC_VECTORS;
139
+ riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_WSI);
140
+}
141
+
142
+static Property riscv_iommu_sys_properties[] = {
143
+ DEFINE_PROP_UINT64("addr", RISCVIOMMUStateSys, addr, 0),
144
+ DEFINE_PROP_UINT32("base-irq", RISCVIOMMUStateSys, base_irq, 0),
145
+ DEFINE_PROP_LINK("irqchip", RISCVIOMMUStateSys, irqchip,
146
+ TYPE_DEVICE, DeviceState *),
147
+ DEFINE_PROP_END_OF_LIST(),
148
+};
149
+
150
+static void riscv_iommu_sys_class_init(ObjectClass *klass, void *data)
151
+{
152
+ DeviceClass *dc = DEVICE_CLASS(klass);
153
+ dc->realize = riscv_iommu_sys_realize;
154
+ set_bit(DEVICE_CATEGORY_MISC, dc->categories);
155
+ device_class_set_props(dc, riscv_iommu_sys_properties);
156
+}
157
+
158
+static const TypeInfo riscv_iommu_sys = {
159
+ .name = TYPE_RISCV_IOMMU_SYS,
160
+ .parent = TYPE_SYS_BUS_DEVICE,
161
+ .class_init = riscv_iommu_sys_class_init,
162
+ .instance_init = riscv_iommu_sys_init,
163
+ .instance_size = sizeof(RISCVIOMMUStateSys),
164
+};
165
+
166
+static void riscv_iommu_register_sys(void)
167
+{
168
+ type_register_static(&riscv_iommu_sys);
169
+}
170
+
171
+type_init(riscv_iommu_register_sys)
172
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/riscv/riscv-iommu.c
175
+++ b/hw/riscv/riscv-iommu.c
176
@@ -XXX,XX +XXX,XX @@ static uint8_t riscv_iommu_get_icvec_vector(uint32_t icvec, uint32_t vec_type)
177
178
static void riscv_iommu_notify(RISCVIOMMUState *s, int vec_type)
179
{
180
- const uint32_t fctl = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_FCTL);
181
uint32_t ipsr, icvec, vector;
182
183
- if (fctl & RISCV_IOMMU_FCTL_WSI || !s->notify) {
184
+ if (!s->notify) {
185
return;
186
}
187
188
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
189
index XXXXXXX..XXXXXXX 100644
190
--- a/hw/riscv/meson.build
191
+++ b/hw/riscv/meson.build
192
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c'))
193
riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))
194
riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfsoc.c'))
195
riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
196
-riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 'riscv-iommu-pci.c'))
197
+riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c'))
198
199
hw_arch += {'riscv': riscv_ss}
168
--
200
--
169
2.38.1
201
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Sunil V L <sunilvl@ventanamicro.com>
2
2
3
Commit 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
3
Add a new machine option called 'iommu-sys' that enables a
4
changed the value of VIRT_IRQCHIP_NUM_SOURCES from 127 to 53, which
4
riscv-iommu-sys platform device for the 'virt' machine. The option is
5
is VIRTIO_NDEV and also used as the value of "riscv,ndev" property
5
default 'off'.
6
in the dtb. Unfortunately this is wrong as VIRT_IRQCHIP_NUM_SOURCES
6
7
should include interrupt source 0 but "riscv,ndev" does not.
7
The device will use IRQs 36 to 39.
8
8
9
While we are here, we also fix the comments of platform bus irq range
9
We will not support both riscv-iommu-sys and riscv-iommu-pci devices in
10
which is now "64 to 96", but should be "64 to 95", introduced since
10
the same board in this first implementation. If a riscv-iommu-pci device
11
commit 1832b7cb3f64 ("hw/riscv: virt: Create a platform bus").
11
is added in the command line we will disable the riscv-iommu-sys device.
12
12
13
Fixes: 28d8c281200f ("hw/riscv: virt: Add optional AIA IMSIC support to virt machine")
13
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
14
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-Id: <20221211030829.802437-13-bmeng@tinylab.org>
16
Message-ID: <20241106133407.604587-5-dbarboza@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
18
---
19
include/hw/riscv/virt.h | 5 ++---
19
include/hw/riscv/iommu.h | 2 +
20
hw/riscv/virt.c | 3 ++-
20
include/hw/riscv/virt.h | 6 ++-
21
2 files changed, 4 insertions(+), 4 deletions(-)
21
hw/riscv/virt.c | 104 ++++++++++++++++++++++++++++++++++++++-
22
22
3 files changed, 109 insertions(+), 3 deletions(-)
23
24
diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/riscv/iommu.h
27
+++ b/include/hw/riscv/iommu.h
28
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci;
29
OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS)
30
typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys;
31
32
+#define FDT_IRQ_TYPE_EDGE_LOW 1
33
+
34
#endif
23
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
35
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
24
index XXXXXXX..XXXXXXX 100644
36
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/virt.h
37
--- a/include/hw/riscv/virt.h
26
+++ b/include/hw/riscv/virt.h
38
+++ b/include/hw/riscv/virt.h
39
@@ -XXX,XX +XXX,XX @@ struct RISCVVirtState {
40
OnOffAuto acpi;
41
const MemMapEntry *memmap;
42
struct GPEXHost *gpex_host;
43
+ OnOffAuto iommu_sys;
44
};
45
46
enum {
47
@@ -XXX,XX +XXX,XX @@ enum {
48
VIRT_PCIE_MMIO,
49
VIRT_PCIE_PIO,
50
VIRT_PLATFORM_BUS,
51
- VIRT_PCIE_ECAM
52
+ VIRT_PCIE_ECAM,
53
+ VIRT_IOMMU_SYS,
54
};
55
56
enum {
27
@@ -XXX,XX +XXX,XX @@ enum {
57
@@ -XXX,XX +XXX,XX @@ enum {
28
VIRTIO_IRQ = 1, /* 1 to 8 */
58
VIRTIO_IRQ = 1, /* 1 to 8 */
29
VIRTIO_COUNT = 8,
59
VIRTIO_COUNT = 8,
30
PCIE_IRQ = 0x20, /* 32 to 35 */
60
PCIE_IRQ = 0x20, /* 32 to 35 */
31
- VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */
61
+ IOMMU_SYS_IRQ = 0x24, /* 36-39 */
32
- VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */
62
VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
33
+ VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
34
};
63
};
35
64
36
#define VIRT_PLATFORM_BUS_NUM_IRQS 32
65
@@ -XXX,XX +XXX,XX @@ enum {
37
66
1 + FDT_APLIC_INT_CELLS)
38
#define VIRT_IRQCHIP_NUM_MSIS 255
67
39
-#define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
68
bool virt_is_acpi_enabled(RISCVVirtState *s);
40
+#define VIRT_IRQCHIP_NUM_SOURCES 96
69
+bool virt_is_iommu_sys_enabled(RISCVVirtState *s);
41
#define VIRT_IRQCHIP_NUM_PRIO_BITS 3
70
void virt_acpi_setup(RISCVVirtState *vms);
42
#define VIRT_IRQCHIP_MAX_GUESTS_BITS 3
71
uint32_t imsic_num_bits(uint32_t count);
43
#define VIRT_IRQCHIP_MAX_GUESTS ((1U << VIRT_IRQCHIP_MAX_GUESTS_BITS) - 1U)
72
44
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
73
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
45
index XXXXXXX..XXXXXXX 100644
74
index XXXXXXX..XXXXXXX 100644
46
--- a/hw/riscv/virt.c
75
--- a/hw/riscv/virt.c
47
+++ b/hw/riscv/virt.c
76
+++ b/hw/riscv/virt.c
48
@@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s,
77
@@ -XXX,XX +XXX,XX @@
49
plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4);
78
#include "target/riscv/pmu.h"
50
qemu_fdt_setprop_cells(mc->fdt, plic_name, "reg",
79
#include "hw/riscv/riscv_hart.h"
51
0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size);
80
#include "hw/riscv/iommu.h"
52
- qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev", VIRTIO_NDEV);
81
+#include "hw/riscv/riscv-iommu-bits.h"
53
+ qemu_fdt_setprop_cell(mc->fdt, plic_name, "riscv,ndev",
82
#include "hw/riscv/virt.h"
54
+ VIRT_IRQCHIP_NUM_SOURCES - 1);
83
#include "hw/riscv/boot.h"
55
riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket);
84
#include "hw/riscv/numa.h"
56
qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle",
85
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
57
plic_phandles[socket]);
86
[VIRT_CLINT] = { 0x2000000, 0x10000 },
87
[VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 },
88
[VIRT_PCIE_PIO] = { 0x3000000, 0x10000 },
89
+ [VIRT_IOMMU_SYS] = { 0x3010000, 0x1000 },
90
[VIRT_PLATFORM_BUS] = { 0x4000000, 0x2000000 },
91
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
92
[VIRT_APLIC_M] = { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) },
93
@@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap,
94
95
static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap,
96
uint32_t irq_pcie_phandle,
97
- uint32_t msi_pcie_phandle)
98
+ uint32_t msi_pcie_phandle,
99
+ uint32_t iommu_sys_phandle)
100
{
101
g_autofree char *name = NULL;
102
MachineState *ms = MACHINE(s);
103
@@ -XXX,XX +XXX,XX @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap,
104
2, virt_high_pcie_memmap.base,
105
2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size);
106
107
+ if (virt_is_iommu_sys_enabled(s)) {
108
+ qemu_fdt_setprop_cells(ms->fdt, name, "iommu-map",
109
+ 0, iommu_sys_phandle, 0, 0, 0,
110
+ iommu_sys_phandle, 0, 0xffff);
111
+ }
112
+
113
create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio_iommu(RISCVVirtState *s, uint16_t bdf)
117
bdf + 1, iommu_phandle, bdf + 1, 0xffff - bdf);
118
}
119
120
+static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip,
121
+ uint32_t *iommu_sys_phandle)
122
+{
123
+ const char comp[] = "riscv,iommu";
124
+ void *fdt = MACHINE(s)->fdt;
125
+ uint32_t iommu_phandle;
126
+ g_autofree char *iommu_node = NULL;
127
+ hwaddr addr = s->memmap[VIRT_IOMMU_SYS].base;
128
+ hwaddr size = s->memmap[VIRT_IOMMU_SYS].size;
129
+ uint32_t iommu_irq_map[RISCV_IOMMU_INTR_COUNT] = {
130
+ IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_CQ,
131
+ IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_FQ,
132
+ IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_PM,
133
+ IOMMU_SYS_IRQ + RISCV_IOMMU_INTR_PQ,
134
+ };
135
+
136
+ iommu_node = g_strdup_printf("/soc/iommu@%x",
137
+ (unsigned int) s->memmap[VIRT_IOMMU_SYS].base);
138
+ iommu_phandle = qemu_fdt_alloc_phandle(fdt);
139
+ qemu_fdt_add_subnode(fdt, iommu_node);
140
+
141
+ qemu_fdt_setprop(fdt, iommu_node, "compatible", comp, sizeof(comp));
142
+ qemu_fdt_setprop_cell(fdt, iommu_node, "#iommu-cells", 1);
143
+ qemu_fdt_setprop_cell(fdt, iommu_node, "phandle", iommu_phandle);
144
+
145
+ qemu_fdt_setprop_cells(fdt, iommu_node, "reg",
146
+ addr >> 32, addr, size >> 32, size);
147
+ qemu_fdt_setprop_cell(fdt, iommu_node, "interrupt-parent", irq_chip);
148
+
149
+ qemu_fdt_setprop_cells(fdt, iommu_node, "interrupts",
150
+ iommu_irq_map[0], FDT_IRQ_TYPE_EDGE_LOW,
151
+ iommu_irq_map[1], FDT_IRQ_TYPE_EDGE_LOW,
152
+ iommu_irq_map[2], FDT_IRQ_TYPE_EDGE_LOW,
153
+ iommu_irq_map[3], FDT_IRQ_TYPE_EDGE_LOW);
154
+
155
+ *iommu_sys_phandle = iommu_phandle;
156
+}
157
+
158
static void create_fdt_iommu(RISCVVirtState *s, uint16_t bdf)
159
{
160
const char comp[] = "riscv,pci-iommu";
161
@@ -XXX,XX +XXX,XX @@ static void finalize_fdt(RISCVVirtState *s)
162
{
163
uint32_t phandle = 1, irq_mmio_phandle = 1, msi_pcie_phandle = 1;
164
uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1;
165
+ uint32_t iommu_sys_phandle = 1;
166
167
create_fdt_sockets(s, virt_memmap, &phandle, &irq_mmio_phandle,
168
&irq_pcie_phandle, &irq_virtio_phandle,
169
@@ -XXX,XX +XXX,XX @@ static void finalize_fdt(RISCVVirtState *s)
170
171
create_fdt_virtio(s, virt_memmap, irq_virtio_phandle);
172
173
- create_fdt_pcie(s, virt_memmap, irq_pcie_phandle, msi_pcie_phandle);
174
+ if (virt_is_iommu_sys_enabled(s)) {
175
+ create_fdt_iommu_sys(s, irq_mmio_phandle, &iommu_sys_phandle);
176
+ }
177
+ create_fdt_pcie(s, virt_memmap, irq_pcie_phandle, msi_pcie_phandle,
178
+ iommu_sys_phandle);
179
180
create_fdt_reset(s, virt_memmap, &phandle);
181
182
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
183
create_fdt(s, memmap);
184
}
185
186
+ if (virt_is_iommu_sys_enabled(s)) {
187
+ DeviceState *iommu_sys = qdev_new(TYPE_RISCV_IOMMU_SYS);
188
+
189
+ object_property_set_uint(OBJECT(iommu_sys), "addr",
190
+ s->memmap[VIRT_IOMMU_SYS].base,
191
+ &error_fatal);
192
+ object_property_set_uint(OBJECT(iommu_sys), "base-irq",
193
+ IOMMU_SYS_IRQ,
194
+ &error_fatal);
195
+ object_property_set_link(OBJECT(iommu_sys), "irqchip",
196
+ OBJECT(mmio_irqchip),
197
+ &error_fatal);
198
+
199
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(iommu_sys), &error_fatal);
200
+ }
201
+
202
s->machine_done.notify = virt_machine_done;
203
qemu_add_machine_init_done_notifier(&s->machine_done);
204
}
205
@@ -XXX,XX +XXX,XX @@ static void virt_machine_instance_init(Object *obj)
206
s->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
207
s->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
208
s->acpi = ON_OFF_AUTO_AUTO;
209
+ s->iommu_sys = ON_OFF_AUTO_AUTO;
210
}
211
212
static char *virt_get_aia_guests(Object *obj, Error **errp)
213
@@ -XXX,XX +XXX,XX @@ static void virt_set_aclint(Object *obj, bool value, Error **errp)
214
s->have_aclint = value;
215
}
216
217
+bool virt_is_iommu_sys_enabled(RISCVVirtState *s)
218
+{
219
+ return s->iommu_sys == ON_OFF_AUTO_ON;
220
+}
221
+
222
+static void virt_get_iommu_sys(Object *obj, Visitor *v, const char *name,
223
+ void *opaque, Error **errp)
224
+{
225
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
226
+ OnOffAuto iommu_sys = s->iommu_sys;
227
+
228
+ visit_type_OnOffAuto(v, name, &iommu_sys, errp);
229
+}
230
+
231
+static void virt_set_iommu_sys(Object *obj, Visitor *v, const char *name,
232
+ void *opaque, Error **errp)
233
+{
234
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(obj);
235
+
236
+ visit_type_OnOffAuto(v, name, &s->iommu_sys, errp);
237
+}
238
+
239
bool virt_is_acpi_enabled(RISCVVirtState *s)
240
{
241
return s->acpi != ON_OFF_AUTO_OFF;
242
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
243
DeviceState *dev)
244
{
245
MachineClass *mc = MACHINE_GET_CLASS(machine);
246
+ RISCVVirtState *s = RISCV_VIRT_MACHINE(machine);
247
248
if (device_is_dynamic_sysbus(mc, dev) ||
249
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
250
object_dynamic_cast(OBJECT(dev), TYPE_RISCV_IOMMU_PCI)) {
251
+ s->iommu_sys = ON_OFF_AUTO_OFF;
252
return HOTPLUG_HANDLER(machine);
253
}
254
255
@@ -XXX,XX +XXX,XX @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev,
256
257
if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_IOMMU_PCI)) {
258
create_fdt_iommu(s, pci_get_bdf(PCI_DEVICE(dev)));
259
+ s->iommu_sys = ON_OFF_AUTO_OFF;
260
}
261
}
262
263
@@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
264
NULL, NULL);
265
object_class_property_set_description(oc, "acpi",
266
"Enable ACPI");
267
+
268
+ object_class_property_add(oc, "iommu-sys", "OnOffAuto",
269
+ virt_get_iommu_sys, virt_set_iommu_sys,
270
+ NULL, NULL);
271
+ object_class_property_set_description(oc, "iommu-sys",
272
+ "Enable IOMMU platform device");
273
}
274
275
static const TypeInfo virt_machine_typeinfo = {
58
--
276
--
59
2.38.1
277
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The priv spec v1.12 says:
3
MSIx support is added in the RISC-V IOMMU platform device by including
4
4
the required MSIx facilities to alow software to properly setup the MSIx
5
If no PMP entry matches an M-mode access, the access succeeds. If
5
subsystem.
6
no PMP entry matches an S-mode or U-mode access, but at least one
6
7
PMP entry is implemented, the access fails. Failed accesses generate
7
We took inspiration of what is being done in the riscv-iommu-pci device,
8
an instruction, load, or store access-fault exception.
8
mainly msix_init() and msix_notify(), while keeping in mind that
9
9
riscv-iommu-sys isn't a true PCI device and we don't need to copy/paste
10
At present the exception cause is set to 'illegal instruction' but
10
all the contents of these MSIx functions.
11
should have been 'instruction access fault'.
11
12
12
Two extra MSI MemoryRegions were added: 'msix-table' and 'msix-pba'.
13
Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is configured")
13
They are used to manage r/w of the MSI table and Pending Bit Array (PBA)
14
Signed-off-by: Bin Meng <bmeng@tinylab.org>
14
respectively. Both are subregions of the main IOMMU memory region,
15
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
15
iommu->regs_mr, initialized during riscv_iommu_realize(), and each one
16
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
has their own handlers for MSIx reads and writes.
17
Message-Id: <20221205065303.204095-1-bmeng@tinylab.org>
17
18
This is the expected memory map when using this device in the 'virt'
19
machine:
20
21
0000000003010000-0000000003010fff (prio 0, i/o): riscv-iommu-regs
22
0000000003010300-000000000301034f (prio 0, i/o): msix-table
23
0000000003010400-0000000003010407 (prio 0, i/o): msix-pba
24
25
We're now able to set IGS to RISCV_IOMMU_CAP_IGS_BOTH, and userspace is
26
free to decide which interrupt model to use.
27
28
Enabling MSIx support for this device in the 'virt' machine requires
29
adding 'msi-parent' in the iommu-sys DT.
30
31
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
32
Acked-by: Alistair Francis <alistair.francis@wdc.com>
33
Message-ID: <20241106133407.604587-6-dbarboza@ventanamicro.com>
34
[ Changes by AF:
35
- Used PRIx64 in trace
36
]
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
37
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
38
---
20
target/riscv/op_helper.c | 2 +-
39
hw/riscv/riscv-iommu-sys.c | 116 +++++++++++++++++++++++++++++++++++--
21
1 file changed, 1 insertion(+), 1 deletion(-)
40
hw/riscv/virt.c | 6 +-
22
41
hw/riscv/trace-events | 2 +
23
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
42
3 files changed, 119 insertions(+), 5 deletions(-)
43
44
diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
24
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
25
--- a/target/riscv/op_helper.c
46
--- a/hw/riscv/riscv-iommu-sys.c
26
+++ b/target/riscv/op_helper.c
47
+++ b/hw/riscv/riscv-iommu-sys.c
27
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
48
@@ -XXX,XX +XXX,XX @@
28
49
#include "qemu/host-utils.h"
29
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
50
#include "qemu/module.h"
30
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
51
#include "qom/object.h"
31
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
52
+#include "exec/exec-all.h"
32
+ riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
53
+#include "trace.h"
54
55
#include "riscv-iommu.h"
56
57
#define RISCV_IOMMU_SYSDEV_ICVEC_VECTORS 0x3333
58
59
+#define RISCV_IOMMU_PCI_MSIX_VECTORS 5
60
+
61
/* RISC-V IOMMU System Platform Device Emulation */
62
63
struct RISCVIOMMUStateSys {
64
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUStateSys {
65
uint32_t base_irq;
66
DeviceState *irqchip;
67
RISCVIOMMUState iommu;
68
+
69
+ /* Wired int support */
70
qemu_irq irqs[RISCV_IOMMU_INTR_COUNT];
71
+
72
+ /* Memory Regions for MSIX table and pending bit entries. */
73
+ MemoryRegion msix_table_mmio;
74
+ MemoryRegion msix_pba_mmio;
75
+ uint8_t *msix_table;
76
+ uint8_t *msix_pba;
77
+};
78
+
79
+static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr,
80
+ unsigned size)
81
+{
82
+ RISCVIOMMUStateSys *s = opaque;
83
+
84
+ g_assert(addr + size <= RISCV_IOMMU_PCI_MSIX_VECTORS * PCI_MSIX_ENTRY_SIZE);
85
+ return pci_get_long(s->msix_table + addr);
86
+}
87
+
88
+static void msix_table_mmio_write(void *opaque, hwaddr addr,
89
+ uint64_t val, unsigned size)
90
+{
91
+ RISCVIOMMUStateSys *s = opaque;
92
+
93
+ g_assert(addr + size <= RISCV_IOMMU_PCI_MSIX_VECTORS * PCI_MSIX_ENTRY_SIZE);
94
+ pci_set_long(s->msix_table + addr, val);
95
+}
96
+
97
+static const MemoryRegionOps msix_table_mmio_ops = {
98
+ .read = msix_table_mmio_read,
99
+ .write = msix_table_mmio_write,
100
+ .endianness = DEVICE_LITTLE_ENDIAN,
101
+ .valid = {
102
+ .min_access_size = 4,
103
+ .max_access_size = 8,
104
+ },
105
+ .impl = {
106
+ .max_access_size = 4,
107
+ },
108
+};
109
+
110
+static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr,
111
+ unsigned size)
112
+{
113
+ RISCVIOMMUStateSys *s = opaque;
114
+
115
+ return pci_get_long(s->msix_pba + addr);
116
+}
117
+
118
+static void msix_pba_mmio_write(void *opaque, hwaddr addr,
119
+ uint64_t val, unsigned size)
120
+{
121
+}
122
+
123
+static const MemoryRegionOps msix_pba_mmio_ops = {
124
+ .read = msix_pba_mmio_read,
125
+ .write = msix_pba_mmio_write,
126
+ .endianness = DEVICE_LITTLE_ENDIAN,
127
+ .valid = {
128
+ .min_access_size = 4,
129
+ .max_access_size = 8,
130
+ },
131
+ .impl = {
132
+ .max_access_size = 4,
133
+ },
134
};
135
136
+static void riscv_iommu_sysdev_init_msi(RISCVIOMMUStateSys *s,
137
+ uint32_t n_vectors)
138
+{
139
+ RISCVIOMMUState *iommu = &s->iommu;
140
+ uint32_t table_size = table_size = n_vectors * PCI_MSIX_ENTRY_SIZE;
141
+ uint32_t table_offset = RISCV_IOMMU_REG_MSI_CONFIG;
142
+ uint32_t pba_size = QEMU_ALIGN_UP(n_vectors, 64) / 8;
143
+ uint32_t pba_offset = RISCV_IOMMU_REG_MSI_CONFIG + 256;
144
+
145
+ s->msix_table = g_malloc0(table_size);
146
+ s->msix_pba = g_malloc0(pba_size);
147
+
148
+ memory_region_init_io(&s->msix_table_mmio, OBJECT(s), &msix_table_mmio_ops,
149
+ s, "msix-table", table_size);
150
+ memory_region_add_subregion(&iommu->regs_mr, table_offset,
151
+ &s->msix_table_mmio);
152
+
153
+ memory_region_init_io(&s->msix_pba_mmio, OBJECT(s), &msix_pba_mmio_ops, s,
154
+ "msix-pba", pba_size);
155
+ memory_region_add_subregion(&iommu->regs_mr, pba_offset,
156
+ &s->msix_pba_mmio);
157
+}
158
+
159
+static void riscv_iommu_sysdev_send_MSI(RISCVIOMMUStateSys *s,
160
+ uint32_t vector)
161
+{
162
+ uint8_t *table_entry = s->msix_table + vector * PCI_MSIX_ENTRY_SIZE;
163
+ uint64_t msi_addr = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
164
+ uint32_t msi_data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
165
+ MemTxResult result;
166
+
167
+ address_space_stl_le(&address_space_memory, msi_addr,
168
+ msi_data, MEMTXATTRS_UNSPECIFIED, &result);
169
+ trace_riscv_iommu_sys_msi_sent(vector, msi_addr, msi_data, result);
170
+}
171
+
172
static void riscv_iommu_sysdev_notify(RISCVIOMMUState *iommu,
173
unsigned vector)
174
{
175
RISCVIOMMUStateSys *s = container_of(iommu, RISCVIOMMUStateSys, iommu);
176
uint32_t fctl = riscv_iommu_reg_get32(iommu, RISCV_IOMMU_REG_FCTL);
177
178
- /* We do not support MSIs yet */
179
- if (!(fctl & RISCV_IOMMU_FCTL_WSI)) {
180
+ if (fctl & RISCV_IOMMU_FCTL_WSI) {
181
+ qemu_irq_pulse(s->irqs[vector]);
182
+ trace_riscv_iommu_sys_irq_sent(vector);
183
return;
33
}
184
}
34
185
35
target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
186
- qemu_irq_pulse(s->irqs[vector]);
187
+ riscv_iommu_sysdev_send_MSI(s, vector);
188
}
189
190
static void riscv_iommu_sys_realize(DeviceState *dev, Error **errp)
191
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_sys_realize(DeviceState *dev, Error **errp)
192
irq = qdev_get_gpio_in(s->irqchip, s->base_irq + i);
193
sysbus_connect_irq(sysdev, i, irq);
194
}
195
+
196
+ riscv_iommu_sysdev_init_msi(s, RISCV_IOMMU_PCI_MSIX_VECTORS);
197
}
198
199
static void riscv_iommu_sys_init(Object *obj)
200
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_sys_init(Object *obj)
201
qdev_alias_all_properties(DEVICE(iommu), obj);
202
203
iommu->icvec_avail_vectors = RISCV_IOMMU_SYSDEV_ICVEC_VECTORS;
204
- riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_WSI);
205
+ riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_BOTH);
206
}
207
208
static Property riscv_iommu_sys_properties[] = {
209
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
210
index XXXXXXX..XXXXXXX 100644
211
--- a/hw/riscv/virt.c
212
+++ b/hw/riscv/virt.c
213
@@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio_iommu(RISCVVirtState *s, uint16_t bdf)
214
}
215
216
static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip,
217
+ uint32_t msi_phandle,
218
uint32_t *iommu_sys_phandle)
219
{
220
const char comp[] = "riscv,iommu";
221
@@ -XXX,XX +XXX,XX @@ static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip,
222
iommu_irq_map[2], FDT_IRQ_TYPE_EDGE_LOW,
223
iommu_irq_map[3], FDT_IRQ_TYPE_EDGE_LOW);
224
225
+ qemu_fdt_setprop_cell(fdt, iommu_node, "msi-parent", msi_phandle);
226
+
227
*iommu_sys_phandle = iommu_phandle;
228
}
229
230
@@ -XXX,XX +XXX,XX @@ static void finalize_fdt(RISCVVirtState *s)
231
create_fdt_virtio(s, virt_memmap, irq_virtio_phandle);
232
233
if (virt_is_iommu_sys_enabled(s)) {
234
- create_fdt_iommu_sys(s, irq_mmio_phandle, &iommu_sys_phandle);
235
+ create_fdt_iommu_sys(s, irq_mmio_phandle, msi_pcie_phandle,
236
+ &iommu_sys_phandle);
237
}
238
create_fdt_pcie(s, virt_memmap, irq_pcie_phandle, msi_pcie_phandle,
239
iommu_sys_phandle);
240
diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events
241
index XXXXXXX..XXXXXXX 100644
242
--- a/hw/riscv/trace-events
243
+++ b/hw/riscv/trace-events
244
@@ -XXX,XX +XXX,XX @@ riscv_iommu_icvec_write(uint32_t orig, uint32_t actual) "ICVEC write: incoming 0
245
riscv_iommu_ats(const char *id, unsigned b, unsigned d, unsigned f, uint64_t iova) "%s: translate request %04x:%02x.%u iova: 0x%"PRIx64
246
riscv_iommu_ats_inval(const char *id) "%s: dev-iotlb invalidate"
247
riscv_iommu_ats_prgr(const char *id) "%s: dev-iotlb page request group response"
248
+riscv_iommu_sys_irq_sent(uint32_t vector) "IRQ sent to vector %u"
249
+riscv_iommu_sys_msi_sent(uint32_t vector, uint64_t msi_addr, uint32_t msi_data, uint32_t result) "MSI sent to vector %u msi_addr 0x%"PRIx64" msi_data 0x%x result %u"
36
--
250
--
37
2.38.1
251
2.47.1
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The system controller on PolarFire SoC is access via a mailbox. The
3
Add a riscv_iommu_reset() helper in the base emulation code that
4
control registers for this mailbox lie in the "IOSCB" region & the
4
implements the expected reset behavior as defined by the riscv-iommu
5
interrupt is cleared via write to the "SYSREG" region. It also has a
5
spec.
6
QSPI controller, usually connected to a flash chip, that is used for
6
7
storing FPGA bitstreams and used for In-Application Programming (IAP).
7
Devices can then use this helper in their own reset callbacks.
8
8
9
Linux has an implementation of the system controller, through which the
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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>
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
20
Message-Id: <20221117225518.4102575-4-conor@kernel.org>
11
Message-ID: <20241106133407.604587-7-dbarboza@ventanamicro.com>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
13
---
23
include/hw/misc/mchp_pfsoc_ioscb.h | 3 ++
14
hw/riscv/riscv-iommu.h | 1 +
24
include/hw/misc/mchp_pfsoc_sysreg.h | 1 +
15
include/hw/riscv/iommu.h | 6 ++++--
25
include/hw/riscv/microchip_pfsoc.h | 1 +
16
hw/riscv/riscv-iommu-pci.c | 20 ++++++++++++++++++++
26
hw/misc/mchp_pfsoc_ioscb.c | 72 ++++++++++++++++++++++++++++-
17
hw/riscv/riscv-iommu-sys.c | 20 ++++++++++++++++++++
27
hw/misc/mchp_pfsoc_sysreg.c | 18 ++++++--
18
hw/riscv/riscv-iommu.c | 35 +++++++++++++++++++++++++++++++++++
28
hw/riscv/microchip_pfsoc.c | 6 +++
19
hw/riscv/trace-events | 2 ++
29
6 files changed, 95 insertions(+), 6 deletions(-)
20
6 files changed, 82 insertions(+), 2 deletions(-)
30
21
31
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
22
diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h
32
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
33
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
24
--- a/hw/riscv/riscv-iommu.h
34
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
25
+++ b/hw/riscv/riscv-iommu.h
35
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
26
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUState {
36
MemoryRegion lane01;
27
void riscv_iommu_pci_setup_iommu(RISCVIOMMUState *iommu, PCIBus *bus,
37
MemoryRegion lane23;
28
Error **errp);
38
MemoryRegion ctrl;
29
void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode);
39
+ MemoryRegion qspixip;
30
+void riscv_iommu_reset(RISCVIOMMUState *s);
40
+ MemoryRegion mailbox;
31
41
MemoryRegion cfg;
32
/* private helpers */
42
MemoryRegion ccc;
33
43
MemoryRegion pll_mss;
34
diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h
44
@@ -XXX,XX +XXX,XX @@ typedef struct MchpPfSoCIoscbState {
35
index XXXXXXX..XXXXXXX 100644
45
MemoryRegion cfm_sgmii;
36
--- a/include/hw/riscv/iommu.h
46
MemoryRegion bc_sgmii;
37
+++ b/include/hw/riscv/iommu.h
47
MemoryRegion io_calib_sgmii;
38
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUState RISCVIOMMUState;
48
+ qemu_irq irq;
39
typedef struct RISCVIOMMUSpace RISCVIOMMUSpace;
49
} MchpPfSoCIoscbState;
40
50
41
#define TYPE_RISCV_IOMMU_PCI "riscv-iommu-pci"
51
#define TYPE_MCHP_PFSOC_IOSCB "mchp.pfsoc.ioscb"
42
-OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI)
52
diff --git a/include/hw/misc/mchp_pfsoc_sysreg.h b/include/hw/misc/mchp_pfsoc_sysreg.h
43
+OBJECT_DECLARE_TYPE(RISCVIOMMUStatePci, RISCVIOMMUPciClass, RISCV_IOMMU_PCI)
53
index XXXXXXX..XXXXXXX 100644
44
typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci;
54
--- a/include/hw/misc/mchp_pfsoc_sysreg.h
45
+typedef struct RISCVIOMMUPciClass RISCVIOMMUPciClass;
55
+++ b/include/hw/misc/mchp_pfsoc_sysreg.h
46
47
#define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device"
48
-OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS)
49
+OBJECT_DECLARE_TYPE(RISCVIOMMUStateSys, RISCVIOMMUSysClass, RISCV_IOMMU_SYS)
50
typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys;
51
+typedef struct RISCVIOMMUSysClass RISCVIOMMUSysClass;
52
53
#define FDT_IRQ_TYPE_EDGE_LOW 1
54
55
diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/riscv/riscv-iommu-pci.c
58
+++ b/hw/riscv/riscv-iommu-pci.c
56
@@ -XXX,XX +XXX,XX @@
59
@@ -XXX,XX +XXX,XX @@
57
typedef struct MchpPfSoCSysregState {
60
#include "cpu_bits.h"
58
SysBusDevice parent;
61
#include "riscv-iommu.h"
59
MemoryRegion sysreg;
62
#include "riscv-iommu-bits.h"
60
+ qemu_irq irq;
63
+#include "trace.h"
61
} MchpPfSoCSysregState;
64
62
65
/* RISC-V IOMMU PCI Device Emulation */
63
#define TYPE_MCHP_PFSOC_SYSREG "mchp.pfsoc.sysreg"
66
#define RISCV_PCI_CLASS_SYSTEM_IOMMU 0x0806
64
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
67
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUStatePci {
65
index XXXXXXX..XXXXXXX 100644
68
RISCVIOMMUState iommu; /* common IOMMU state */
66
--- a/include/hw/riscv/microchip_pfsoc.h
69
} RISCVIOMMUStatePci;
67
+++ b/include/hw/riscv/microchip_pfsoc.h
70
68
@@ -XXX,XX +XXX,XX @@ enum {
71
+struct RISCVIOMMUPciClass {
69
MICROCHIP_PFSOC_MMUART2_IRQ = 92,
72
+ /*< public >*/
70
MICROCHIP_PFSOC_MMUART3_IRQ = 93,
73
+ DeviceRealize parent_realize;
71
MICROCHIP_PFSOC_MMUART4_IRQ = 94,
74
+ ResettablePhases parent_phases;
72
+ MICROCHIP_PFSOC_MAILBOX_IRQ = 96,
75
+};
76
+
77
/* interrupt delivery callback */
78
static void riscv_iommu_pci_notify(RISCVIOMMUState *iommu, unsigned vector)
79
{
80
@@ -XXX,XX +XXX,XX @@ static const Property riscv_iommu_pci_properties[] = {
81
DEFINE_PROP_END_OF_LIST(),
73
};
82
};
74
83
75
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
84
+static void riscv_iommu_pci_reset_hold(Object *obj, ResetType type)
76
diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c
85
+{
77
index XXXXXXX..XXXXXXX 100644
86
+ RISCVIOMMUStatePci *pci = RISCV_IOMMU_PCI(obj);
78
--- a/hw/misc/mchp_pfsoc_ioscb.c
87
+ RISCVIOMMUState *iommu = &pci->iommu;
79
+++ b/hw/misc/mchp_pfsoc_ioscb.c
88
+
80
@@ -XXX,XX +XXX,XX @@
89
+ riscv_iommu_reset(iommu);
81
#include "qemu/bitops.h"
90
+
82
#include "qemu/log.h"
91
+ trace_riscv_iommu_pci_reset_hold(type);
83
#include "qapi/error.h"
92
+}
84
+#include "hw/irq.h"
93
+
85
#include "hw/sysbus.h"
94
static void riscv_iommu_pci_class_init(ObjectClass *klass, void *data)
86
#include "hw/misc/mchp_pfsoc_ioscb.h"
95
{
87
96
DeviceClass *dc = DEVICE_CLASS(klass);
88
@@ -XXX,XX +XXX,XX @@
97
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
89
#define IOSCB_WHOLE_REG_SIZE 0x10000000
98
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
90
#define IOSCB_SUBMOD_REG_SIZE 0x1000
99
+
91
#define IOSCB_CCC_REG_SIZE 0x2000000
100
+ rc->phases.hold = riscv_iommu_pci_reset_hold;
92
+#define IOSCB_CTRL_REG_SIZE 0x800
101
93
+#define IOSCB_QSPIXIP_REG_SIZE 0x200
102
k->realize = riscv_iommu_pci_realize;
94
+
103
k->exit = riscv_iommu_pci_exit;
95
104
diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
96
/*
105
index XXXXXXX..XXXXXXX 100644
97
* There are many sub-modules in the IOSCB module.
106
--- a/hw/riscv/riscv-iommu-sys.c
98
@@ -XXX,XX +XXX,XX @@
107
+++ b/hw/riscv/riscv-iommu-sys.c
99
#define IOSCB_LANE01_BASE 0x06500000
108
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUStateSys {
100
#define IOSCB_LANE23_BASE 0x06510000
109
uint8_t *msix_pba;
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
};
110
111
111
+#define SERVICES_CR 0x50
112
+struct RISCVIOMMUSysClass {
112
+#define SERVICES_SR 0x54
113
+ /*< public >*/
113
+#define SERVICES_STATUS_SHIFT 16
114
+ DeviceRealize parent_realize;
114
+
115
+ ResettablePhases parent_phases;
115
+static uint64_t mchp_pfsoc_ctrl_read(void *opaque, hwaddr offset,
116
+};
116
+ unsigned size)
117
+
118
static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr,
119
unsigned size)
120
{
121
@@ -XXX,XX +XXX,XX @@ static Property riscv_iommu_sys_properties[] = {
122
DEFINE_PROP_END_OF_LIST(),
123
};
124
125
+static void riscv_iommu_sys_reset_hold(Object *obj, ResetType type)
117
+{
126
+{
118
+ uint32_t val = 0;
127
+ RISCVIOMMUStateSys *sys = RISCV_IOMMU_SYS(obj);
119
+
128
+ RISCVIOMMUState *iommu = &sys->iommu;
120
+ switch (offset) {
129
+
121
+ case SERVICES_SR:
130
+ riscv_iommu_reset(iommu);
122
+ /*
131
+
123
+ * Although some services have no error codes, most do. All services
132
+ trace_riscv_iommu_sys_reset_hold(type);
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
+}
133
+}
139
+
134
+
140
+static void mchp_pfsoc_ctrl_write(void *opaque, hwaddr offset,
135
static void riscv_iommu_sys_class_init(ObjectClass *klass, void *data)
141
+ uint64_t value, unsigned size)
136
{
137
DeviceClass *dc = DEVICE_CLASS(klass);
138
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
139
+
140
+ rc->phases.hold = riscv_iommu_sys_reset_hold;
141
+
142
dc->realize = riscv_iommu_sys_realize;
143
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
144
device_class_set_props(dc, riscv_iommu_sys_properties);
145
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
146
index XXXXXXX..XXXXXXX 100644
147
--- a/hw/riscv/riscv-iommu.c
148
+++ b/hw/riscv/riscv-iommu.c
149
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_unrealize(DeviceState *dev)
150
g_hash_table_unref(s->ctx_cache);
151
}
152
153
+void riscv_iommu_reset(RISCVIOMMUState *s)
142
+{
154
+{
143
+ MchpPfSoCIoscbState *s = opaque;
155
+ uint32_t reg_clr;
144
+
156
+ int ddtp_mode;
145
+ switch (offset) {
157
+
146
+ case SERVICES_CR:
158
+ /*
147
+ qemu_irq_raise(s->irq);
159
+ * Clear DDTP while setting DDTP_mode back to user
148
+ break;
160
+ * initial setting.
149
+ default:
161
+ */
150
+ qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write "
162
+ ddtp_mode = s->enable_off ?
151
+ "(size %d, value 0x%" PRIx64
163
+ RISCV_IOMMU_DDTP_MODE_OFF : RISCV_IOMMU_DDTP_MODE_BARE;
152
+ ", offset 0x%" HWADDR_PRIx ")\n",
164
+ s->ddtp = set_field(0, RISCV_IOMMU_DDTP_MODE, ddtp_mode);
153
+ __func__, size, value, offset);
165
+ riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_DDTP, s->ddtp);
154
+ }
166
+
167
+ reg_clr = RISCV_IOMMU_CQCSR_CQEN | RISCV_IOMMU_CQCSR_CIE |
168
+ RISCV_IOMMU_CQCSR_CQON | RISCV_IOMMU_CQCSR_BUSY;
169
+ riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_CQCSR, 0, reg_clr);
170
+
171
+ reg_clr = RISCV_IOMMU_FQCSR_FQEN | RISCV_IOMMU_FQCSR_FIE |
172
+ RISCV_IOMMU_FQCSR_FQON | RISCV_IOMMU_FQCSR_BUSY;
173
+ riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_FQCSR, 0, reg_clr);
174
+
175
+ reg_clr = RISCV_IOMMU_PQCSR_PQEN | RISCV_IOMMU_PQCSR_PIE |
176
+ RISCV_IOMMU_PQCSR_PQON | RISCV_IOMMU_PQCSR_BUSY;
177
+ riscv_iommu_reg_mod32(s, RISCV_IOMMU_REG_PQCSR, 0, reg_clr);
178
+
179
+ riscv_iommu_reg_mod64(s, RISCV_IOMMU_REG_TR_REQ_CTL, 0,
180
+ RISCV_IOMMU_TR_REQ_CTL_GO_BUSY);
181
+
182
+ riscv_iommu_reg_set32(s, RISCV_IOMMU_REG_IPSR, 0);
183
+
184
+ g_hash_table_remove_all(s->ctx_cache);
185
+ g_hash_table_remove_all(s->iot_cache);
155
+}
186
+}
156
+
187
+
157
+static const MemoryRegionOps mchp_pfsoc_ctrl_ops = {
188
static const Property riscv_iommu_properties[] = {
158
+ .read = mchp_pfsoc_ctrl_read,
189
DEFINE_PROP_UINT32("version", RISCVIOMMUState, version,
159
+ .write = mchp_pfsoc_ctrl_write,
190
RISCV_IOMMU_SPEC_DOT_VER),
160
+ .endianness = DEVICE_LITTLE_ENDIAN,
191
diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events
161
+};
192
index XXXXXXX..XXXXXXX 100644
162
+
193
--- a/hw/riscv/trace-events
163
static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
194
+++ b/hw/riscv/trace-events
164
{
195
@@ -XXX,XX +XXX,XX @@ riscv_iommu_ats_inval(const char *id) "%s: dev-iotlb invalidate"
165
MchpPfSoCIoscbState *s = MCHP_PFSOC_IOSCB(dev);
196
riscv_iommu_ats_prgr(const char *id) "%s: dev-iotlb page request group response"
166
@@ -XXX,XX +XXX,XX @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp)
197
riscv_iommu_sys_irq_sent(uint32_t vector) "IRQ sent to vector %u"
167
"mchp.pfsoc.ioscb.lane23", IOSCB_SUBMOD_REG_SIZE);
198
riscv_iommu_sys_msi_sent(uint32_t vector, uint64_t msi_addr, uint32_t msi_data, uint32_t result) "MSI sent to vector %u msi_addr 0x%"PRIx64" msi_data 0x%x result %u"
168
memory_region_add_subregion(&s->container, IOSCB_LANE23_BASE, &s->lane23);
199
+riscv_iommu_sys_reset_hold(int reset_type) "reset type %d"
169
200
+riscv_iommu_pci_reset_hold(int reset_type) "reset type %d"
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
--
201
--
268
2.38.1
202
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Since priv spec v1.12, MRET and SRET now clear mstatus.MPRV when
3
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
4
leaving M-mode.
5
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221207090037.281452-2-bmeng@tinylab.org>
5
Message-ID: <20241106133407.604587-8-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
7
---
11
target/riscv/op_helper.c | 6 ++++++
8
docs/specs/riscv-iommu.rst | 30 +++++++++++++++++++++++++++---
12
1 file changed, 6 insertions(+)
9
docs/system/riscv/virt.rst | 10 ++++++++++
10
2 files changed, 37 insertions(+), 3 deletions(-)
13
11
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
12
diff --git a/docs/specs/riscv-iommu.rst b/docs/specs/riscv-iommu.rst
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/op_helper.c
14
--- a/docs/specs/riscv-iommu.rst
17
+++ b/target/riscv/op_helper.c
15
+++ b/docs/specs/riscv-iommu.rst
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
16
@@ -XXX,XX +XXX,XX @@ RISC-V IOMMU support for RISC-V machines
19
get_field(mstatus, MSTATUS_SPIE));
17
QEMU implements a RISC-V IOMMU emulation based on the RISC-V IOMMU spec
20
mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
18
version 1.0 `iommu1.0`_.
21
mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
19
22
+ if (env->priv_ver >= PRIV_VERSION_1_12_0) {
20
-The emulation includes a PCI reference device, riscv-iommu-pci, that QEMU
23
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
21
-RISC-V boards can use. The 'virt' RISC-V machine is compatible with this
24
+ }
22
-device.
25
env->mstatus = mstatus;
23
+The emulation includes a PCI reference device (riscv-iommu-pci) and a platform
26
24
+bus device (riscv-iommu-sys) that QEMU RISC-V boards can use. The 'virt'
27
if (riscv_has_ext(env, RVH) && !riscv_cpu_virt_enabled(env)) {
25
+RISC-V machine is compatible with both devices.
28
@@ -XXX,XX +XXX,XX @@ target_ulong helper_mret(CPURISCVState *env)
26
29
mstatus = set_field(mstatus, MSTATUS_MPIE, 1);
27
riscv-iommu-pci reference device
30
mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
28
--------------------------------
31
mstatus = set_field(mstatus, MSTATUS_MPV, 0);
29
@@ -XXX,XX +XXX,XX @@ Several options are available to control the capabilities of the device, namely:
32
+ if ((env->priv_ver >= PRIV_VERSION_1_12_0) && (prev_priv != PRV_M)) {
30
- "s-stage": enable s-stage support
33
+ mstatus = set_field(mstatus, MSTATUS_MPRV, 0);
31
- "g-stage": enable g-stage support
34
+ }
32
35
env->mstatus = mstatus;
33
+riscv-iommu-sys device
36
riscv_cpu_set_mode(env, prev_priv);
34
+----------------------
35
+
36
+This device implements the RISC-V IOMMU emulation as a platform bus device that
37
+RISC-V boards can use.
38
+
39
+For the 'virt' board the device is disabled by default. To enable it use the
40
+'iommu-sys' machine option:
41
+
42
+.. code-block:: bash
43
+
44
+ $ qemu-system-riscv64 -M virt,iommu-sys=on (...)
45
+
46
+There is no options to configure the capabilities of this device in the 'virt'
47
+board using the QEMU command line. The device is configured with the following
48
+riscv-iommu options:
49
+
50
+- "ioatc-limit": default value (2Mb)
51
+- "intremap": enabled
52
+- "ats": enabled
53
+- "off": on (DMA disabled)
54
+- "s-stage": enabled
55
+- "g-stage": enabled
56
+
57
.. _iommu1.0: https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf
58
59
.. _linux-v8: https://lore.kernel.org/linux-riscv/cover.1718388908.git.tjeznach@rivosinc.com/
60
diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst
61
index XXXXXXX..XXXXXXX 100644
62
--- a/docs/system/riscv/virt.rst
63
+++ b/docs/system/riscv/virt.rst
64
@@ -XXX,XX +XXX,XX @@ command line:
65
66
$ qemu-system-riscv64 -M virt -device riscv-iommu-pci (...)
67
68
+It also has support for the riscv-iommu-sys platform device:
69
+
70
+.. code-block:: bash
71
+
72
+ $ qemu-system-riscv64 -M virt,iommu-sys=on (...)
73
+
74
Refer to :ref:`riscv-iommu` for more information on how the RISC-V IOMMU support
75
works.
76
77
@@ -XXX,XX +XXX,XX @@ The following machine-specific options are supported:
78
having AIA IMSIC (i.e. "aia=aplic-imsic" selected). When not specified,
79
the default number of per-HART VS-level AIA IMSIC pages is 0.
80
81
+- iommu-sys=[on|off]
82
+
83
+ Enables the riscv-iommu-sys platform device. Defaults to 'off'.
84
+
85
Running Linux kernel
86
--------------------
37
87
38
--
88
--
39
2.38.1
89
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Anton Blanchard <antonb@tenstorrent.com>
2
2
3
"hartid-base" and "priority-base" are zero by default. There is no
3
Add a CPU entry for the Tenstorrent Ascalon CPU, a series of 2 wide to
4
need to initialize them to zero again.
4
8 wide RV64 cores. More details can be found at
5
https://tenstorrent.com/ip/tt-ascalon
5
6
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Anton Blanchard <antonb@tenstorrent.com>
7
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-Id: <20221211030829.802437-15-bmeng@tinylab.org>
10
Message-ID: <20241113110459.1607299-1-antonb@tenstorrent.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
---
12
hw/riscv/opentitan.c | 2 --
13
target/riscv/cpu-qom.h | 1 +
13
1 file changed, 2 deletions(-)
14
target/riscv/cpu.c | 67 ++++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 68 insertions(+)
14
16
15
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
17
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/opentitan.c
19
--- a/target/riscv/cpu-qom.h
18
+++ b/hw/riscv/opentitan.c
20
+++ b/target/riscv/cpu-qom.h
19
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
21
@@ -XXX,XX +XXX,XX @@
20
22
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
21
/* PLIC */
23
#define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906")
22
qdev_prop_set_string(DEVICE(&s->plic), "hart-config", "M");
24
#define TYPE_RISCV_CPU_VEYRON_V1 RISCV_CPU_TYPE_NAME("veyron-v1")
23
- qdev_prop_set_uint32(DEVICE(&s->plic), "hartid-base", 0);
25
+#define TYPE_RISCV_CPU_TT_ASCALON RISCV_CPU_TYPE_NAME("tt-ascalon")
24
qdev_prop_set_uint32(DEVICE(&s->plic), "num-sources", 180);
26
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
25
qdev_prop_set_uint32(DEVICE(&s->plic), "num-priorities", 3);
27
26
- qdev_prop_set_uint32(DEVICE(&s->plic), "priority-base", 0x00);
28
OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
27
qdev_prop_set_uint32(DEVICE(&s->plic), "pending-base", 0x1000);
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
28
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-base", 0x2000);
30
index XXXXXXX..XXXXXXX 100644
29
qdev_prop_set_uint32(DEVICE(&s->plic), "enable-stride", 32);
31
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static void rv64_veyron_v1_cpu_init(Object *obj)
34
#endif
35
}
36
37
+/* Tenstorrent Ascalon */
38
+static void rv64_tt_ascalon_cpu_init(Object *obj)
39
+{
40
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
41
+ RISCVCPU *cpu = RISCV_CPU(obj);
42
+
43
+ riscv_cpu_set_misa_ext(env, RVG | RVC | RVS | RVU | RVH | RVV);
44
+ env->priv_ver = PRIV_VERSION_1_13_0;
45
+
46
+ /* Enable ISA extensions */
47
+ cpu->cfg.mmu = true;
48
+ cpu->cfg.vlenb = 256 >> 3;
49
+ cpu->cfg.elen = 64;
50
+ cpu->env.vext_ver = VEXT_VERSION_1_00_0;
51
+ cpu->cfg.rvv_ma_all_1s = true;
52
+ cpu->cfg.rvv_ta_all_1s = true;
53
+ cpu->cfg.misa_w = true;
54
+ cpu->cfg.pmp = true;
55
+ cpu->cfg.cbom_blocksize = 64;
56
+ cpu->cfg.cbop_blocksize = 64;
57
+ cpu->cfg.cboz_blocksize = 64;
58
+ cpu->cfg.ext_zic64b = true;
59
+ cpu->cfg.ext_zicbom = true;
60
+ cpu->cfg.ext_zicbop = true;
61
+ cpu->cfg.ext_zicboz = true;
62
+ cpu->cfg.ext_zicntr = true;
63
+ cpu->cfg.ext_zicond = true;
64
+ cpu->cfg.ext_zicsr = true;
65
+ cpu->cfg.ext_zifencei = true;
66
+ cpu->cfg.ext_zihintntl = true;
67
+ cpu->cfg.ext_zihintpause = true;
68
+ cpu->cfg.ext_zihpm = true;
69
+ cpu->cfg.ext_zimop = true;
70
+ cpu->cfg.ext_zawrs = true;
71
+ cpu->cfg.ext_zfa = true;
72
+ cpu->cfg.ext_zfbfmin = true;
73
+ cpu->cfg.ext_zfh = true;
74
+ cpu->cfg.ext_zfhmin = true;
75
+ cpu->cfg.ext_zcb = true;
76
+ cpu->cfg.ext_zcmop = true;
77
+ cpu->cfg.ext_zba = true;
78
+ cpu->cfg.ext_zbb = true;
79
+ cpu->cfg.ext_zbs = true;
80
+ cpu->cfg.ext_zkt = true;
81
+ cpu->cfg.ext_zvbb = true;
82
+ cpu->cfg.ext_zvbc = true;
83
+ cpu->cfg.ext_zvfbfmin = true;
84
+ cpu->cfg.ext_zvfbfwma = true;
85
+ cpu->cfg.ext_zvfh = true;
86
+ cpu->cfg.ext_zvfhmin = true;
87
+ cpu->cfg.ext_zvkng = true;
88
+ cpu->cfg.ext_smaia = true;
89
+ cpu->cfg.ext_smstateen = true;
90
+ cpu->cfg.ext_ssaia = true;
91
+ cpu->cfg.ext_sscofpmf = true;
92
+ cpu->cfg.ext_sstc = true;
93
+ cpu->cfg.ext_svade = true;
94
+ cpu->cfg.ext_svinval = true;
95
+ cpu->cfg.ext_svnapot = true;
96
+ cpu->cfg.ext_svpbmt = true;
97
+
98
+#ifndef CONFIG_USER_ONLY
99
+ set_satp_mode_max_supported(cpu, VM_1_10_SV57);
100
+#endif
101
+}
102
+
103
#ifdef CONFIG_TCG
104
static void rv128_base_cpu_init(Object *obj)
105
{
106
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
107
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, MXL_RV64, rv64_sifive_u_cpu_init),
108
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C, MXL_RV64, rv64_sifive_u_cpu_init),
109
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64, rv64_thead_c906_cpu_init),
110
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64, rv64_tt_ascalon_cpu_init),
111
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, MXL_RV64, rv64_veyron_v1_cpu_init),
112
#ifdef CONFIG_TCG
113
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, MXL_RV128, rv128_base_cpu_init),
30
--
114
--
31
2.38.1
115
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The realize() callback has an errp for us to propagate the error up.
3
The helper is_kvm_aia() is checking not only for AIA, but for
4
While we are here, correct the wrong multi-line comment format.
4
aplic-imsic (i.e. "aia=aplic-imsic" in 'virt' RISC-V machine) with an
5
in-kernel chip present.
5
6
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Rename it to be a bit clear what the helper is doing since we'll add
8
more AIA helpers in the next patches.
9
10
Make the helper public because the 'virt' machine will use it as well.
11
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
14
Message-ID: <20241119191706.718860-2-dbarboza@ventanamicro.com>
9
Message-Id: <20221211030829.802437-8-bmeng@tinylab.org>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
16
---
12
hw/intc/sifive_plic.c | 7 ++++---
17
include/hw/intc/riscv_aplic.h | 1 +
13
1 file changed, 4 insertions(+), 3 deletions(-)
18
hw/intc/riscv_aplic.c | 8 ++++----
19
2 files changed, 5 insertions(+), 4 deletions(-)
14
20
15
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
21
diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/intc/sifive_plic.c
23
--- a/include/hw/intc/riscv_aplic.h
18
+++ b/hw/intc/sifive_plic.c
24
+++ b/include/hw/intc/riscv_aplic.h
19
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
25
@@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState {
20
s->m_external_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
26
};
21
qdev_init_gpio_out(dev, s->m_external_irqs, s->num_harts);
27
22
28
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
23
- /* We can't allow the supervisor to control SEIP as this would allow the
29
+bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
24
+ /*
30
25
+ * We can't allow the supervisor to control SEIP as this would allow the
31
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
26
* supervisor to clear a pending external interrupt which will result in
32
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
27
* lost a interrupt in the case a PLIC is attached. The SEIP bit must be
33
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
28
* hardware controlled when a PLIC is attached.
34
index XXXXXXX..XXXXXXX 100644
29
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
35
--- a/hw/intc/riscv_aplic.c
30
for (i = 0; i < s->num_harts; i++) {
36
+++ b/hw/intc/riscv_aplic.c
31
RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i));
37
@@ -XXX,XX +XXX,XX @@
32
if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
38
* KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
33
- error_report("SEIP already claimed");
39
* APLIC Wired.
34
- exit(1);
40
*/
35
+ error_setg(errp, "SEIP already claimed");
41
-static bool is_kvm_aia(bool msimode)
36
+ return;
42
+bool riscv_is_kvm_aia_aplic_imsic(bool msimode)
37
}
43
{
44
return kvm_irqchip_in_kernel() && msimode;
45
}
46
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
47
uint32_t i;
48
RISCVAPLICState *aplic = RISCV_APLIC(dev);
49
50
- if (!is_kvm_aia(aplic->msimode)) {
51
+ if (!riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) {
52
aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
53
aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
54
aplic->state = g_new0(uint32_t, aplic->num_irqs);
55
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
56
* have IRQ lines delegated by their parent APLIC.
57
*/
58
if (!aplic->parent) {
59
- if (kvm_enabled() && is_kvm_aia(aplic->msimode)) {
60
+ if (kvm_enabled() && riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) {
61
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
62
} else {
63
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
64
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
65
66
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
67
68
- if (!is_kvm_aia(msimode)) {
69
+ if (!riscv_is_kvm_aia_aplic_imsic(msimode)) {
70
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
38
}
71
}
39
72
40
--
73
--
41
2.38.1
74
2.47.1
diff view generated by jsdifflib
1
From: Atish Patra <atishp@rivosinc.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
The imsic DT binding[1] has changed and no longer require an ipi-id.
3
In create_fdt_sockets() we have the following pattern:
4
The latest IMSIC driver dynamically allocates ipi id if slow-ipi
5
is not defined.
6
4
7
Get rid of the unused dt property which may lead to confusion.
5
if (kvm_enabled() && virt_use_kvm_aia(s)) {
6
(... do stuff ...)
7
} else {
8
(... do other stuff ...)
9
}
10
if (kvm_enabled() && virt_use_kvm_aia(s)) {
11
(... do more stuff ...)
12
} else {
13
(... do more other stuff)
14
}
8
15
9
[1] https://lore.kernel.org/lkml/20221111044207.1478350-5-apatel@ventanamicro.com/
16
Do everything in a single if/else clause to reduce the usage of
17
virt_use_kvm_aia() helper and to make the code a bit less repetitive.
10
18
11
Signed-off-by: Atish Patra <atishp@rivosinc.com>
19
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-Id: <20221122080529.1692533-1-atishp@rivosinc.com>
21
Message-ID: <20241119191706.718860-3-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
23
---
16
include/hw/riscv/virt.h | 1 -
24
hw/riscv/virt.c | 10 ++++------
17
hw/riscv/virt.c | 4 ----
25
1 file changed, 4 insertions(+), 6 deletions(-)
18
2 files changed, 5 deletions(-)
19
26
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
27
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
33
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
34
--- a/hw/riscv/virt.c
29
--- a/hw/riscv/virt.c
35
+++ b/hw/riscv/virt.c
30
+++ b/hw/riscv/virt.c
36
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
31
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
37
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
32
msi_m_phandle, msi_s_phandle, phandle,
38
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
33
&intc_phandles[0], xplic_phandles,
39
VIRT_IRQCHIP_NUM_MSIS);
34
ms->smp.cpus);
40
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
35
+
41
- VIRT_IRQCHIP_IPI_MSI);
36
+ *irq_mmio_phandle = xplic_phandles[0];
42
if (riscv_socket_count(mc) > 1) {
37
+ *irq_virtio_phandle = xplic_phandles[0];
43
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
38
+ *irq_pcie_phandle = xplic_phandles[0];
44
imsic_num_bits(imsic_max_hart_per_socket));
39
} else {
45
@@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap,
40
phandle_pos = ms->smp.cpus;
46
riscv_socket_count(mc) * sizeof(uint32_t) * 4);
41
for (socket = (socket_count - 1); socket >= 0; socket--) {
47
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
42
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
48
VIRT_IRQCHIP_NUM_MSIS);
43
s->soc[socket].num_harts);
49
- qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
44
}
50
- VIRT_IRQCHIP_IPI_MSI);
45
}
51
if (imsic_guest_bits) {
46
- }
52
qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,guest-index-bits",
47
53
imsic_guest_bits);
48
- if (kvm_enabled() && virt_use_kvm_aia(s)) {
49
- *irq_mmio_phandle = xplic_phandles[0];
50
- *irq_virtio_phandle = xplic_phandles[0];
51
- *irq_pcie_phandle = xplic_phandles[0];
52
- } else {
53
for (socket = 0; socket < socket_count; socket++) {
54
if (socket == 0) {
55
*irq_mmio_phandle = xplic_phandles[socket];
54
--
56
--
55
2.38.1
57
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
There are 2 paths in helper_sret() and the same mstatus update codes
3
Similar to the riscv_is_kvm_aia_aplic_imsic() helper from riscv_aplic.c,
4
are replicated. Extract the common parts to simplify it a little bit.
4
the existing virt_use_kvm_aia() is testing for KVM aia=aplic-imsic with
5
in-kernel irqchip enabled. It is not checking for a generic AIA support.
5
6
6
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Rename the helper to virt_use_kvm_aia_aplic_imsic() to reflect what the
8
helper is doing, and use the existing riscv_is_kvm_aia_aplic_imsic() to
9
obscure details such as the presence of the in-kernel irqchip.
10
11
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221207090037.281452-1-bmeng@tinylab.org>
13
Message-ID: <20241119191706.718860-4-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
target/riscv/op_helper.c | 20 ++++++--------------
16
hw/riscv/virt.c | 12 +++++++-----
12
1 file changed, 6 insertions(+), 14 deletions(-)
17
1 file changed, 7 insertions(+), 5 deletions(-)
13
18
14
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
19
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
15
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/op_helper.c
21
--- a/hw/riscv/virt.c
17
+++ b/target/riscv/op_helper.c
22
+++ b/hw/riscv/virt.c
18
@@ -XXX,XX +XXX,XX @@ target_ulong helper_sret(CPURISCVState *env)
23
@@ -XXX,XX +XXX,XX @@
24
#include "hw/virtio/virtio-iommu.h"
25
26
/* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */
27
-static bool virt_use_kvm_aia(RISCVVirtState *s)
28
+static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type)
29
{
30
- return kvm_irqchip_in_kernel() && s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
31
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
32
+
33
+ return riscv_is_kvm_aia_aplic_imsic(msimode);
34
}
35
36
static bool virt_aclint_allowed(void)
37
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
38
*msi_pcie_phandle = msi_s_phandle;
19
}
39
}
20
40
21
mstatus = env->mstatus;
41
- /* KVM AIA only has one APLIC instance */
22
+ prev_priv = get_field(mstatus, MSTATUS_SPP);
42
- if (kvm_enabled() && virt_use_kvm_aia(s)) {
23
+ mstatus = set_field(mstatus, MSTATUS_SIE,
43
+ /* KVM AIA aplic-imsic only has one APLIC instance */
24
+ get_field(mstatus, MSTATUS_SPIE));
44
+ if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) {
25
+ mstatus = set_field(mstatus, MSTATUS_SPIE, 1);
45
create_fdt_socket_aplic(s, memmap, 0,
26
+ mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
46
msi_m_phandle, msi_s_phandle, phandle,
27
+ env->mstatus = mstatus;
47
&intc_phandles[0], xplic_phandles,
28
48
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
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
}
49
}
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
}
50
}
59
51
60
riscv_cpu_set_mode(env, prev_priv);
52
- if (kvm_enabled() && virt_use_kvm_aia(s)) {
53
+ if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) {
54
kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT,
55
VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS,
56
memmap[VIRT_APLIC_S].base,
61
--
57
--
62
2.38.1
58
2.47.1
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Only the pmp index that be checked by pmp_hart_has_privs can be used
3
Before adding support to kernel-irqchip=split when using KVM AIA we need
4
by pmp_get_tlb_size to avoid an error pmp index.
4
to change how we create the in-kernel AIA device.
5
5
6
Before modification, we may use an error pmp index. For example,
6
In the use case we have so far, i.e. in-kernel irqchip without split
7
we check address 0x4fc, and the size 0x4 in pmp_hart_has_privs. If there
7
mode, both the s-mode APLIC and IMSIC controllers are provided by the
8
is an pmp rule, valid range is [0x4fc, 0x500), then pmp_hart_has_privs
8
irqchip. In irqchip_split() mode we'll emulate the s-mode APLIC
9
will return true;
9
controller, which will send MSIs to the in-kernel IMSIC controller. To
10
do that we need to change kvm_riscv_aia_create() to not create the
11
in-kernel s-mode APLIC controller.
10
12
11
However, this checked pmp index is discarded as pmp_hart_has_privs
13
In the kernel source arch/riscv/kvm/aia_aplic.c, function
12
return bool value. In pmp_is_range_in_tlb, it will traverse all pmp
14
kvm_riscv_aia_aplic_init(), we verify that the APLIC controller won't be
13
rules. The tlb_sa will be 0x0, and tlb_ea will be 0xfff. If there is
15
instantiated by KVM if we do not set 'nr_sources', which is set via
14
a pmp rule [0x10, 0x14), it will be misused as it is legal in
16
KVM_DEV_RISCV_AIA_CONFIG_SRCS. For QEMU this means that we should not
15
pmp_get_tlb_size.
17
set 'aia_irq_num' during kvm_riscv_aia_create() in irqchip_split() mode.
16
18
17
As we have already known the correct pmp index, just remove the
19
In this same condition, skip KVM_DEV_RISCV_AIA_ADDR_APLIC as well since
18
remove the pmp_is_range_in_tlb and get tlb size directly from
20
it is used to set the base address for the in-kernel APLIC controller.
19
pmp_get_tlb_size.
20
21
21
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
22
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
23
Message-Id: <20221012060016.30856-1-zhiwei_liu@linux.alibaba.com>
24
Message-ID: <20241119191706.718860-5-dbarboza@ventanamicro.com>
24
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
25
---
26
---
26
target/riscv/pmp.h | 6 +--
27
target/riscv/kvm/kvm-cpu.c | 38 +++++++++++++++++++++++---------------
27
target/riscv/cpu_helper.c | 16 ++++---
28
1 file changed, 23 insertions(+), 15 deletions(-)
28
target/riscv/pmp.c | 90 +++++++++++++--------------------------
29
3 files changed, 42 insertions(+), 70 deletions(-)
30
29
31
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
30
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
32
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/pmp.h
32
--- a/target/riscv/kvm/kvm-cpu.c
34
+++ b/target/riscv/pmp.h
33
+++ b/target/riscv/kvm/kvm-cpu.c
35
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env);
34
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
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
}
35
}
137
}
36
}
138
37
139
/* No rule matched */
38
- ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
140
if (ret == -1) {
39
- KVM_DEV_RISCV_AIA_CONFIG_SRCS,
141
- return pmp_hart_has_privs_default(env, addr, size, privs,
40
- &aia_irq_num, true, NULL);
142
- allowed_privs, mode);
41
- if (ret < 0) {
143
+ if (pmp_hart_has_privs_default(env, addr, size, privs,
42
- error_report("KVM AIA: failed to set number of input irq lines");
144
+ allowed_privs, mode)) {
43
- exit(1);
145
+ ret = MAX_RISCV_PMPS;
44
- }
45
+ /*
46
+ * Skip APLIC creation in KVM if we're running split mode.
47
+ * This is done by leaving KVM_DEV_RISCV_AIA_CONFIG_SRCS
48
+ * unset. We can also skip KVM_DEV_RISCV_AIA_ADDR_APLIC
49
+ * since KVM won't be using it.
50
+ */
51
+ if (!kvm_kernel_irqchip_split()) {
52
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
53
+ KVM_DEV_RISCV_AIA_CONFIG_SRCS,
54
+ &aia_irq_num, true, NULL);
55
+ if (ret < 0) {
56
+ error_report("KVM AIA: failed to set number of input irq lines");
57
+ exit(1);
146
+ }
58
+ }
59
+
60
+ ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
61
+ KVM_DEV_RISCV_AIA_ADDR_APLIC,
62
+ &aplic_base, true, NULL);
63
+ if (ret < 0) {
64
+ error_report("KVM AIA: failed to set the base address of APLIC");
65
+ exit(1);
66
+ }
67
+ }
68
69
ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
70
KVM_DEV_RISCV_AIA_CONFIG_IDS,
71
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
72
exit(1);
147
}
73
}
148
74
149
- return ret == 1 ? true : false;
75
- ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
150
+ return ret;
76
- KVM_DEV_RISCV_AIA_ADDR_APLIC,
151
}
77
- &aplic_base, true, NULL);
152
78
- if (ret < 0) {
153
/*
79
- error_report("KVM AIA: failed to set the base address of APLIC");
154
@@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env)
80
- exit(1);
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
- }
81
- }
169
-
82
-
170
- if (pmp_sa >= tlb_sa && pmp_sa <= tlb_ea && pmp_ea >= tlb_ea) {
83
for (socket = 0; socket < socket_count; socket++) {
171
- return tlb_ea - pmp_sa + 1;
84
socket_imsic_base = imsic_base + socket * (1U << group_shift);
172
- }
85
hart_count = riscv_socket_hart_count(machine, socket);
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
--
86
--
233
2.38.1
87
2.47.1
diff view generated by jsdifflib
Deleted patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
2
1
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
Deleted patch
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
2
1
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
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
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
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
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
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
When icount is not enabled, there is no API in QEMU that can get the
3
The current logic to determine if we don't need an emulated APLIC
4
guest instruction number.
4
controller, i.e. KVM will provide for us, is to determine if we're
5
running KVM, with in-kernel irqchip support, and running
6
aia=aplic-imsic. This is modelled by riscv_is_kvm_aia_aplic_imsic() and
7
virt_use_kvm_aia_aplic_imsic().
5
8
6
Translate the guest code in a way that each TB only has one instruction.
9
This won't suffice to support irqchip_split() mode: it will match
7
After executing the instruction, decrease the count by 1 until it reaches 0
10
exactly the same conditions as the one above, but setting the irqchip to
8
where the itrigger fires.
11
'split' mode will now require us to emulate an APLIC s-mode controller,
12
like we're doing with 'aia=aplic'.
9
13
10
Note that only when priviledge matches the itrigger configuration,
14
Create a new riscv_use_emulated_aplic() helper that will encapsulate
11
the count will decrease.
15
this logic. Replace the uses of "riscv_is_kvm_aia_aplic_imsic()" with
16
this helper every time we're taking a decision on emulate an APLIC
17
controller or not. Do the same in virt.c with virt_use_emulated_aplic().
12
18
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
19
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-Id: <20221013062946.7530-2-zhiwei_liu@linux.alibaba.com>
21
Message-ID: <20241119191706.718860-6-dbarboza@ventanamicro.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
23
---
18
target/riscv/cpu.h | 2 +
24
include/hw/intc/riscv_aplic.h | 1 +
19
target/riscv/debug.h | 12 ++++
25
hw/intc/riscv_aplic.c | 24 +++++++++++++++++++++---
20
target/riscv/helper.h | 2 +
26
hw/riscv/virt.c | 14 ++++++++++++--
21
target/riscv/cpu_helper.c | 6 ++
27
3 files changed, 34 insertions(+), 5 deletions(-)
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
28
29
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
29
diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h
30
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.h
31
--- a/include/hw/intc/riscv_aplic.h
32
+++ b/target/riscv/cpu.h
32
+++ b/include/hw/intc/riscv_aplic.h
33
@@ -XXX,XX +XXX,XX @@ FIELD(TB_FLAGS, PM_MASK_ENABLED, 22, 1)
33
@@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState {
34
FIELD(TB_FLAGS, PM_BASE_ENABLED, 23, 1)
34
35
FIELD(TB_FLAGS, VTA, 24, 1)
35
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
36
FIELD(TB_FLAGS, VMA, 25, 1)
36
bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
37
+/* Native debug itrigger */
37
+bool riscv_use_emulated_aplic(bool msimode);
38
+FIELD(TB_FLAGS, ITRIGGER, 26, 1)
38
39
39
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
40
#ifdef TARGET_RISCV32
40
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
41
#define riscv_cpu_mxl(env) ((void)(env), MXL_RV32)
41
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
42
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
43
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
44
--- a/target/riscv/debug.h
43
--- a/hw/intc/riscv_aplic.c
45
+++ b/target/riscv/debug.h
44
+++ b/hw/intc/riscv_aplic.c
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 @@
45
@@ -XXX,XX +XXX,XX @@
88
#include "tcg/tcg-op.h"
46
#include "target/riscv/cpu.h"
89
#include "trace.h"
47
#include "sysemu/sysemu.h"
90
#include "semihosting/common-semi.h"
48
#include "sysemu/kvm.h"
91
+#include "sysemu/cpu-timers.h"
49
+#include "sysemu/tcg.h"
92
#include "cpu_bits.h"
50
#include "kvm/kvm_riscv.h"
93
+#include "debug.h"
51
#include "migration/vmstate.h"
94
52
95
int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
53
@@ -XXX,XX +XXX,XX @@ bool riscv_is_kvm_aia_aplic_imsic(bool msimode)
96
{
54
return kvm_irqchip_in_kernel() && msimode;
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
}
55
}
123
56
124
+/* icount trigger type */
57
+bool riscv_use_emulated_aplic(bool msimode)
125
+static inline int
126
+itrigger_get_count(CPURISCVState *env, int index)
127
+{
58
+{
128
+ return get_field(env->tdata1[index], ITRIGGER_COUNT);
59
+#ifdef CONFIG_KVM
129
+}
60
+ if (tcg_enabled()) {
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;
61
+ return true;
168
+ }
62
+ }
169
+
63
+
170
+ return false;
64
+ if (!riscv_is_kvm_aia_aplic_imsic(msimode)) {
65
+ return true;
66
+ }
67
+
68
+ return kvm_kernel_irqchip_split();
69
+#else
70
+ return true;
71
+#endif
171
+}
72
+}
172
+
73
+
173
+void helper_itrigger_match(CPURISCVState *env)
74
static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
75
uint32_t irq)
76
{
77
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
78
uint32_t i;
79
RISCVAPLICState *aplic = RISCV_APLIC(dev);
80
81
- if (!riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) {
82
+ if (riscv_use_emulated_aplic(aplic->msimode)) {
83
aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
84
aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
85
aplic->state = g_new0(uint32_t, aplic->num_irqs);
86
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
87
* have IRQ lines delegated by their parent APLIC.
88
*/
89
if (!aplic->parent) {
90
- if (kvm_enabled() && riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) {
91
+ if (kvm_enabled() && !riscv_use_emulated_aplic(aplic->msimode)) {
92
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
93
} else {
94
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
95
@@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
96
97
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
98
99
- if (!riscv_is_kvm_aia_aplic_imsic(msimode)) {
100
+ if (riscv_use_emulated_aplic(msimode)) {
101
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
102
}
103
104
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/riscv/virt.c
107
+++ b/hw/riscv/virt.c
108
@@ -XXX,XX +XXX,XX @@ static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type)
109
return riscv_is_kvm_aia_aplic_imsic(msimode);
110
}
111
112
+static bool virt_use_emulated_aplic(RISCVVirtAIAType aia_type)
174
+{
113
+{
175
+ int count;
114
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
176
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
115
+
177
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
116
+ return riscv_use_emulated_aplic(msimode);
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
+}
117
+}
193
+
118
+
194
target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index)
119
static bool virt_aclint_allowed(void)
195
{
120
{
196
switch (tdata_index) {
121
return tcg_enabled() || qtest_enabled();
197
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
122
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
198
index XXXXXXX..XXXXXXX 100644
123
*msi_pcie_phandle = msi_s_phandle;
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
}
124
}
250
}
125
251
126
- /* KVM AIA aplic-imsic only has one APLIC instance */
252
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
127
- if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) {
253
memset(ctx->ftemp, 0, sizeof(ctx->ftemp));
128
+ /*
254
ctx->pm_mask_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_MASK_ENABLED);
129
+ * With KVM AIA aplic-imsic, using an irqchip without split
255
ctx->pm_base_enabled = FIELD_EX32(tb_flags, TB_FLAGS, PM_BASE_ENABLED);
130
+ * mode, we'll use only one APLIC instance.
256
+ ctx->itrigger = FIELD_EX32(tb_flags, TB_FLAGS, ITRIGGER);
131
+ */
257
ctx->zero = tcg_constant_tl(0);
132
+ if (!virt_use_emulated_aplic(s->aia_type)) {
258
}
133
create_fdt_socket_aplic(s, memmap, 0,
259
134
msi_m_phandle, msi_s_phandle, phandle,
260
@@ -XXX,XX +XXX,XX @@ static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
135
&intc_phandles[0], xplic_phandles,
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
--
136
--
354
2.38.1
137
2.47.1
diff view generated by jsdifflib
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Accesses to henvcfg, henvcfgh and senvcfg are allowed only if the corresponding
3
The last step to enable KVM AIA aplic-imsic with irqchip in split mode
4
bit in mstateen0/hstateen0 is enabled. Otherwise an illegal instruction trap is
4
is to deal with how MSIs are going to be sent. In our current design we
5
generated.
5
don't allow an APLIC controller to send MSIs unless it's on m-mode. And
6
we also do not allow Supervisor MSI address configuration via the
7
'smsiaddrcfg' and 'smsiaddrcfgh' registers unless it's also a m-mode
8
APLIC controller.
6
9
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
10
Add a new RISCVACPLICState attribute called 'kvm_msicfgaddr'. This
8
Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn>
11
attribute represents the base configuration address for MSIs, in our
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
case the base addr of the IMSIC controller. This attribute is being set
10
Message-Id: <20221016124726.102129-3-mchitale@ventanamicro.com>
13
only when running irqchip_split() mode with aia=aplic-imsic.
14
15
During riscv_aplic_msi_send() we'll check if the attribute was set to
16
skip the check for a m-mode APLIC controller and to change the resulting
17
MSI addr by adding kvm_msicfgaddr right before address_space_stl_le().
18
19
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
20
Acked-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-ID: <20241119191706.718860-7-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
23
---
13
target/riscv/csr.c | 87 ++++++++++++++++++++++++++++++++++++++++++----
24
include/hw/intc/riscv_aplic.h | 6 +++++
14
1 file changed, 80 insertions(+), 7 deletions(-)
25
hw/intc/riscv_aplic.c | 42 +++++++++++++++++++++++++++--------
26
hw/riscv/virt.c | 6 ++++-
27
3 files changed, 44 insertions(+), 10 deletions(-)
15
28
16
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
29
diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h
17
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/csr.c
31
--- a/include/hw/intc/riscv_aplic.h
19
+++ b/target/riscv/csr.c
32
+++ b/include/hw/intc/riscv_aplic.h
20
@@ -XXX,XX +XXX,XX @@ void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
33
@@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState {
34
uint32_t num_irqs;
35
bool msimode;
36
bool mmode;
37
+
38
+ /* To support KVM aia=aplic-imsic with irqchip split mode */
39
+ bool kvm_splitmode;
40
+ uint32_t kvm_msicfgaddr;
41
+ uint32_t kvm_msicfgaddrH;
42
};
43
44
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
45
bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
46
bool riscv_use_emulated_aplic(bool msimode);
47
+void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr);
48
49
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
50
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
51
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
52
index XXXXXXX..XXXXXXX 100644
53
--- a/hw/intc/riscv_aplic.c
54
+++ b/hw/intc/riscv_aplic.c
55
@@ -XXX,XX +XXX,XX @@ bool riscv_use_emulated_aplic(bool msimode)
56
#endif
21
}
57
}
22
58
23
/* Predicates */
59
+void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr)
24
+#if !defined(CONFIG_USER_ONLY)
25
+static RISCVException smstateen_acc_ok(CPURISCVState *env, int index,
26
+ uint64_t bit)
27
+{
60
+{
28
+ bool virt = riscv_cpu_virt_enabled(env);
61
+#ifdef CONFIG_KVM
29
+ CPUState *cs = env_cpu(env);
62
+ if (riscv_use_emulated_aplic(aplic->msimode)) {
30
+ RISCVCPU *cpu = RISCV_CPU(cs);
63
+ aplic->kvm_msicfgaddr = extract64(addr, 0, 32);
64
+ aplic->kvm_msicfgaddrH = extract64(addr, 32, 32);
65
+ }
66
+#endif
67
+}
31
+
68
+
32
+ if (env->priv == PRV_M || !cpu->cfg.ext_smstateen) {
69
static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
33
+ return RISCV_EXCP_NONE;
70
uint32_t irq)
71
{
72
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic,
73
uint32_t lhxs, lhxw, hhxs, hhxw, group_idx, msicfgaddr, msicfgaddrH;
74
75
aplic_m = aplic;
76
- while (aplic_m && !aplic_m->mmode) {
77
- aplic_m = aplic_m->parent;
78
- }
79
- if (!aplic_m) {
80
- qemu_log_mask(LOG_GUEST_ERROR, "%s: m-level APLIC not found\n",
81
- __func__);
82
- return;
83
+
84
+ if (!aplic->kvm_splitmode) {
85
+ while (aplic_m && !aplic_m->mmode) {
86
+ aplic_m = aplic_m->parent;
87
+ }
88
+ if (!aplic_m) {
89
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: m-level APLIC not found\n",
90
+ __func__);
91
+ return;
92
+ }
93
}
94
95
if (aplic->mmode) {
96
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic,
97
addr |= (uint64_t)(guest_idx & APLIC_xMSICFGADDR_PPN_HART(lhxs));
98
addr <<= APLIC_xMSICFGADDR_PPN_SHIFT;
99
100
+ if (aplic->kvm_splitmode) {
101
+ addr |= aplic->kvm_msicfgaddr;
102
+ addr |= ((uint64_t)aplic->kvm_msicfgaddrH << 32);
34
+ }
103
+ }
35
+
104
+
36
+ if (!(env->mstateen[index] & bit)) {
105
address_space_stl_le(&address_space_memory, addr,
37
+ return RISCV_EXCP_ILLEGAL_INST;
106
eiid, MEMTXATTRS_UNSPECIFIED, &result);
107
if (result != MEMTX_OK) {
108
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
109
memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops,
110
aplic, TYPE_RISCV_APLIC, aplic->aperture_size);
111
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio);
112
+
113
+ if (kvm_enabled()) {
114
+ aplic->kvm_splitmode = true;
115
+ }
116
}
117
118
/*
119
@@ -XXX,XX +XXX,XX @@ static const Property riscv_aplic_properties[] = {
120
121
static const VMStateDescription vmstate_riscv_aplic = {
122
.name = "riscv_aplic",
123
- .version_id = 1,
124
- .minimum_version_id = 1,
125
+ .version_id = 2,
126
+ .minimum_version_id = 2,
127
.fields = (const VMStateField[]) {
128
VMSTATE_UINT32(domaincfg, RISCVAPLICState),
129
VMSTATE_UINT32(mmsicfgaddr, RISCVAPLICState),
130
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_riscv_aplic = {
131
VMSTATE_UINT32(smsicfgaddr, RISCVAPLICState),
132
VMSTATE_UINT32(smsicfgaddrH, RISCVAPLICState),
133
VMSTATE_UINT32(genmsi, RISCVAPLICState),
134
+ VMSTATE_UINT32(kvm_msicfgaddr, RISCVAPLICState),
135
+ VMSTATE_UINT32(kvm_msicfgaddrH, RISCVAPLICState),
136
VMSTATE_VARRAY_UINT32(sourcecfg, RISCVAPLICState,
137
num_irqs, 0,
138
vmstate_info_uint32, uint32_t),
139
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
140
index XXXXXXX..XXXXXXX 100644
141
--- a/hw/riscv/virt.c
142
+++ b/hw/riscv/virt.c
143
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
144
int base_hartid, int hart_count)
145
{
146
int i;
147
- hwaddr addr;
148
+ hwaddr addr = 0;
149
uint32_t guest_bits;
150
DeviceState *aplic_s = NULL;
151
DeviceState *aplic_m = NULL;
152
@@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests,
153
VIRT_IRQCHIP_NUM_PRIO_BITS,
154
msimode, false, aplic_m);
155
156
+ if (kvm_enabled() && msimode) {
157
+ riscv_aplic_set_kvm_msicfgaddr(RISCV_APLIC(aplic_s), addr);
38
+ }
158
+ }
39
+
159
+
40
+ if (virt) {
160
return kvm_enabled() ? aplic_s : aplic_m;
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
}
161
}
77
@@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
162
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
--
163
--
195
2.38.1
164
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
At present the SiFive PLIC model "priority-base" expects interrupt
3
Remove the 'irqchip_split()' restriction in kvm_arch_init() now that
4
priority register base starting from source 1 instead source 0,
4
we have support for "-accel kvm,kernel-irqchip=split".
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
5
9
Note the irq number calculation in sifive_plic_{read,write} is
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
17
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
8
Message-ID: <20241119191706.718860-8-dbarboza@ventanamicro.com>
18
Message-Id: <20221211030829.802437-14-bmeng@tinylab.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
10
---
21
include/hw/riscv/microchip_pfsoc.h | 2 +-
11
target/riscv/kvm/kvm-cpu.c | 5 -----
22
include/hw/riscv/shakti_c.h | 2 +-
12
1 file changed, 5 deletions(-)
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
13
29
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
14
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
30
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/riscv/microchip_pfsoc.h
16
--- a/target/riscv/kvm/kvm-cpu.c
32
+++ b/include/hw/riscv/microchip_pfsoc.h
17
+++ b/target/riscv/kvm/kvm-cpu.c
33
@@ -XXX,XX +XXX,XX @@ enum {
18
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
34
19
35
#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
20
int kvm_arch_irqchip_create(KVMState *s)
36
#define MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES 7
21
{
37
-#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x04
22
- if (kvm_kernel_irqchip_split()) {
38
+#define MICROCHIP_PFSOC_PLIC_PRIORITY_BASE 0x00
23
- error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
39
#define MICROCHIP_PFSOC_PLIC_PENDING_BASE 0x1000
24
- exit(1);
40
#define MICROCHIP_PFSOC_PLIC_ENABLE_BASE 0x2000
25
- }
41
#define MICROCHIP_PFSOC_PLIC_ENABLE_STRIDE 0x80
26
-
42
diff --git a/include/hw/riscv/shakti_c.h b/include/hw/riscv/shakti_c.h
27
/*
43
index XXXXXXX..XXXXXXX 100644
28
* We can create the VAIA using the newer device control API.
44
--- a/include/hw/riscv/shakti_c.h
29
*/
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
--
30
--
125
2.38.1
31
2.47.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Failure to set pc_succ_insn may result in a TB covering zero bytes,
3
Also add a new page, docs/specs/riscv-aia.rst, where we're documenting
4
which triggers an assert within the code generator.
4
the state of AIA support in QEMU w.r.t the controllers being emulated or
5
not depending on the AIA and accelerator settings.
5
6
6
Cc: qemu-stable@nongnu.org
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-ID: <20241119191706.718860-9-dbarboza@ventanamicro.com>
11
Message-Id: <20221203175744.151365-1-richard.henderson@linaro.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
target/riscv/translate.c | 12 ++++--------
12
docs/specs/index.rst | 1 +
15
tests/tcg/Makefile.target | 2 ++
13
docs/specs/riscv-aia.rst | 83 ++++++++++++++++++++++++++++++++++++++
16
tests/tcg/riscv64/Makefile.target | 5 +++++
14
docs/system/riscv/virt.rst | 7 ++++
17
tests/tcg/riscv64/test-noc.S | 32 +++++++++++++++++++++++++++++++
15
3 files changed, 91 insertions(+)
18
4 files changed, 43 insertions(+), 8 deletions(-)
16
create mode 100644 docs/specs/riscv-aia.rst
19
create mode 100644 tests/tcg/riscv64/test-noc.S
20
17
21
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
18
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
22
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/translate.c
20
--- a/docs/specs/index.rst
24
+++ b/target/riscv/translate.c
21
+++ b/docs/specs/index.rst
25
@@ -XXX,XX +XXX,XX @@ static void decode_opc(CPURISCVState *env, DisasContext *ctx, uint16_t opcode)
22
@@ -XXX,XX +XXX,XX @@ guest hardware that is specific to QEMU.
26
ctx->virt_inst_excp = false;
23
rapl-msr
27
/* Check for compressed insn */
24
rocker
28
if (insn_len(opcode) == 2) {
25
riscv-iommu
29
- if (!has_ext(ctx, RVC)) {
26
+ riscv-aia
30
- gen_exception_illegal(ctx);
27
diff --git a/docs/specs/riscv-aia.rst b/docs/specs/riscv-aia.rst
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
28
new file mode 100644
72
index XXXXXXX..XXXXXXX
29
index XXXXXXX..XXXXXXX
73
--- /dev/null
30
--- /dev/null
74
+++ b/tests/tcg/riscv64/test-noc.S
31
+++ b/docs/specs/riscv-aia.rst
75
@@ -XXX,XX +XXX,XX @@
32
@@ -XXX,XX +XXX,XX @@
76
+#include <asm/unistd.h>
33
+.. _riscv-aia:
77
+
34
+
78
+    .text
35
+RISC-V AIA support for RISC-V machines
79
+    .globl _start
36
+======================================
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
+
37
+
89
+    .option    rvc
38
+AIA (Advanced Interrupt Architecture) support is implemented in the ``virt``
90
+    li    a0, 1
39
+RISC-V machine for TCG and KVM accelerators.
91
+    j    exit
92
+    .option    norvc
93
+
40
+
94
+pass:
41
+The support consists of two main modes:
95
+    li    a0, 0
96
+exit:
97
+    li    a7, __NR_exit
98
+    scall
99
+
42
+
100
+    .data
43
+- "aia=aplic": adds one or more APLIC (Advanced Platform Level Interrupt Controller)
101
+    /* struct kernel_sigaction sa = { .sa_handler = pass }; */
44
+ devices
102
+    .type    sa, @object
45
+- "aia=aplic-imsic": adds one or more APLIC device and an IMSIC (Incoming MSI
103
+    .size    sa, 32
46
+ Controller) device for each CPU
104
+sa:
105
+    .dword    pass
106
+    .zero    24
107
+
47
+
48
+From an user standpoint, these modes will behave the same regardless of the accelerator
49
+used. From a developer standpoint the accelerator settings will change what it being
50
+emulated in userspace versus what is being emulated by an in-kernel irqchip.
51
+
52
+When running TCG, all controllers are emulated in userspace, including machine mode
53
+(m-mode) APLIC and IMSIC (when applicable).
54
+
55
+When running KVM:
56
+
57
+- no m-mode is provided, so there is no m-mode APLIC or IMSIC emulation regardless of
58
+ the AIA mode chosen
59
+- with "aia=aplic", s-mode APLIC will be emulated by userspace
60
+- with "aia=aplic-imsic" there are two possibilities. If no additional KVM option
61
+ is provided there will be no APLIC or IMSIC emulation in userspace, and the virtual
62
+ machine will use the provided in-kernel APLIC and IMSIC controllers. If the user
63
+ chooses to use the irqchip in split mode via "-accel kvm,kernel-irqchip=split",
64
+ s-mode APLIC will be emulated while using the s-mode IMSIC from the irqchip
65
+
66
+The following table summarizes how the AIA and accelerator options defines what
67
+we will emulate in userspace:
68
+
69
+
70
+.. list-table:: How AIA and accel options changes controller emulation
71
+ :widths: 25 25 25 25 25 25 25
72
+ :header-rows: 1
73
+
74
+ * - Accel
75
+ - Accel props
76
+ - AIA type
77
+ - APLIC m-mode
78
+ - IMSIC m-mode
79
+ - APLIC s-mode
80
+ - IMSIC s-mode
81
+ * - tcg
82
+ - ---
83
+ - aplic
84
+ - emul
85
+ - n/a
86
+ - emul
87
+ - n/a
88
+ * - tcg
89
+ - ---
90
+ - aplic-imsic
91
+ - emul
92
+ - emul
93
+ - emul
94
+ - emul
95
+ * - kvm
96
+ - ---
97
+ - aplic
98
+ - n/a
99
+ - n/a
100
+ - emul
101
+ - n/a
102
+ * - kvm
103
+ - none
104
+ - aplic-imsic
105
+ - n/a
106
+ - n/a
107
+ - in-kernel
108
+ - in-kernel
109
+ * - kvm
110
+ - irqchip=split
111
+ - aplic-imsic
112
+ - n/a
113
+ - n/a
114
+ - emul
115
+ - in-kernel
116
diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst
117
index XXXXXXX..XXXXXXX 100644
118
--- a/docs/system/riscv/virt.rst
119
+++ b/docs/system/riscv/virt.rst
120
@@ -XXX,XX +XXX,XX @@ The following machine-specific options are supported:
121
MSIs. When not specified, this option is assumed to be "none" which selects
122
SiFive PLIC to handle wired interrupts.
123
124
+ This option also interacts with '-accel kvm'. When using "aia=aplic-imsic"
125
+ with KVM, it is possible to set the use of the kernel irqchip in split mode
126
+ by using "-accel kvm,kernel-irqchip=split". In this case the ``virt`` machine
127
+ will emulate the APLIC controller instead of using the APLIC controller from
128
+ the irqchip. See :ref:`riscv-aia` for more details on all available AIA
129
+ modes.
130
+
131
- aia-guests=nnn
132
133
The number of per-HART VS-level AIA IMSIC pages to be emulated for a guest
108
--
134
--
109
2.38.1
135
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
2
2
3
SHAKTI_C machine Kconfig option was inserted in disorder. Fix it.
3
Add a basic board with interrupt controller (intc), timer, serial
4
4
(uartlite), small memory called LMB@0 (128kB) and DDR@0x80000000
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
5
(configured via command line eg. -m 2g).
6
This is basic configuration which matches HW generated out of AMD Vivado
7
(design tools). But initial configuration is going beyond what it is
8
configured by default because validation should be done on other
9
configurations too. That's why wire also additional uart16500, axi
10
ethernet(with axi dma).
11
GPIOs, i2c and qspi is also listed for completeness.
12
13
IRQ map is: (addr)
14
0 - timer (0x41c00000)
15
1 - uartlite (0x40600000)
16
2 - i2c (0x40800000)
17
3 - qspi (0x44a00000)
18
4 - uart16550 (0x44a10000)
19
5 - emaclite (0x40e00000)
20
6 - timer2 (0x41c10000)
21
7 - axi emac (0x40c00000)
22
8 - axi dma (0x41e00000)
23
9 - axi dma
24
10 - gpio (0x40000000)
25
11 - gpio2 (0x40010000)
26
12 - gpio3 (0x40020000)
27
28
Signed-off-by: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
29
Signed-off-by: Michal Simek <michal.simek@amd.com>
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
31
Message-ID: <20241125134739.18189-1-sai.pavan.boddu@amd.com>
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>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
33
---
12
hw/riscv/Kconfig | 16 +++++++++-------
34
MAINTAINERS | 6 +
13
1 file changed, 9 insertions(+), 7 deletions(-)
35
docs/system/riscv/microblaze-v-generic.rst | 42 +++++
14
36
docs/system/target-riscv.rst | 1 +
37
hw/riscv/microblaze-v-generic.c | 184 +++++++++++++++++++++
38
hw/riscv/Kconfig | 8 +
39
hw/riscv/meson.build | 1 +
40
6 files changed, 242 insertions(+)
41
create mode 100644 docs/system/riscv/microblaze-v-generic.rst
42
create mode 100644 hw/riscv/microblaze-v-generic.c
43
44
diff --git a/MAINTAINERS b/MAINTAINERS
45
index XXXXXXX..XXXXXXX 100644
46
--- a/MAINTAINERS
47
+++ b/MAINTAINERS
48
@@ -XXX,XX +XXX,XX @@ F: docs/system/riscv/sifive_u.rst
49
F: hw/*/*sifive*.c
50
F: include/hw/*/*sifive*.h
51
52
+AMD Microblaze-V Generic Board
53
+M: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
54
+S: Maintained
55
+F: hw/riscv/microblaze-v-generic.c
56
+F: docs/system/riscv/microblaze-v-generic.rst
57
+
58
RX Machines
59
-----------
60
rx-gdbsim
61
diff --git a/docs/system/riscv/microblaze-v-generic.rst b/docs/system/riscv/microblaze-v-generic.rst
62
new file mode 100644
63
index XXXXXXX..XXXXXXX
64
--- /dev/null
65
+++ b/docs/system/riscv/microblaze-v-generic.rst
66
@@ -XXX,XX +XXX,XX @@
67
+Microblaze-V generic board (``amd-microblaze-v-generic``)
68
+=========================================================
69
+The AMD MicroBlaze™ V processor is a soft-core RISC-V processor IP for AMD
70
+adaptive SoCs and FPGAs. The MicroBlaze™ V processor is based on the 32-bit (or
71
+64-bit) RISC-V instruction set architecture (ISA) and contains interfaces
72
+compatible with the classic MicroBlaze™ V processor (i.e it is a drop in
73
+replacement for the classic MicroBlaze™ processor in existing RTL designs).
74
+More information can be found in below document.
75
+
76
+https://docs.amd.com/r/en-US/ug1629-microblaze-v-user-guide/MicroBlaze-V-Architecture
77
+
78
+The MicroBlaze™ V generic board in QEMU has following supported devices:
79
+
80
+ - timer
81
+ - uartlite
82
+ - uart16550
83
+ - emaclite
84
+ - timer2
85
+ - axi emac
86
+ - axi dma
87
+
88
+The MicroBlaze™ V core in QEMU has the following configuration:
89
+
90
+ - RV32I base integer instruction set
91
+ - "Zicsr" Control and Status register instructions
92
+ - "Zifencei" instruction-fetch
93
+ - Extensions: m, a, f, c
94
+
95
+Running
96
+"""""""
97
+Below is an example command line for launching mainline U-boot
98
+(xilinx_mbv32_defconfig) on the Microblaze-V generic board.
99
+
100
+.. code-block:: bash
101
+
102
+ $ qemu-system-riscv32 -M amd-microblaze-v-generic \
103
+ -display none \
104
+ -device loader,addr=0x80000000,file=u-boot-spl.bin,cpu-num=0 \
105
+ -device loader,addr=0x80200000,file=u-boot.img \
106
+ -serial mon:stdio \
107
+ -device loader,addr=0x83000000,file=system.dtb \
108
+ -m 2g
109
diff --git a/docs/system/target-riscv.rst b/docs/system/target-riscv.rst
110
index XXXXXXX..XXXXXXX 100644
111
--- a/docs/system/target-riscv.rst
112
+++ b/docs/system/target-riscv.rst
113
@@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running
114
.. toctree::
115
:maxdepth: 1
116
117
+ riscv/microblaze-v-generic
118
riscv/microchip-icicle-kit
119
riscv/shakti-c
120
riscv/sifive_u
121
diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c
122
new file mode 100644
123
index XXXXXXX..XXXXXXX
124
--- /dev/null
125
+++ b/hw/riscv/microblaze-v-generic.c
126
@@ -XXX,XX +XXX,XX @@
127
+/*
128
+ * QEMU model of Microblaze V generic board.
129
+ *
130
+ * based on hw/microblaze/petalogix_ml605_mmu.c
131
+ *
132
+ * Copyright (c) 2011 Michal Simek <monstr@monstr.eu>
133
+ * Copyright (c) 2011 PetaLogix
134
+ * Copyright (c) 2009 Edgar E. Iglesias.
135
+ * Copyright (C) 2024, Advanced Micro Devices, Inc.
136
+ * SPDX-License-Identifier: GPL-2.0-or-later
137
+ *
138
+ * Written by Sai Pavan Boddu <sai.pavan.boddu@amd.com
139
+ * and by Michal Simek <michal.simek@amd.com>.
140
+ */
141
+
142
+#include "qemu/osdep.h"
143
+#include "qemu/units.h"
144
+#include "qapi/error.h"
145
+#include "cpu.h"
146
+#include "hw/sysbus.h"
147
+#include "sysemu/sysemu.h"
148
+#include "net/net.h"
149
+#include "hw/boards.h"
150
+#include "hw/char/serial-mm.h"
151
+#include "exec/address-spaces.h"
152
+#include "hw/char/xilinx_uartlite.h"
153
+#include "hw/misc/unimp.h"
154
+
155
+#define LMB_BRAM_SIZE (128 * KiB)
156
+#define MEMORY_BASEADDR 0x80000000
157
+#define INTC_BASEADDR 0x41200000
158
+#define TIMER_BASEADDR 0x41c00000
159
+#define TIMER_BASEADDR2 0x41c10000
160
+#define UARTLITE_BASEADDR 0x40600000
161
+#define ETHLITE_BASEADDR 0x40e00000
162
+#define UART16550_BASEADDR 0x44a10000
163
+#define AXIENET_BASEADDR 0x40c00000
164
+#define AXIDMA_BASEADDR 0x41e00000
165
+#define GPIO_BASEADDR 0x40000000
166
+#define GPIO_BASEADDR2 0x40010000
167
+#define GPIO_BASEADDR3 0x40020000
168
+#define I2C_BASEADDR 0x40800000
169
+#define QSPI_BASEADDR 0x44a00000
170
+
171
+#define TIMER_IRQ 0
172
+#define UARTLITE_IRQ 1
173
+#define UART16550_IRQ 4
174
+#define ETHLITE_IRQ 5
175
+#define TIMER_IRQ2 6
176
+#define AXIENET_IRQ 7
177
+#define AXIDMA_IRQ1 8
178
+#define AXIDMA_IRQ0 9
179
+
180
+static void mb_v_generic_init(MachineState *machine)
181
+{
182
+ ram_addr_t ram_size = machine->ram_size;
183
+ DeviceState *dev, *dma, *eth0;
184
+ Object *ds, *cs;
185
+ int i;
186
+ RISCVCPU *cpu;
187
+ hwaddr ddr_base = MEMORY_BASEADDR;
188
+ MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1);
189
+ MemoryRegion *phys_ram = g_new(MemoryRegion, 1);
190
+ qemu_irq irq[32];
191
+ MemoryRegion *sysmem = get_system_memory();
192
+
193
+ cpu = RISCV_CPU(object_new(machine->cpu_type));
194
+ object_property_set_bool(OBJECT(cpu), "h", false, NULL);
195
+ object_property_set_bool(OBJECT(cpu), "d", false, NULL);
196
+ qdev_realize(DEVICE(cpu), NULL, &error_abort);
197
+ /* Attach emulated BRAM through the LMB. */
198
+ memory_region_init_ram(phys_lmb_bram, NULL,
199
+ "mb_v.lmb_bram", LMB_BRAM_SIZE,
200
+ &error_fatal);
201
+ memory_region_add_subregion(sysmem, 0x00000000, phys_lmb_bram);
202
+
203
+ memory_region_init_ram(phys_ram, NULL, "mb_v.ram",
204
+ ram_size, &error_fatal);
205
+ memory_region_add_subregion(sysmem, ddr_base, phys_ram);
206
+
207
+ dev = qdev_new("xlnx.xps-intc");
208
+ qdev_prop_set_uint32(dev, "kind-of-intr",
209
+ 1 << UARTLITE_IRQ);
210
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
211
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR);
212
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
213
+ qdev_get_gpio_in(DEVICE(cpu), 11));
214
+ for (i = 0; i < 32; i++) {
215
+ irq[i] = qdev_get_gpio_in(dev, i);
216
+ }
217
+
218
+ /* Uartlite */
219
+ dev = qdev_new(TYPE_XILINX_UARTLITE);
220
+ qdev_prop_set_chr(dev, "chardev", serial_hd(0));
221
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
222
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, UARTLITE_BASEADDR);
223
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[UARTLITE_IRQ]);
224
+
225
+ /* Full uart */
226
+ serial_mm_init(sysmem, UART16550_BASEADDR + 0x1000, 2,
227
+ irq[UART16550_IRQ], 115200, serial_hd(1),
228
+ DEVICE_LITTLE_ENDIAN);
229
+
230
+ /* 2 timers at irq 0 @ 100 Mhz. */
231
+ dev = qdev_new("xlnx.xps-timer");
232
+ qdev_prop_set_uint32(dev, "one-timer-only", 0);
233
+ qdev_prop_set_uint32(dev, "clock-frequency", 100000000);
234
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
235
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR);
236
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ]);
237
+
238
+ /* 2 timers at irq 3 @ 100 Mhz. */
239
+ dev = qdev_new("xlnx.xps-timer");
240
+ qdev_prop_set_uint32(dev, "one-timer-only", 0);
241
+ qdev_prop_set_uint32(dev, "clock-frequency", 100000000);
242
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
243
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, TIMER_BASEADDR2);
244
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[TIMER_IRQ2]);
245
+
246
+ /* Emaclite */
247
+ dev = qdev_new("xlnx.xps-ethernetlite");
248
+ qemu_configure_nic_device(dev, true, NULL);
249
+ qdev_prop_set_uint32(dev, "tx-ping-pong", 0);
250
+ qdev_prop_set_uint32(dev, "rx-ping-pong", 0);
251
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
252
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, ETHLITE_BASEADDR);
253
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq[ETHLITE_IRQ]);
254
+
255
+ /* axi ethernet and dma initialization. */
256
+ eth0 = qdev_new("xlnx.axi-ethernet");
257
+ dma = qdev_new("xlnx.axi-dma");
258
+
259
+ /* FIXME: attach to the sysbus instead */
260
+ object_property_add_child(qdev_get_machine(), "xilinx-eth", OBJECT(eth0));
261
+ object_property_add_child(qdev_get_machine(), "xilinx-dma", OBJECT(dma));
262
+
263
+ ds = object_property_get_link(OBJECT(dma),
264
+ "axistream-connected-target", NULL);
265
+ cs = object_property_get_link(OBJECT(dma),
266
+ "axistream-control-connected-target", NULL);
267
+ qemu_configure_nic_device(eth0, true, NULL);
268
+ qdev_prop_set_uint32(eth0, "rxmem", 0x1000);
269
+ qdev_prop_set_uint32(eth0, "txmem", 0x1000);
270
+ object_property_set_link(OBJECT(eth0), "axistream-connected", ds,
271
+ &error_abort);
272
+ object_property_set_link(OBJECT(eth0), "axistream-control-connected", cs,
273
+ &error_abort);
274
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(eth0), &error_fatal);
275
+ sysbus_mmio_map(SYS_BUS_DEVICE(eth0), 0, AXIENET_BASEADDR);
276
+ sysbus_connect_irq(SYS_BUS_DEVICE(eth0), 0, irq[AXIENET_IRQ]);
277
+
278
+ ds = object_property_get_link(OBJECT(eth0),
279
+ "axistream-connected-target", NULL);
280
+ cs = object_property_get_link(OBJECT(eth0),
281
+ "axistream-control-connected-target", NULL);
282
+ qdev_prop_set_uint32(dma, "freqhz", 100000000);
283
+ object_property_set_link(OBJECT(dma), "axistream-connected", ds,
284
+ &error_abort);
285
+ object_property_set_link(OBJECT(dma), "axistream-control-connected", cs,
286
+ &error_abort);
287
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dma), &error_fatal);
288
+ sysbus_mmio_map(SYS_BUS_DEVICE(dma), 0, AXIDMA_BASEADDR);
289
+ sysbus_connect_irq(SYS_BUS_DEVICE(dma), 0, irq[AXIDMA_IRQ0]);
290
+ sysbus_connect_irq(SYS_BUS_DEVICE(dma), 1, irq[AXIDMA_IRQ1]);
291
+
292
+ /* unimplemented devices */
293
+ create_unimplemented_device("gpio", GPIO_BASEADDR, 0x10000);
294
+ create_unimplemented_device("gpio2", GPIO_BASEADDR2, 0x10000);
295
+ create_unimplemented_device("gpio3", GPIO_BASEADDR3, 0x10000);
296
+ create_unimplemented_device("i2c", I2C_BASEADDR, 0x10000);
297
+ create_unimplemented_device("qspi", QSPI_BASEADDR, 0x10000);
298
+}
299
+
300
+static void mb_v_generic_machine_init(MachineClass *mc)
301
+{
302
+ mc->desc = "AMD Microblaze-V generic platform";
303
+ mc->init = mb_v_generic_init;
304
+ mc->min_cpus = 1;
305
+ mc->max_cpus = 1;
306
+ mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
307
+ mc->default_cpus = 1;
308
+}
309
+
310
+DEFINE_MACHINE("amd-microblaze-v-generic", mb_v_generic_machine_init)
15
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
311
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
16
index XXXXXXX..XXXXXXX 100644
312
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/riscv/Kconfig
313
--- a/hw/riscv/Kconfig
18
+++ b/hw/riscv/Kconfig
314
+++ b/hw/riscv/Kconfig
19
@@ -XXX,XX +XXX,XX @@ config RISCV_NUMA
315
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
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
316
select SIFIVE_PLIC
30
select UNIMP
317
select UNIMP
31
318
32
-config SHAKTI_C
319
+config MICROBLAZE_V
33
- bool
320
+ bool
34
- select UNIMP
321
+ default y
35
- select SHAKTI_UART
322
+ depends on RISCV32 || RISCV64
36
- select RISCV_ACLINT
323
+ select XILINX
37
- select SIFIVE_PLIC
324
+ select XILINX_AXI
38
-
325
+ select XILINX_ETHLITE
39
config RISCV_VIRT
326
+
327
config OPENTITAN
40
bool
328
bool
41
imply PCI_DEVICES
329
default y
42
@@ -XXX,XX +XXX,XX @@ config RISCV_VIRT
330
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
43
select FW_CFG_DMA
331
index XXXXXXX..XXXXXXX 100644
44
select PLATFORM_BUS
332
--- a/hw/riscv/meson.build
45
333
+++ b/hw/riscv/meson.build
46
+config SHAKTI_C
334
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))
47
+ bool
335
riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfsoc.c'))
48
+ select RISCV_ACLINT
336
riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
49
+ select SHAKTI_UART
337
riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c'))
50
+ select SIFIVE_PLIC
338
+riscv_ss.add(when: 'CONFIG_MICROBLAZE_V', if_true: files('microblaze-v-generic.c'))
51
+ select UNIMP
339
52
+
340
hw_arch += {'riscv': riscv_ss}
53
config SIFIVE_E
54
bool
55
select RISCV_ACLINT
56
--
341
--
57
2.38.1
342
2.47.1
343
344
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
2
2
3
At present magic number is used to create "riscv,ndev" property
3
Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
4
in the dtb. Let's use the macro SIFIVE_U_PLIC_NUM_SOURCES that
4
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
5
is used to instantiate the PLIC model instead.
5
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
6
Message-ID: <20241028015744.624943-2-jeeheng.sia@starfivetech.com>
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>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
8
---
13
hw/riscv/sifive_u.c | 3 ++-
9
tests/qtest/bios-tables-test-allowed-diff.h | 1 +
14
1 file changed, 2 insertions(+), 1 deletion(-)
10
1 file changed, 1 insertion(+)
15
11
16
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
12
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
17
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/sifive_u.c
14
--- a/tests/qtest/bios-tables-test-allowed-diff.h
19
+++ b/hw/riscv/sifive_u.c
15
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
20
@@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap,
16
@@ -1 +1,2 @@
21
qemu_fdt_setprop_cells(fdt, nodename, "reg",
17
/* List of comma-separated changed AML files to ignore */
22
0x0, memmap[SIFIVE_U_DEV_PLIC].base,
18
+"tests/data/acpi/riscv64/virt/SPCR",
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
--
19
--
31
2.38.1
20
2.47.1
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
2
2
3
The max count in itrigger can be 0x3FFF, which will cause a no trivial
3
Update the SPCR table to accommodate the SPCR Table revision 4 [1].
4
translation and execution overload.
4
The SPCR table has been modified to adhere to the revision 4 format [2].
5
5
6
When icount is enabled, QEMU provides API that can fetch guest
6
[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
7
instruction number. Thus, we can set an timer for itrigger with
7
[2]: https://github.com/acpica/acpica/pull/931
8
the count as deadline.
9
8
10
Only when timer expires or priviledge mode changes, do lazy update
9
Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
11
to count.
10
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
12
11
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
13
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
15
Message-Id: <20221013062946.7530-3-zhiwei_liu@linux.alibaba.com>
14
Message-ID: <20241028015744.624943-3-jeeheng.sia@starfivetech.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
16
---
18
target/riscv/cpu.h | 2 ++
17
include/hw/acpi/acpi-defs.h | 7 +++++--
19
target/riscv/debug.h | 1 +
18
include/hw/acpi/aml-build.h | 2 +-
20
target/riscv/cpu_helper.c | 3 ++
19
hw/acpi/aml-build.c | 20 ++++++++++++++++----
21
target/riscv/debug.c | 59 +++++++++++++++++++++++++++++++++++++++
20
hw/arm/virt-acpi-build.c | 8 ++++++--
22
4 files changed, 65 insertions(+)
21
hw/loongarch/acpi-build.c | 6 +++++-
22
hw/riscv/virt-acpi-build.c | 12 +++++++++---
23
6 files changed, 42 insertions(+), 13 deletions(-)
23
24
24
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
25
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
25
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
26
--- a/target/riscv/cpu.h
27
--- a/include/hw/acpi/acpi-defs.h
27
+++ b/target/riscv/cpu.h
28
+++ b/include/hw/acpi/acpi-defs.h
28
@@ -XXX,XX +XXX,XX @@ struct CPUArchState {
29
@@ -XXX,XX +XXX,XX @@ typedef struct AcpiSpcrData {
29
target_ulong tdata3[RV_MAX_TRIGGERS];
30
uint8_t flow_control;
30
struct CPUBreakpoint *cpu_breakpoint[RV_MAX_TRIGGERS];
31
uint8_t terminal_type;
31
struct CPUWatchpoint *cpu_watchpoint[RV_MAX_TRIGGERS];
32
uint8_t language;
32
+ QEMUTimer *itrigger_timer[RV_MAX_TRIGGERS];
33
- uint8_t reserved1;
33
+ int64_t last_icount;
34
uint16_t pci_device_id; /* Must be 0xffff if not PCI device */
34
35
uint16_t pci_vendor_id; /* Must be 0xffff if not PCI device */
35
/* machine specific rdtime callback */
36
uint8_t pci_bus;
36
uint64_t (*rdtime_fn)(void *);
37
@@ -XXX,XX +XXX,XX @@ typedef struct AcpiSpcrData {
37
diff --git a/target/riscv/debug.h b/target/riscv/debug.h
38
uint8_t pci_function;
39
uint32_t pci_flags;
40
uint8_t pci_segment;
41
- uint32_t reserved2;
42
+ uint32_t uart_clk_freq;
43
+ uint32_t precise_baudrate;
44
+ uint32_t namespace_string_length;
45
+ uint32_t namespace_string_offset;
46
+ char namespace_string[];
47
} AcpiSpcrData;
48
49
#define ACPI_FADT_ARM_PSCI_COMPLIANT (1 << 0)
50
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
38
index XXXXXXX..XXXXXXX 100644
51
index XXXXXXX..XXXXXXX 100644
39
--- a/target/riscv/debug.h
52
--- a/include/hw/acpi/aml-build.h
40
+++ b/target/riscv/debug.h
53
+++ b/include/hw/acpi/aml-build.h
41
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp);
54
@@ -XXX,XX +XXX,XX @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
42
void riscv_trigger_init(CPURISCVState *env);
55
43
56
void build_spcr(GArray *table_data, BIOSLinker *linker,
44
bool riscv_itrigger_enabled(CPURISCVState *env);
57
const AcpiSpcrData *f, const uint8_t rev,
45
+void riscv_itrigger_update_priv(CPURISCVState *env);
58
- const char *oem_id, const char *oem_table_id);
46
#endif /* RISCV_DEBUG_H */
59
+ const char *oem_id, const char *oem_table_id, const char *name);
47
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
60
#endif
61
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
48
index XXXXXXX..XXXXXXX 100644
62
index XXXXXXX..XXXXXXX 100644
49
--- a/target/riscv/cpu_helper.c
63
--- a/hw/acpi/aml-build.c
50
+++ b/target/riscv/cpu_helper.c
64
+++ b/hw/acpi/aml-build.c
51
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
65
@@ -XXX,XX +XXX,XX @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
52
if (newpriv == PRV_H) {
66
53
newpriv = PRV_U;
67
void build_spcr(GArray *table_data, BIOSLinker *linker,
54
}
68
const AcpiSpcrData *f, const uint8_t rev,
55
+ if (icount_enabled() && newpriv != env->priv) {
69
- const char *oem_id, const char *oem_table_id)
56
+ riscv_itrigger_update_priv(env);
70
+ const char *oem_id, const char *oem_table_id, const char *name)
71
{
72
AcpiTable table = { .sig = "SPCR", .rev = rev, .oem_id = oem_id,
73
.oem_table_id = oem_table_id };
74
@@ -XXX,XX +XXX,XX @@ void build_spcr(GArray *table_data, BIOSLinker *linker,
75
build_append_int_noprefix(table_data, f->pci_flags, 4);
76
/* PCI Segment */
77
build_append_int_noprefix(table_data, f->pci_segment, 1);
78
- /* Reserved */
79
- build_append_int_noprefix(table_data, 0, 4);
80
-
81
+ if (rev < 4) {
82
+ /* Reserved */
83
+ build_append_int_noprefix(table_data, 0, 4);
84
+ } else {
85
+ /* UartClkFreq */
86
+ build_append_int_noprefix(table_data, f->uart_clk_freq, 4);
87
+ /* PreciseBaudrate */
88
+ build_append_int_noprefix(table_data, f->precise_baudrate, 4);
89
+ /* NameSpaceStringLength */
90
+ build_append_int_noprefix(table_data, f->namespace_string_length, 2);
91
+ /* NameSpaceStringOffset */
92
+ build_append_int_noprefix(table_data, f->namespace_string_offset, 2);
93
+ /* NamespaceString[] */
94
+ g_array_append_vals(table_data, name, f->namespace_string_length);
57
+ }
95
+ }
58
/* tlb_flush is unnecessary as mode is contained in mmu_idx */
96
acpi_table_end(linker, &table);
59
env->priv = newpriv;
97
}
60
env->xl = cpu_recompute_xl(env);
98
/*
61
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
99
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
100
index XXXXXXX..XXXXXXX 100644
63
--- a/target/riscv/debug.c
101
--- a/hw/arm/virt-acpi-build.c
64
+++ b/target/riscv/debug.c
102
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@
103
@@ -XXX,XX +XXX,XX @@ spcr_setup(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
#include "trace.h"
104
.pci_flags = 0,
67
#include "exec/exec-all.h"
105
.pci_segment = 0,
68
#include "exec/helper-proto.h"
106
};
69
+#include "sysemu/cpu-timers.h"
107
-
108
- build_spcr(table_data, linker, &serial, 2, vms->oem_id, vms->oem_table_id);
109
+ /*
110
+ * Passing NULL as the SPCR Table for Revision 2 doesn't support
111
+ * NameSpaceString.
112
+ */
113
+ build_spcr(table_data, linker, &serial, 2, vms->oem_id, vms->oem_table_id,
114
+ NULL);
115
}
70
116
71
/*
117
/*
72
* The following M-mode trigger CSRs are implemented:
118
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
73
@@ -XXX,XX +XXX,XX @@ void helper_itrigger_match(CPURISCVState *env)
119
index XXXXXXX..XXXXXXX 100644
74
}
120
--- a/hw/loongarch/acpi-build.c
121
+++ b/hw/loongarch/acpi-build.c
122
@@ -XXX,XX +XXX,XX @@ spcr_setup(GArray *table_data, BIOSLinker *linker, MachineState *machine)
123
};
124
125
lvms = LOONGARCH_VIRT_MACHINE(machine);
126
+ /*
127
+ * Passing NULL as the SPCR Table for Revision 2 doesn't support
128
+ * NameSpaceString.
129
+ */
130
build_spcr(table_data, linker, &serial, 2, lvms->oem_id,
131
- lvms->oem_table_id);
132
+ lvms->oem_table_id, NULL);
75
}
133
}
76
134
77
+static void riscv_itrigger_update_count(CPURISCVState *env)
135
typedef
78
+{
136
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
79
+ int count, executed;
137
index XXXXXXX..XXXXXXX 100644
80
+ /*
138
--- a/hw/riscv/virt-acpi-build.c
81
+ * Record last icount, so that we can evaluate the executed instructions
139
+++ b/hw/riscv/virt-acpi-build.c
82
+ * since last priviledge mode change or timer expire.
140
@@ -XXX,XX +XXX,XX @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
83
+ */
141
84
+ int64_t last_icount = env->last_icount, current_icount;
142
/*
85
+ current_icount = env->last_icount = icount_get_raw();
143
* Serial Port Console Redirection Table (SPCR)
86
+
144
- * Rev: 1.07
87
+ for (int i = 0; i < RV_MAX_TRIGGERS; i++) {
145
+ * Rev: 1.10
88
+ if (get_trigger_type(env, i) != TRIGGER_TYPE_INST_CNT) {
146
*/
89
+ continue;
147
90
+ }
148
static void
91
+ count = itrigger_get_count(env, i);
149
spcr_setup(GArray *table_data, BIOSLinker *linker, RISCVVirtState *s)
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
{
150
{
135
switch (tdata_index) {
151
+ const char name[] = ".";
136
@@ -XXX,XX +XXX,XX @@ void riscv_trigger_init(CPURISCVState *env)
152
AcpiSpcrData serial = {
137
env->tdata3[i] = 0;
153
- .interface_type = 0, /* 16550 compatible */
138
env->cpu_breakpoint[i] = NULL;
154
+ .interface_type = 0x12, /* 16550 compatible */
139
env->cpu_watchpoint[i] = NULL;
155
.base_addr.id = AML_AS_SYSTEM_MEMORY,
140
+ env->itrigger_timer[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL,
156
.base_addr.width = 32,
141
+ riscv_itrigger_timer_cb, env);
157
.base_addr.offset = 0,
142
}
158
@@ -XXX,XX +XXX,XX @@ spcr_setup(GArray *table_data, BIOSLinker *linker, RISCVVirtState *s)
159
.pci_function = 0,
160
.pci_flags = 0,
161
.pci_segment = 0,
162
+ .uart_clk_freq = 0,
163
+ .precise_baudrate = 0,
164
+ .namespace_string_length = sizeof(name),
165
+ .namespace_string_offset = 88,
166
};
167
168
- build_spcr(table_data, linker, &serial, 2, s->oem_id, s->oem_table_id);
169
+ build_spcr(table_data, linker, &serial, 4, s->oem_id, s->oem_table_id,
170
+ name);
143
}
171
}
172
173
/* RHCT Node[N] starts at offset 56 */
144
--
174
--
145
2.38.1
175
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
2
2
3
Per chapter 6.5.2 in [1], the number of interupt sources including
3
Update the virt SPCR golden reference file for RISC-V to accommodate the
4
interrupt source 0 should be 187.
4
SPCR Table revision 4 [1], utilizing the iasl binary compiled from the
5
latest ACPICA repository. The SPCR table has been modified to
6
adhere to the revision 4 format [2].
5
7
6
[1] PolarFire SoC MSS TRM:
8
[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
7
https://ww1.microchip.com/downloads/aemDocuments/documents/FPGA/ProductDocuments/ReferenceManuals/PolarFire_SoC_FPGA_MSS_Technical_Reference_Manual_VC.pdf
9
[2]: https://github.com/acpica/acpica/pull/931
8
10
9
Fixes: 56f6e31e7b7e ("hw/riscv: Initial support for Microchip PolarFire SoC Icicle Kit board")
11
Diffs from iasl:
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
12
/*
11
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
13
* Intel ACPI Component Architecture
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
* AML/ASL+ Disassembler version 20200925 (64-bit version)
13
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
15
* Copyright (c) 2000 - 2020 Intel Corporation
14
Message-Id: <20221211030829.802437-10-bmeng@tinylab.org>
16
*
17
- * Disassembly of tests/data/acpi/riscv64/virt/SPCR, Wed Aug 28 18:28:19 2024
18
+ * Disassembly of /tmp/aml-MN0NS2, Wed Aug 28 18:28:19 2024
19
*
20
* ACPI Data Table [SPCR]
21
*
22
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
23
*/
24
25
[000h 0000 4] Signature : "SPCR" [Serial Port Console Redirection table]
26
-[004h 0004 4] Table Length : 00000050
27
-[008h 0008 1] Revision : 02
28
-[009h 0009 1] Checksum : B9
29
+[004h 0004 4] Table Length : 0000005A
30
+[008h 0008 1] Revision : 04
31
+[009h 0009 1] Checksum : 13
32
[00Ah 0010 6] Oem ID : "BOCHS "
33
[010h 0016 8] Oem Table ID : "BXPC "
34
[018h 0024 4] Oem Revision : 00000001
35
[01Ch 0028 4] Asl Compiler ID : "BXPC"
36
[020h 0032 4] Asl Compiler Revision : 00000001
37
38
-[024h 0036 1] Interface Type : 00
39
+[024h 0036 1] Interface Type : 12
40
[025h 0037 3] Reserved : 000000
41
42
[028h 0040 12] Serial Port Register : [Generic Address Structure]
43
[028h 0040 1] Space ID : 00 [SystemMemory]
44
[029h 0041 1] Bit Width : 20
45
[02Ah 0042 1] Bit Offset : 00
46
[02Bh 0043 1] Encoded Access Width : 01 [Byte Access:8]
47
[02Ch 0044 8] Address : 0000000010000000
48
49
[034h 0052 1] Interrupt Type : 10
50
[035h 0053 1] PCAT-compatible IRQ : 00
51
[036h 0054 4] Interrupt : 0000000A
52
[03Ah 0058 1] Baud Rate : 07
53
[03Bh 0059 1] Parity : 00
54
[03Ch 0060 1] Stop Bits : 01
55
[03Dh 0061 1] Flow Control : 00
56
[03Eh 0062 1] Terminal Type : 00
57
[04Ch 0076 1] Reserved : 00
58
[040h 0064 2] PCI Device ID : FFFF
59
[042h 0066 2] PCI Vendor ID : FFFF
60
[044h 0068 1] PCI Bus : 00
61
[045h 0069 1] PCI Device : 00
62
[046h 0070 1] PCI Function : 00
63
[047h 0071 4] PCI Flags : 00000000
64
[04Bh 0075 1] PCI Segment : 00
65
-[04Ch 0076 4] Reserved : 00000000
66
+[04Ch 0076 004h] Uart Clock Freq : 00000000
67
+[050h 0080 004h] Precise Baud rate : 00000000
68
+[054h 0084 002h] NameSpaceStringLength : 0002
69
+[056h 0086 002h] NameSpaceStringOffset : 0058
70
+[058h 0088 002h] NamespaceString : "."
71
72
-Raw Table Data: Length 80 (0x50)
73
+Raw Table Data: Length 90 (0x5A)
74
75
- 0000: 53 50 43 52 50 00 00 00 02 B9 42 4F 43 48 53 20 // SPCRP.....BOCHS
76
+ 0000: 53 50 43 52 5A 00 00 00 04 13 42 4F 43 48 53 20 // SPCRZ.....BOCHS
77
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
78
- 0020: 01 00 00 00 00 00 00 00 00 20 00 01 00 00 00 10 // ......... ......
79
+ 0020: 01 00 00 00 12 00 00 00 00 20 00 01 00 00 00 10 // ......... ......
80
0030: 00 00 00 00 10 00 0A 00 00 00 07 00 01 00 00 03 // ................
81
0040: FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00 // ................
82
+ 0050: 00 00 00 00 02 00 58 00 2E 00 // ......X...
83
84
Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
85
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
86
Message-ID: <20241028015744.624943-4-jeeheng.sia@starfivetech.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
87
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
88
---
17
include/hw/riscv/microchip_pfsoc.h | 2 +-
89
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
18
1 file changed, 1 insertion(+), 1 deletion(-)
90
tests/data/acpi/riscv64/virt/SPCR | Bin 80 -> 90 bytes
91
2 files changed, 1 deletion(-)
19
92
20
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
93
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
21
index XXXXXXX..XXXXXXX 100644
94
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/riscv/microchip_pfsoc.h
95
--- a/tests/qtest/bios-tables-test-allowed-diff.h
23
+++ b/include/hw/riscv/microchip_pfsoc.h
96
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
24
@@ -XXX,XX +XXX,XX @@ enum {
97
@@ -1,2 +1 @@
25
#define MICROCHIP_PFSOC_MANAGEMENT_CPU_COUNT 1
98
/* List of comma-separated changed AML files to ignore */
26
#define MICROCHIP_PFSOC_COMPUTE_CPU_COUNT 4
99
-"tests/data/acpi/riscv64/virt/SPCR",
27
100
diff --git a/tests/data/acpi/riscv64/virt/SPCR b/tests/data/acpi/riscv64/virt/SPCR
28
-#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 185
101
index XXXXXXX..XXXXXXX 100644
29
+#define MICROCHIP_PFSOC_PLIC_NUM_SOURCES 187
102
Binary files a/tests/data/acpi/riscv64/virt/SPCR and b/tests/data/acpi/riscv64/virt/SPCR differ
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
--
103
--
34
2.38.1
104
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
hw/pci/Kconfig says MSI_NONBROKEN should be selected by interrupt
3
The HTIF interface is RISC-V specific, add
4
controllers regardless of how MSI is implemented. msi_nonbroken is
4
it within the MAINTAINERS section covering
5
initialized to true in both riscv_aplic_realize() and
5
hw/riscv/.
6
riscv_imsic_realize().
7
6
8
Select MSI_NONBROKEN in RISCV_APLIC and RISCV_IMSIC.
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
10
Signed-off-by: Bin Meng <bmeng@tinylab.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Message-Id: <20221211030829.802437-2-bmeng@tinylab.org>
10
Message-ID: <20241129154304.34946-2-philmd@linaro.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
12
---
16
hw/intc/Kconfig | 2 ++
13
MAINTAINERS | 2 ++
17
1 file changed, 2 insertions(+)
14
1 file changed, 2 insertions(+)
18
15
19
diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig
16
diff --git a/MAINTAINERS b/MAINTAINERS
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/intc/Kconfig
18
--- a/MAINTAINERS
22
+++ b/hw/intc/Kconfig
19
+++ b/MAINTAINERS
23
@@ -XXX,XX +XXX,XX @@ config RISCV_ACLINT
20
@@ -XXX,XX +XXX,XX @@ S: Supported
24
21
F: configs/targets/riscv*
25
config RISCV_APLIC
22
F: docs/system/target-riscv.rst
26
bool
23
F: target/riscv/
27
+ select MSI_NONBROKEN
24
+F: hw/char/riscv_htif.c
28
25
F: hw/riscv/
29
config RISCV_IMSIC
26
F: hw/intc/riscv*
30
bool
27
+F: include/hw/char/riscv_htif.h
31
+ select MSI_NONBROKEN
28
F: include/hw/riscv/
32
29
F: linux-user/host/riscv32/
33
config SIFIVE_PLIC
30
F: linux-user/host/riscv64/
34
bool
35
--
31
--
36
2.38.1
32
2.47.1
33
34
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Per chapter 10 in Freedom E310 manuals [1][2][3], E310 G002 and G003
3
Since our RISC-V system emulation is only built for little
4
supports 52 interrupt sources while G000 supports 51 interrupt sources.
4
endian, the HTIF device aims to interface with little endian
5
memory accesses, thus we can explicit htif_mm_ops:endianness
6
being DEVICE_LITTLE_ENDIAN.
5
7
6
We use the value of G002 and G003, so it is 53 (including source 0).
8
In that case tswap64() is equivalent to le64_to_cpu(), as in
9
"convert this 64-bit little-endian value into host cpu order".
10
Replace to simplify.
7
11
8
[1] G000 manual:
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20221211030829.802437-11-bmeng@tinylab.org>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Message-ID: <20241129154304.34946-3-philmd@linaro.org>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
17
---
24
include/hw/riscv/sifive_e.h | 7 ++++++-
18
hw/char/riscv_htif.c | 11 ++++++-----
25
1 file changed, 6 insertions(+), 1 deletion(-)
19
1 file changed, 6 insertions(+), 5 deletions(-)
26
20
27
diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h
21
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
28
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
29
--- a/include/hw/riscv/sifive_e.h
23
--- a/hw/char/riscv_htif.c
30
+++ b/include/hw/riscv/sifive_e.h
24
+++ b/hw/char/riscv_htif.c
31
@@ -XXX,XX +XXX,XX @@ enum {
25
@@ -XXX,XX +XXX,XX @@
26
#include "qemu/timer.h"
27
#include "qemu/error-report.h"
28
#include "exec/address-spaces.h"
29
-#include "exec/tswap.h"
30
+#include "qemu/bswap.h"
31
#include "sysemu/dma.h"
32
#include "sysemu/runstate.h"
33
34
@@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
35
} else {
36
uint64_t syscall[8];
37
cpu_physical_memory_read(payload, syscall, sizeof(syscall));
38
- if (tswap64(syscall[0]) == PK_SYS_WRITE &&
39
- tswap64(syscall[1]) == HTIF_DEV_CONSOLE &&
40
- tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
41
+ if (le64_to_cpu(syscall[0]) == PK_SYS_WRITE &&
42
+ le64_to_cpu(syscall[1]) == HTIF_DEV_CONSOLE &&
43
+ le64_to_cpu(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
44
uint8_t ch;
45
- cpu_physical_memory_read(tswap64(syscall[2]), &ch, 1);
46
+ cpu_physical_memory_read(le64_to_cpu(syscall[2]), &ch, 1);
47
/*
48
* XXX this blocks entire thread. Rewrite to use
49
* qemu_chr_fe_write and background I/O callbacks
50
@@ -XXX,XX +XXX,XX @@ static void htif_mm_write(void *opaque, hwaddr addr,
51
static const MemoryRegionOps htif_mm_ops = {
52
.read = htif_mm_read,
53
.write = htif_mm_write,
54
+ .endianness = DEVICE_LITTLE_ENDIAN,
32
};
55
};
33
56
34
#define SIFIVE_E_PLIC_HART_CONFIG "M"
57
HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
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
--
58
--
46
2.38.1
59
2.47.1
60
61
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The Fabric Interconnect Controllers provide interfaces between the FPGA
3
Looking at htif_mm_ops[] read/write handlers, we notice they
4
fabric and the core complex. There are 5 FICs on PolarFire SoC, numbered
4
expect 32-bit values to accumulate into to the 'fromhost' and
5
0 through 4. FIC2 is an AXI4 slave interface from the FPGA fabric and
5
'tohost' 64-bit variables. Explicit by setting the .impl
6
does not show up on the MSS memory map. FIC4 is dedicated to the User
6
min/max fields.
7
Crypto Processor and does not show up on the MSS memory map either.
8
7
9
FIC 0, 1 & 3 do show up in the MSS memory map and neither FICs 0 or 1
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
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>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Conor Dooley <conor.dooley@microchip.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
16
Message-Id: <20221117225518.4102575-3-conor@kernel.org>
11
Message-ID: <20241129154304.34946-4-philmd@linaro.org>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
13
---
19
include/hw/riscv/microchip_pfsoc.h | 2 +
14
hw/char/riscv_htif.c | 4 ++++
20
hw/riscv/microchip_pfsoc.c | 115 ++++++++++++++++-------------
15
1 file changed, 4 insertions(+)
21
2 files changed, 65 insertions(+), 52 deletions(-)
22
16
23
diff --git a/include/hw/riscv/microchip_pfsoc.h b/include/hw/riscv/microchip_pfsoc.h
17
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
24
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/riscv/microchip_pfsoc.h
19
--- a/hw/char/riscv_htif.c
26
+++ b/include/hw/riscv/microchip_pfsoc.h
20
+++ b/hw/char/riscv_htif.c
27
@@ -XXX,XX +XXX,XX @@ enum {
21
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps htif_mm_ops = {
28
MICROCHIP_PFSOC_USB,
22
.read = htif_mm_read,
29
MICROCHIP_PFSOC_QSPI_XIP,
23
.write = htif_mm_write,
30
MICROCHIP_PFSOC_IOSCB,
24
.endianness = DEVICE_LITTLE_ENDIAN,
31
+ MICROCHIP_PFSOC_FABRIC_FIC0,
25
+ .impl = {
32
+ MICROCHIP_PFSOC_FABRIC_FIC1,
26
+ .min_access_size = 4,
33
MICROCHIP_PFSOC_FABRIC_FIC3,
27
+ .max_access_size = 4,
34
MICROCHIP_PFSOC_DRAM_LO,
28
+ },
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
};
29
};
152
30
153
static void microchip_pfsoc_soc_instance_init(Object *obj)
31
HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
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
--
32
--
170
2.38.1
33
2.47.1
34
35
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Jim Shu <jim.shu@sifive.com>
2
2
3
PLIC is not included in the 'spike' machine.
3
Larger initrd image will overlap the DTB at 3GB address. Since 64-bit
4
system doesn't have 32-bit addressable issue, we just load DTB to the end
5
of dram in 64-bit system.
4
6
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221211030829.802437-5-bmeng@tinylab.org>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20241120153935.24706-2-jim.shu@sifive.com>
11
[ Changes by AF
12
- Store fdt_load_addr_hi32 in the reset vector
13
]
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
15
---
11
hw/riscv/spike.c | 1 -
16
include/hw/riscv/boot.h | 2 +-
12
1 file changed, 1 deletion(-)
17
hw/riscv/boot.c | 14 +++++++++-----
18
hw/riscv/microchip_pfsoc.c | 4 ++--
19
hw/riscv/sifive_u.c | 8 +++++---
20
hw/riscv/spike.c | 4 ++--
21
hw/riscv/virt.c | 2 +-
22
6 files changed, 20 insertions(+), 14 deletions(-)
13
23
24
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
25
index XXXXXXX..XXXXXXX 100644
26
--- a/include/hw/riscv/boot.h
27
+++ b/include/hw/riscv/boot.h
28
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
29
bool load_initrd,
30
symbol_fn_t sym_cb);
31
uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
32
- MachineState *ms);
33
+ MachineState *ms, RISCVHartArrayState *harts);
34
void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
35
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
36
hwaddr saddr,
37
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/riscv/boot.c
40
+++ b/hw/riscv/boot.c
41
@@ -XXX,XX +XXX,XX @@ out:
42
* The FDT is fdt_packed() during the calculation.
43
*/
44
uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
45
- MachineState *ms)
46
+ MachineState *ms, RISCVHartArrayState *harts)
47
{
48
int ret = fdt_pack(ms->fdt);
49
hwaddr dram_end, temp;
50
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
51
52
/*
53
* We should put fdt as far as possible to avoid kernel/initrd overwriting
54
- * its content. But it should be addressable by 32 bit system as well.
55
- * Thus, put it at an 2MB aligned address that less than fdt size from the
56
- * end of dram or 3GB whichever is lesser.
57
+ * its content. But it should be addressable by 32 bit system as well in RV32.
58
+ * Thus, put it near to the end of dram in RV64, and put it near to the end
59
+ * of dram or 3GB whichever is lesser in RV32.
60
*/
61
- temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
62
+ if (!riscv_is_32bit(harts)) {
63
+ temp = dram_end;
64
+ } else {
65
+ temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
66
+ }
67
68
return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
69
}
70
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
71
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/riscv/microchip_pfsoc.c
73
+++ b/hw/riscv/microchip_pfsoc.c
74
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
75
bool kernel_as_payload = false;
76
target_ulong firmware_end_addr, kernel_start_addr;
77
uint64_t kernel_entry;
78
- uint32_t fdt_load_addr;
79
+ uint64_t fdt_load_addr;
80
DriveInfo *dinfo = drive_get(IF_SD, 0, 0);
81
82
/* Sanity check on RAM size */
83
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
84
/* Compute the fdt load address in dram */
85
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
86
memmap[MICROCHIP_PFSOC_DRAM_LO].size,
87
- machine);
88
+ machine, &s->soc.u_cpus);
89
riscv_load_fdt(fdt_load_addr, machine->fdt);
90
91
/* Load the reset vector */
92
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
93
index XXXXXXX..XXXXXXX 100644
94
--- a/hw/riscv/sifive_u.c
95
+++ b/hw/riscv/sifive_u.c
96
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
97
target_ulong firmware_end_addr, kernel_start_addr;
98
const char *firmware_name;
99
uint32_t start_addr_hi32 = 0x00000000;
100
+ uint32_t fdt_load_addr_hi32 = 0x00000000;
101
int i;
102
- uint32_t fdt_load_addr;
103
+ uint64_t fdt_load_addr;
104
uint64_t kernel_entry;
105
DriveInfo *dinfo;
106
BlockBackend *blk;
107
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
108
109
fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base,
110
memmap[SIFIVE_U_DEV_DRAM].size,
111
- machine);
112
+ machine, &s->soc.u_cpus);
113
riscv_load_fdt(fdt_load_addr, machine->fdt);
114
115
if (!riscv_is_32bit(&s->soc.u_cpus)) {
116
start_addr_hi32 = (uint64_t)start_addr >> 32;
117
+ fdt_load_addr_hi32 = fdt_load_addr >> 32;
118
}
119
120
/* reset vector */
121
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
122
start_addr, /* start: .dword */
123
start_addr_hi32,
124
fdt_load_addr, /* fdt_laddr: .dword */
125
- 0x00000000,
126
+ fdt_load_addr_hi32,
127
0x00000000,
128
/* fw_dyn: */
129
};
14
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
130
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
15
index XXXXXXX..XXXXXXX 100644
131
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/riscv/spike.c
132
--- a/hw/riscv/spike.c
17
+++ b/hw/riscv/spike.c
133
+++ b/hw/riscv/spike.c
18
@@ -XXX,XX +XXX,XX @@
134
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
19
*
135
hwaddr firmware_load_addr = memmap[SPIKE_DRAM].base;
20
* 0) HTIF Console and Poweroff
136
target_ulong kernel_start_addr;
21
* 1) CLINT (Timer and IPI)
137
char *firmware_name;
22
- * 2) PLIC (Platform Level Interrupt Controller)
138
- uint32_t fdt_load_addr;
23
*
139
+ uint64_t fdt_load_addr;
24
* This program is free software; you can redistribute it and/or modify it
140
uint64_t kernel_entry;
25
* under the terms and conditions of the GNU General Public License,
141
char *soc_name;
142
int i, base_hartid, hart_count;
143
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
144
145
fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base,
146
memmap[SPIKE_DRAM].size,
147
- machine);
148
+ machine, &s->soc[0]);
149
riscv_load_fdt(fdt_load_addr, machine->fdt);
150
151
/* load the reset vector */
152
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/hw/riscv/virt.c
155
+++ b/hw/riscv/virt.c
156
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
157
158
fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base,
159
memmap[VIRT_DRAM].size,
160
- machine);
161
+ machine, &s->soc[0]);
162
riscv_load_fdt(fdt_load_addr, machine->fdt);
163
164
/* load the reset vector */
26
--
165
--
27
2.38.1
166
2.47.1
diff view generated by jsdifflib
1
From: Wilfred Mallawa <wilfred.mallawa@wdc.com>
1
From: Jim Shu <jim.shu@sifive.com>
2
2
3
Adds the updated `aon_timer` base as an unimplemented device. This is
3
Add a new struct RISCVBootInfo to sync boot information between multiple
4
used by TockOS, patch ensures the guest doesn't hit load faults.
4
boot functions.
5
5
6
Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
6
Signed-off-by: Jim Shu <jim.shu@sifive.com>
7
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221025043335.339815-3-wilfred.mallawa@opensource.wdc.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-ID: <20241120153935.24706-3-jim.shu@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
include/hw/riscv/opentitan.h | 1 +
12
include/hw/riscv/boot.h | 25 ++++++++++-----
13
hw/riscv/opentitan.c | 3 +++
13
hw/riscv/boot.c | 65 ++++++++++++++++++++++----------------
14
2 files changed, 4 insertions(+)
14
hw/riscv/microchip_pfsoc.c | 11 ++++---
15
hw/riscv/opentitan.c | 4 ++-
16
hw/riscv/sifive_e.c | 4 ++-
17
hw/riscv/sifive_u.c | 12 ++++---
18
hw/riscv/spike.c | 12 ++++---
19
hw/riscv/virt.c | 13 +++++---
20
8 files changed, 90 insertions(+), 56 deletions(-)
15
21
16
diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h
22
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
17
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/riscv/opentitan.h
24
--- a/include/hw/riscv/boot.h
19
+++ b/include/hw/riscv/opentitan.h
25
+++ b/include/hw/riscv/boot.h
20
@@ -XXX,XX +XXX,XX @@ enum {
26
@@ -XXX,XX +XXX,XX @@
21
IBEX_DEV_RSTMGR,
27
#define RISCV32_BIOS_BIN "opensbi-riscv32-generic-fw_dynamic.bin"
22
IBEX_DEV_CLKMGR,
28
#define RISCV64_BIOS_BIN "opensbi-riscv64-generic-fw_dynamic.bin"
23
IBEX_DEV_PINMUX,
29
24
+ IBEX_DEV_AON_TIMER,
30
+typedef struct RISCVBootInfo {
25
IBEX_DEV_USBDEV,
31
+ ssize_t kernel_size;
26
IBEX_DEV_FLASH_CTRL,
32
+ hwaddr image_low_addr;
27
IBEX_DEV_PLIC,
33
+ hwaddr image_high_addr;
34
+
35
+ bool is_32bit;
36
+} RISCVBootInfo;
37
+
38
bool riscv_is_32bit(RISCVHartArrayState *harts);
39
40
char *riscv_plic_hart_config_string(int hart_count);
41
42
-target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
43
+void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts);
44
+target_ulong riscv_calc_kernel_start_addr(RISCVBootInfo *info,
45
target_ulong firmware_end_addr);
46
target_ulong riscv_find_and_load_firmware(MachineState *machine,
47
const char *default_machine_firmware,
48
@@ -XXX,XX +XXX,XX @@ char *riscv_find_firmware(const char *firmware_filename,
49
target_ulong riscv_load_firmware(const char *firmware_filename,
50
hwaddr *firmware_load_addr,
51
symbol_fn_t sym_cb);
52
-target_ulong riscv_load_kernel(MachineState *machine,
53
- RISCVHartArrayState *harts,
54
- target_ulong firmware_end_addr,
55
- bool load_initrd,
56
- symbol_fn_t sym_cb);
57
-uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size,
58
- MachineState *ms, RISCVHartArrayState *harts);
59
+void riscv_load_kernel(MachineState *machine,
60
+ RISCVBootInfo *info,
61
+ target_ulong kernel_start_addr,
62
+ bool load_initrd,
63
+ symbol_fn_t sym_cb);
64
+uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
65
+ MachineState *ms, RISCVBootInfo *info);
66
void riscv_load_fdt(hwaddr fdt_addr, void *fdt);
67
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts,
68
hwaddr saddr,
69
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/riscv/boot.c
72
+++ b/hw/riscv/boot.c
73
@@ -XXX,XX +XXX,XX @@ char *riscv_plic_hart_config_string(int hart_count)
74
return g_strjoinv(",", (char **)vals);
75
}
76
77
-target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts,
78
+void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts)
79
+{
80
+ info->kernel_size = 0;
81
+ info->is_32bit = riscv_is_32bit(harts);
82
+}
83
+
84
+target_ulong riscv_calc_kernel_start_addr(RISCVBootInfo *info,
85
target_ulong firmware_end_addr) {
86
- if (riscv_is_32bit(harts)) {
87
+ if (info->is_32bit) {
88
return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB);
89
} else {
90
return QEMU_ALIGN_UP(firmware_end_addr, 2 * MiB);
91
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename,
92
exit(1);
93
}
94
95
-static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
96
+static void riscv_load_initrd(MachineState *machine, RISCVBootInfo *info)
97
{
98
const char *filename = machine->initrd_filename;
99
uint64_t mem_size = machine->ram_size;
100
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
101
* halfway into RAM, and for boards with 1GB of RAM or more we put
102
* the initrd at 512MB.
103
*/
104
- start = kernel_entry + MIN(mem_size / 2, 512 * MiB);
105
+ start = info->image_low_addr + MIN(mem_size / 2, 512 * MiB);
106
107
size = load_ramdisk(filename, start, mem_size - start);
108
if (size == -1) {
109
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry)
110
}
111
}
112
113
-target_ulong riscv_load_kernel(MachineState *machine,
114
- RISCVHartArrayState *harts,
115
- target_ulong kernel_start_addr,
116
- bool load_initrd,
117
- symbol_fn_t sym_cb)
118
+void riscv_load_kernel(MachineState *machine,
119
+ RISCVBootInfo *info,
120
+ target_ulong kernel_start_addr,
121
+ bool load_initrd,
122
+ symbol_fn_t sym_cb)
123
{
124
const char *kernel_filename = machine->kernel_filename;
125
- uint64_t kernel_load_base, kernel_entry;
126
+ ssize_t kernel_size;
127
void *fdt = machine->fdt;
128
129
g_assert(kernel_filename != NULL);
130
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
131
* the (expected) load address load address. This allows kernels to have
132
* separate SBI and ELF entry points (used by FreeBSD, for example).
133
*/
134
- if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
135
- NULL, &kernel_load_base, NULL, NULL, 0,
136
- EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
137
- kernel_entry = kernel_load_base;
138
+ kernel_size = load_elf_ram_sym(kernel_filename, NULL, NULL, NULL, NULL,
139
+ &info->image_low_addr, &info->image_high_addr,
140
+ NULL, 0, EM_RISCV, 1, 0, NULL, true, sym_cb);
141
+ if (kernel_size > 0) {
142
+ info->kernel_size = kernel_size;
143
goto out;
144
}
145
146
- if (load_uimage_as(kernel_filename, &kernel_entry, NULL, NULL,
147
- NULL, NULL, NULL) > 0) {
148
+ kernel_size = load_uimage_as(kernel_filename, &info->image_low_addr,
149
+ NULL, NULL, NULL, NULL, NULL);
150
+ if (kernel_size > 0) {
151
+ info->kernel_size = kernel_size;
152
+ info->image_high_addr = info->image_low_addr + kernel_size;
153
goto out;
154
}
155
156
- if (load_image_targphys_as(kernel_filename, kernel_start_addr,
157
- current_machine->ram_size, NULL) > 0) {
158
- kernel_entry = kernel_start_addr;
159
+ kernel_size = load_image_targphys_as(kernel_filename, kernel_start_addr,
160
+ current_machine->ram_size, NULL);
161
+ if (kernel_size > 0) {
162
+ info->kernel_size = kernel_size;
163
+ info->image_low_addr = kernel_start_addr;
164
+ info->image_high_addr = info->image_low_addr + kernel_size;
165
goto out;
166
}
167
168
@@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine,
169
170
out:
171
/*
172
- * For 32 bit CPUs 'kernel_entry' can be sign-extended by
173
+ * For 32 bit CPUs 'image_low_addr' can be sign-extended by
174
* load_elf_ram_sym().
175
*/
176
- if (riscv_is_32bit(harts)) {
177
- kernel_entry = extract64(kernel_entry, 0, 32);
178
+ if (info->is_32bit) {
179
+ info->image_low_addr = extract64(info->image_low_addr, 0, 32);
180
}
181
182
if (load_initrd && machine->initrd_filename) {
183
- riscv_load_initrd(machine, kernel_entry);
184
+ riscv_load_initrd(machine, info);
185
}
186
187
if (fdt && machine->kernel_cmdline && *machine->kernel_cmdline) {
188
qemu_fdt_setprop_string(fdt, "/chosen", "bootargs",
189
machine->kernel_cmdline);
190
}
191
-
192
- return kernel_entry;
193
}
194
195
/*
196
@@ -XXX,XX +XXX,XX @@ out:
197
* The FDT is fdt_packed() during the calculation.
198
*/
199
uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
200
- MachineState *ms, RISCVHartArrayState *harts)
201
+ MachineState *ms, RISCVBootInfo *info)
202
{
203
int ret = fdt_pack(ms->fdt);
204
hwaddr dram_end, temp;
205
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
206
* Thus, put it near to the end of dram in RV64, and put it near to the end
207
* of dram or 3GB whichever is lesser in RV32.
208
*/
209
- if (!riscv_is_32bit(harts)) {
210
+ if (!info->is_32bit) {
211
temp = dram_end;
212
} else {
213
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
214
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
215
index XXXXXXX..XXXXXXX 100644
216
--- a/hw/riscv/microchip_pfsoc.c
217
+++ b/hw/riscv/microchip_pfsoc.c
218
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
219
uint64_t kernel_entry;
220
uint64_t fdt_load_addr;
221
DriveInfo *dinfo = drive_get(IF_SD, 0, 0);
222
+ RISCVBootInfo boot_info;
223
224
/* Sanity check on RAM size */
225
if (machine->ram_size < mc->default_ram_size) {
226
@@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine)
227
firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
228
&firmware_load_addr, NULL);
229
230
+ riscv_boot_info_init(&boot_info, &s->soc.u_cpus);
231
if (kernel_as_payload) {
232
- kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
233
+ kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,
234
firmware_end_addr);
235
236
- kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
237
- kernel_start_addr, true, NULL);
238
+ riscv_load_kernel(machine, &boot_info, kernel_start_addr,
239
+ true, NULL);
240
+ kernel_entry = boot_info.image_low_addr;
241
242
/* Compute the fdt load address in dram */
243
fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base,
244
memmap[MICROCHIP_PFSOC_DRAM_LO].size,
245
- machine, &s->soc.u_cpus);
246
+ machine, &boot_info);
247
riscv_load_fdt(fdt_load_addr, machine->fdt);
248
249
/* Load the reset vector */
28
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
250
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
29
index XXXXXXX..XXXXXXX 100644
251
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/riscv/opentitan.c
252
--- a/hw/riscv/opentitan.c
31
+++ b/hw/riscv/opentitan.c
253
+++ b/hw/riscv/opentitan.c
32
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry ibex_memmap[] = {
254
@@ -XXX,XX +XXX,XX @@ static void opentitan_machine_init(MachineState *machine)
33
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
255
OpenTitanState *s = OPENTITAN_MACHINE(machine);
34
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
256
const MemMapEntry *memmap = ibex_memmap;
35
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
257
MemoryRegion *sys_mem = get_system_memory();
36
+ [IBEX_DEV_AON_TIMER] = { 0x40470000, 0x1000 },
258
+ RISCVBootInfo boot_info;
37
[IBEX_DEV_SENSOR_CTRL] = { 0x40490000, 0x1000 },
259
38
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
260
if (machine->ram_size != mc->default_ram_size) {
39
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
261
char *sz = size_to_str(mc->default_ram_size);
40
@@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
262
@@ -XXX,XX +XXX,XX @@ static void opentitan_machine_init(MachineState *machine)
41
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
263
riscv_load_firmware(machine->firmware, &firmware_load_addr, NULL);
42
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
264
}
43
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
265
44
+ create_unimplemented_device("riscv.lowrisc.ibex.aon_timer",
266
+ riscv_boot_info_init(&boot_info, &s->soc.cpus);
45
+ memmap[IBEX_DEV_AON_TIMER].base, memmap[IBEX_DEV_AON_TIMER].size);
267
if (machine->kernel_filename) {
46
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
268
- riscv_load_kernel(machine, &s->soc.cpus,
47
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
269
+ riscv_load_kernel(machine, &boot_info,
48
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
270
memmap[IBEX_DEV_RAM].base,
271
false, NULL);
272
}
273
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
274
index XXXXXXX..XXXXXXX 100644
275
--- a/hw/riscv/sifive_e.c
276
+++ b/hw/riscv/sifive_e.c
277
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
278
SiFiveEState *s = RISCV_E_MACHINE(machine);
279
MemoryRegion *sys_mem = get_system_memory();
280
int i;
281
+ RISCVBootInfo boot_info;
282
283
if (machine->ram_size != mc->default_ram_size) {
284
char *sz = size_to_str(mc->default_ram_size);
285
@@ -XXX,XX +XXX,XX @@ static void sifive_e_machine_init(MachineState *machine)
286
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
287
memmap[SIFIVE_E_DEV_MROM].base, &address_space_memory);
288
289
+ riscv_boot_info_init(&boot_info, &s->soc.cpus);
290
if (machine->kernel_filename) {
291
- riscv_load_kernel(machine, &s->soc.cpus,
292
+ riscv_load_kernel(machine, &boot_info,
293
memmap[SIFIVE_E_DEV_DTIM].base,
294
false, NULL);
295
}
296
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
297
index XXXXXXX..XXXXXXX 100644
298
--- a/hw/riscv/sifive_u.c
299
+++ b/hw/riscv/sifive_u.c
300
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
301
BlockBackend *blk;
302
DeviceState *flash_dev, *sd_dev, *card_dev;
303
qemu_irq flash_cs, sd_cs;
304
+ RISCVBootInfo boot_info;
305
306
/* Initialize SoC */
307
object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC);
308
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
309
firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name,
310
&start_addr, NULL);
311
312
+ riscv_boot_info_init(&boot_info, &s->soc.u_cpus);
313
if (machine->kernel_filename) {
314
- kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc.u_cpus,
315
+ kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,
316
firmware_end_addr);
317
-
318
- kernel_entry = riscv_load_kernel(machine, &s->soc.u_cpus,
319
- kernel_start_addr, true, NULL);
320
+ riscv_load_kernel(machine, &boot_info, kernel_start_addr,
321
+ true, NULL);
322
+ kernel_entry = boot_info.image_low_addr;
323
} else {
324
/*
325
* If dynamic firmware is used, it doesn't know where is the next mode
326
@@ -XXX,XX +XXX,XX @@ static void sifive_u_machine_init(MachineState *machine)
327
328
fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base,
329
memmap[SIFIVE_U_DEV_DRAM].size,
330
- machine, &s->soc.u_cpus);
331
+ machine, &boot_info);
332
riscv_load_fdt(fdt_load_addr, machine->fdt);
333
334
if (!riscv_is_32bit(&s->soc.u_cpus)) {
335
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
336
index XXXXXXX..XXXXXXX 100644
337
--- a/hw/riscv/spike.c
338
+++ b/hw/riscv/spike.c
339
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
340
char *soc_name;
341
int i, base_hartid, hart_count;
342
bool htif_custom_base = false;
343
+ RISCVBootInfo boot_info;
344
345
/* Check socket count limit */
346
if (SPIKE_SOCKETS_MAX < riscv_socket_count(machine)) {
347
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
348
create_fdt(s, memmap, riscv_is_32bit(&s->soc[0]), htif_custom_base);
349
350
/* Load kernel */
351
+ riscv_boot_info_init(&boot_info, &s->soc[0]);
352
if (machine->kernel_filename) {
353
- kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
354
+ kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,
355
firmware_end_addr);
356
357
- kernel_entry = riscv_load_kernel(machine, &s->soc[0],
358
- kernel_start_addr,
359
- true, htif_symbol_callback);
360
+ riscv_load_kernel(machine, &boot_info, kernel_start_addr,
361
+ true, htif_symbol_callback);
362
+ kernel_entry = boot_info.image_low_addr;
363
} else {
364
/*
365
* If dynamic firmware is used, it doesn't know where is the next mode
366
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
367
368
fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base,
369
memmap[SPIKE_DRAM].size,
370
- machine, &s->soc[0]);
371
+ machine, &boot_info);
372
riscv_load_fdt(fdt_load_addr, machine->fdt);
373
374
/* load the reset vector */
375
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
376
index XXXXXXX..XXXXXXX 100644
377
--- a/hw/riscv/virt.c
378
+++ b/hw/riscv/virt.c
379
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
380
uint64_t fdt_load_addr;
381
uint64_t kernel_entry = 0;
382
BlockBackend *pflash_blk0;
383
+ RISCVBootInfo boot_info;
384
385
/*
386
* An user provided dtb must include everything, including
387
@@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data)
388
}
389
}
390
391
+ riscv_boot_info_init(&boot_info, &s->soc[0]);
392
+
393
if (machine->kernel_filename && !kernel_entry) {
394
- kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0],
395
+ kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info,
396
firmware_end_addr);
397
-
398
- kernel_entry = riscv_load_kernel(machine, &s->soc[0],
399
- kernel_start_addr, true, NULL);
400
+ riscv_load_kernel(machine, &boot_info, kernel_start_addr,
401
+ true, NULL);
402
+ kernel_entry = boot_info.image_low_addr;
403
}
404
405
fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base,
406
memmap[VIRT_DRAM].size,
407
- machine, &s->soc[0]);
408
+ machine, &boot_info);
409
riscv_load_fdt(fdt_load_addr, machine->fdt);
410
411
/* load the reset vector */
49
--
412
--
50
2.38.1
413
2.47.1
diff view generated by jsdifflib
1
From: Jim Shu <jim.shu@sifive.com>
1
From: Jim Shu <jim.shu@sifive.com>
2
2
3
let tlb_fill() function also increments PMU counter when it is from
3
DTB is placed to the end of memory, so we will check if the start
4
two-stage translation, so QEMU could also monitor these PMU events when
4
address of DTB overlaps to the address of kernel/initrd.
5
CPU runs in VS/VU mode (like running guest OS).
6
5
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
6
Signed-off-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221123090635.6574-1-jim.shu@sifive.com>
8
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Message-ID: <20241120153935.24706-4-jim.shu@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
11
---
12
target/riscv/cpu_helper.c | 2 +-
12
include/hw/riscv/boot.h | 3 +++
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
hw/riscv/boot.c | 25 ++++++++++++++++++++++++-
14
2 files changed, 27 insertions(+), 1 deletion(-)
14
15
15
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
16
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu_helper.c
18
--- a/include/hw/riscv/boot.h
18
+++ b/target/riscv/cpu_helper.c
19
+++ b/include/hw/riscv/boot.h
19
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
20
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVBootInfo {
21
hwaddr image_low_addr;
22
hwaddr image_high_addr;
23
24
+ hwaddr initrd_start;
25
+ ssize_t initrd_size;
26
+
27
bool is_32bit;
28
} RISCVBootInfo;
29
30
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/riscv/boot.c
33
+++ b/hw/riscv/boot.c
34
@@ -XXX,XX +XXX,XX @@ char *riscv_plic_hart_config_string(int hart_count)
35
void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts)
36
{
37
info->kernel_size = 0;
38
+ info->initrd_size = 0;
39
info->is_32bit = riscv_is_32bit(harts);
40
}
41
42
@@ -XXX,XX +XXX,XX @@ static void riscv_load_initrd(MachineState *machine, RISCVBootInfo *info)
20
}
43
}
21
}
44
}
22
45
23
+ pmu_tlb_fill_incr_ctr(cpu, access_type);
46
+ info->initrd_start = start;
24
if (riscv_cpu_virt_enabled(env) ||
47
+ info->initrd_size = size;
25
((riscv_cpu_two_stage_lookup(mmu_idx) || two_stage_lookup) &&
48
+
26
access_type != MMU_INST_FETCH)) {
49
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
27
@@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
50
if (fdt) {
28
}
51
end = start + size;
29
}
52
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
30
} else {
53
int ret = fdt_pack(ms->fdt);
31
- pmu_tlb_fill_incr_ctr(cpu, access_type);
54
hwaddr dram_end, temp;
32
/* Single stage lookup */
55
int fdtsize;
33
ret = get_physical_address(env, &pa, &prot, address, NULL,
56
+ uint64_t dtb_start, dtb_start_limit;
34
access_type, mmu_idx, true, false, false);
57
58
/* Should only fail if we've built a corrupted tree */
59
g_assert(ret == 0);
60
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
61
exit(1);
62
}
63
64
+ if (info->initrd_size) {
65
+ /* If initrd is successfully loaded, place DTB after it. */
66
+ dtb_start_limit = info->initrd_start + info->initrd_size;
67
+ } else if (info->kernel_size) {
68
+ /* If only kernel is successfully loaded, place DTB after it. */
69
+ dtb_start_limit = info->image_high_addr;
70
+ } else {
71
+ /* Otherwise, do not check DTB overlapping */
72
+ dtb_start_limit = 0;
73
+ }
74
+
75
/*
76
* A dram_size == 0, usually from a MemMapEntry[].size element,
77
* means that the DRAM block goes all the way to ms->ram_size.
78
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
79
temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end;
80
}
81
82
- return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
83
+ dtb_start = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
84
+
85
+ if (dtb_start_limit && (dtb_start < dtb_start_limit)) {
86
+ error_report("No enough memory to place DTB after kernel/initrd");
87
+ exit(1);
88
+ }
89
+
90
+ return dtb_start;
91
}
92
93
/*
35
--
94
--
36
2.38.1
95
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: "Fea.Wang" <fea.wang@sifive.com>
2
2
3
H-mode has been removed since priv spec 1.10. Drop it.
3
Refer to the draft of svukte extension from:
4
https://github.com/riscv/riscv-isa-manual/pull/1564
4
5
5
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
Svukte provides a means to make user-mode accesses to supervisor memory
6
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
raise page faults in constant time, mitigating attacks that attempt to
8
discover the supervisor software's address-space layout.
9
10
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
11
Reviewed-by: Frank Chang <frank.chang@sifive.com>
12
Reviewed-by: Jim Shu <jim.shu@sifive.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-Id: <20221211030829.802437-6-bmeng@tinylab.org>
15
Message-ID: <20241203034932.25185-2-fea.wang@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
17
---
11
include/hw/intc/sifive_plic.h | 1 -
18
target/riscv/cpu_cfg.h | 1 +
12
hw/intc/sifive_plic.c | 1 -
19
1 file changed, 1 insertion(+)
13
2 files changed, 2 deletions(-)
14
20
15
diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/sifive_plic.h
23
--- a/target/riscv/cpu_cfg.h
18
+++ b/include/hw/intc/sifive_plic.h
24
+++ b/target/riscv/cpu_cfg.h
19
@@ -XXX,XX +XXX,XX @@ DECLARE_INSTANCE_CHECKER(SiFivePLICState, SIFIVE_PLIC,
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
20
typedef enum PLICMode {
26
bool ext_svnapot;
21
PLICMode_U,
27
bool ext_svpbmt;
22
PLICMode_S,
28
bool ext_svvptc;
23
- PLICMode_H,
29
+ bool ext_svukte;
24
PLICMode_M
30
bool ext_zdinx;
25
} PLICMode;
31
bool ext_zaamo;
26
32
bool ext_zacas;
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
--
33
--
40
2.38.1
34
2.47.1
diff view generated by jsdifflib
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
From: "Fea.Wang" <fea.wang@sifive.com>
2
2
3
Smstateen extension specifies a mechanism to close
3
Svukte extension add UKTE bit, bit[8] in senvcfg CSR. The bit will be
4
the potential covert channels that could cause security issues.
4
supported when the svukte extension is enabled.
5
5
6
This patch adds the CSRs defined in the specification and
6
When senvcfg[UKTE] bit is set, the memory access from U-mode should do
7
the corresponding predicates and read/write functions.
7
the svukte check only except HLV/HLVX/HSV H-mode instructions which
8
depend on hstatus[HUKTE].
8
9
9
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
10
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
10
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
11
Reviewed-by: Frank Chang <frank.chang@sifive.com>
12
Reviewed-by: Jim Shu <jim.shu@sifive.com>
13
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Message-Id: <20221016124726.102129-2-mchitale@ventanamicro.com>
15
Message-ID: <20241203034932.25185-3-fea.wang@sifive.com>
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
17
---
15
target/riscv/cpu.h | 4 +
18
target/riscv/cpu_bits.h | 1 +
16
target/riscv/cpu_bits.h | 37 +++++
19
target/riscv/csr.c | 4 ++++
17
target/riscv/csr.c | 316 ++++++++++++++++++++++++++++++++++++++++
20
2 files changed, 5 insertions(+)
18
target/riscv/machine.c | 21 +++
19
4 files changed, 378 insertions(+)
20
21
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
22
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
44
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
45
--- a/target/riscv/cpu_bits.h
24
--- a/target/riscv/cpu_bits.h
46
+++ b/target/riscv/cpu_bits.h
25
+++ b/target/riscv/cpu_bits.h
47
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
48
/* Supervisor Configuration CSRs */
27
#define SENVCFG_CBIE MENVCFG_CBIE
49
#define CSR_SENVCFG 0x10A
28
#define SENVCFG_CBCFE MENVCFG_CBCFE
50
29
#define SENVCFG_CBZE MENVCFG_CBZE
51
+/* Supervisor state CSRs */
30
+#define SENVCFG_UKTE BIT(8)
52
+#define CSR_SSTATEEN0 0x10C
31
53
+#define CSR_SSTATEEN1 0x10D
32
#define HENVCFG_FIOM MENVCFG_FIOM
54
+#define CSR_SSTATEEN2 0x10E
33
#define HENVCFG_LPE MENVCFG_LPE
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
34
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
106
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
107
--- a/target/riscv/csr.c
36
--- a/target/riscv/csr.c
108
+++ b/target/riscv/csr.c
37
+++ b/target/riscv/csr.c
109
@@ -XXX,XX +XXX,XX @@ static RISCVException umode32(CPURISCVState *env, int csrno)
38
@@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
110
return umode(env, csrno);
39
mask |= SENVCFG_SSE;
111
}
40
}
112
41
113
+static RISCVException mstateen(CPURISCVState *env, int csrno)
42
+ if (env_archcpu(env)->cfg.ext_svukte) {
114
+{
43
+ mask |= SENVCFG_UKTE;
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
+ }
44
+ }
121
+
45
+
122
+ return any(env, csrno);
46
env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
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;
47
return RISCV_EXCP_NONE;
184
}
48
}
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
--
49
--
486
2.38.1
50
2.47.1
diff view generated by jsdifflib
1
From: Anup Patel <apatel@ventanamicro.com>
1
From: "Fea.Wang" <fea.wang@sifive.com>
2
2
3
We should use "&&" instead of "&" when checking hcounteren.TM and
3
Svukte extension add HUKTE bit, bit[24] in hstatus CSR. The written
4
henvcfg.STCE bits.
4
value will be masked when the svukte extension is not enabled.
5
5
6
Fixes: 3ec0fe18a31f ("target/riscv: Add vstimecmp suppor")
6
When hstatus[HUKTE] bit is set, HLV/HLVX/HSV work in the U-mode should
7
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
7
do svukte check.
8
9
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
10
Reviewed-by: Frank Chang <frank.chang@sifive.com>
11
Reviewed-by: Jim Shu <jim.shu@sifive.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-Id: <20221108125703.1463577-2-apatel@ventanamicro.com>
14
Message-ID: <20241203034932.25185-4-fea.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
16
---
12
target/riscv/csr.c | 2 +-
17
target/riscv/cpu_bits.h | 1 +
13
1 file changed, 1 insertion(+), 1 deletion(-)
18
target/riscv/csr.c | 3 +++
19
2 files changed, 4 insertions(+)
14
20
21
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_bits.h
24
+++ b/target/riscv/cpu_bits.h
25
@@ -XXX,XX +XXX,XX @@ typedef enum {
26
#define HSTATUS_VTVM 0x00100000
27
#define HSTATUS_VTW 0x00200000
28
#define HSTATUS_VTSR 0x00400000
29
+#define HSTATUS_HUKTE 0x01000000
30
#define HSTATUS_VSXL 0x300000000
31
32
#define HSTATUS32_WPRI 0xFF8FF87E
15
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
33
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
16
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/csr.c
35
--- a/target/riscv/csr.c
18
+++ b/target/riscv/csr.c
36
+++ b/target/riscv/csr.c
19
@@ -XXX,XX +XXX,XX @@ static RISCVException sstc(CPURISCVState *env, int csrno)
37
@@ -XXX,XX +XXX,XX @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
20
}
38
static RISCVException write_hstatus(CPURISCVState *env, int csrno,
21
39
target_ulong val)
22
if (riscv_cpu_virt_enabled(env)) {
40
{
23
- if (!(get_field(env->hcounteren, COUNTEREN_TM) &
41
+ if (!env_archcpu(env)->cfg.ext_svukte) {
24
+ if (!(get_field(env->hcounteren, COUNTEREN_TM) &&
42
+ val = val & (~HSTATUS_HUKTE);
25
get_field(env->henvcfg, HENVCFG_STCE))) {
43
+ }
26
return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
44
env->hstatus = val;
27
}
45
if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
46
qemu_log_mask(LOG_UNIMP,
28
--
47
--
29
2.38.1
48
2.47.1
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: "Fea.Wang" <fea.wang@sifive.com>
2
2
3
Avoid calling riscv_itrigger_enabled() when calculate the tbflags.
3
Follow the Svukte spec, do the memory access address checking
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
4
8
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
5
1. Include instruction fetches or explicit memory accesses
6
2. System run in effective privilege U or VU
7
3. Check senvcfg[UKTE] being set, or hstatus[HUKTE] being set if
8
instruction is HLV, HLVX, HSV and execute from U mode to VU mode
9
4. Depend on Sv39 and check virtual addresses bit[SXLEN-1]
10
5. Raises a page-fault exception corresponding to the original access
11
type.
12
13
Ref: https://github.com/riscv/riscv-isa-manual/pull/1564/files
14
15
Signed-off-by: Frank Chang <frank.chang@sifive.com>
16
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
17
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
18
Reviewed-by: Jim Shu <jim.shu@sifive.com>
19
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221013062946.7530-5-zhiwei_liu@linux.alibaba.com>
21
Message-ID: <20241203034932.25185-5-fea.wang@sifive.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
23
---
13
target/riscv/cpu.h | 1 +
24
target/riscv/cpu_helper.c | 55 +++++++++++++++++++++++++++++++++++++++
14
target/riscv/cpu_helper.c | 3 +--
25
1 file changed, 55 insertions(+)
15
target/riscv/debug.c | 3 +++
16
target/riscv/machine.c | 15 +++++++++++++++
17
4 files changed, 20 insertions(+), 2 deletions(-)
18
26
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
27
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
32
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
33
--- a/target/riscv/cpu_helper.c
29
--- a/target/riscv/cpu_helper.c
34
+++ b/target/riscv/cpu_helper.c
30
+++ b/target/riscv/cpu_helper.c
35
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
31
@@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
36
get_field(env->mstatus_hs, MSTATUS_VS));
32
return TRANSLATE_SUCCESS;
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
}
33
}
82
34
83
+static int debug_post_load(void *opaque, int version_id)
35
+/* Returns 'true' if a svukte address check is needed */
36
+static bool do_svukte_check(CPURISCVState *env, bool first_stage,
37
+ int mode, bool virt)
84
+{
38
+{
85
+ RISCVCPU *cpu = opaque;
39
+ /* Svukte extension depends on Sv39. */
86
+ CPURISCVState *env = &cpu->env;
40
+ if (!(env_archcpu(env)->cfg.ext_svukte ||
87
+
41
+ !first_stage ||
88
+ if (icount_enabled()) {
42
+ VM_1_10_SV39 != get_field(env->satp, SATP64_MODE))) {
89
+ env->itrigger_enabled = riscv_itrigger_enabled(env);
43
+ return false;
90
+ }
44
+ }
91
+
45
+
92
+ return 0;
46
+ /*
47
+ * Check hstatus.HUKTE if the effective mode is switched to VU-mode by
48
+ * executing HLV/HLVX/HSV in U-mode.
49
+ * For other cases, check senvcfg.UKTE.
50
+ */
51
+ if (env->priv == PRV_U && !env->virt_enabled && virt) {
52
+ if (!get_field(env->hstatus, HSTATUS_HUKTE)) {
53
+ return false;
54
+ }
55
+ } else if (!get_field(env->senvcfg, SENVCFG_UKTE)) {
56
+ return false;
57
+ }
58
+
59
+ /*
60
+ * Svukte extension is qualified only in U or VU-mode.
61
+ *
62
+ * Effective mode can be switched to U or VU-mode by:
63
+ * - M-mode + mstatus.MPRV=1 + mstatus.MPP=U-mode.
64
+ * - Execute HLV/HLVX/HSV from HS-mode + hstatus.SPVP=0.
65
+ * - U-mode.
66
+ * - VU-mode.
67
+ * - Execute HLV/HLVX/HSV from U-mode + hstatus.HU=1.
68
+ */
69
+ if (mode != PRV_U) {
70
+ return false;
71
+ }
72
+
73
+ return true;
93
+}
74
+}
94
+
75
+
95
static const VMStateDescription vmstate_debug = {
76
+static bool check_svukte_addr(CPURISCVState *env, vaddr addr)
96
.name = "cpu/debug",
77
+{
97
.version_id = 2,
78
+ /* svukte extension excludes RV32 */
98
.minimum_version_id = 2,
79
+ uint32_t sxlen = 32 * riscv_cpu_sxl(env);
99
.needed = debug_needed,
80
+ uint64_t high_bit = addr & (1UL << (sxlen - 1));
100
+ .post_load = debug_post_load,
81
+ return !high_bit;
101
.fields = (VMStateField[]) {
82
+}
102
VMSTATE_UINTTL(env.trigger_cur, RISCVCPU),
83
+
103
VMSTATE_UINTTL_ARRAY(env.tdata1, RISCVCPU, RV_MAX_TRIGGERS),
84
/*
85
* get_physical_address - get the physical address for this virtual address
86
*
87
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
88
MemTxResult res;
89
MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
90
int mode = mmuidx_priv(mmu_idx);
91
+ bool virt = mmuidx_2stage(mmu_idx);
92
bool use_background = false;
93
hwaddr ppn;
94
int napot_bits = 0;
95
@@ -XXX,XX +XXX,XX @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
96
bool is_sstack_idx = ((mmu_idx & MMU_IDX_SS_WRITE) == MMU_IDX_SS_WRITE);
97
bool sstack_page = false;
98
99
+ if (do_svukte_check(env, first_stage, mode, virt) &&
100
+ !check_svukte_addr(env, addr)) {
101
+ return TRANSLATE_FAIL;
102
+ }
103
+
104
/*
105
* Check if we should use the background registers for the two
106
* stage translation. We don't need to check if we actually need
104
--
107
--
105
2.38.1
108
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: "Fea.Wang" <fea.wang@sifive.com>
2
2
3
sstatus register dump is currently missing in riscv_cpu_dump_state().
3
Add "svukte" in the ISA string when svukte extension is enabled.
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
4
7
Add some comments for this to let people know this is intentional.
5
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
8
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
9
Signed-off-by: Bin Meng <bmeng@tinylab.org>
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
10
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20221125050354.3166023-1-bmeng@tinylab.org>
9
Message-ID: <20241203034932.25185-6-fea.wang@sifive.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
11
---
14
target/riscv/cpu.c | 4 ++++
12
target/riscv/cpu.c | 2 ++
15
1 file changed, 4 insertions(+)
13
1 file changed, 2 insertions(+)
16
14
17
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu.c
17
--- a/target/riscv/cpu.c
20
+++ b/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
21
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
19
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
22
CSR_MHARTID,
20
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
23
CSR_MSTATUS,
21
ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
24
CSR_MSTATUSH,
22
ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
25
+ /*
23
+ ISA_EXT_DATA_ENTRY(svukte, PRIV_VERSION_1_13_0, ext_svukte),
26
+ * CSR_SSTATUS is intentionally omitted here as its value
24
ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
27
+ * can be figured out by looking at CSR_MSTATUS
25
ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
28
+ */
26
ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
29
CSR_HSTATUS,
27
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
30
CSR_VSSTATUS,
28
31
CSR_MIP,
29
/* These are experimental so mark with 'x-' */
30
const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
31
+ MULTI_EXT_CFG_BOOL("x-svukte", ext_svukte, false),
32
DEFINE_PROP_END_OF_LIST(),
33
};
34
32
--
35
--
33
2.38.1
36
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: "Fea.Wang" <fea.wang@sifive.com>
2
2
3
At present the default value of "num-sources" property is zero,
3
The spec explicitly says svukte doesn't support RV32. So check that it
4
which does not make a lot of sense, as in sifive_plic_realize()
4
is not enabled in RV32.
5
we see s->bitfield_words is calculated by:
6
5
7
s->bitfield_words = (s->num_sources + 31) >> 5;
6
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
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>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-Id: <20221211030829.802437-9-bmeng@tinylab.org>
8
Message-ID: <20241203034932.25185-7-fea.wang@sifive.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
10
---
24
hw/intc/sifive_plic.c | 8 +++++++-
11
target/riscv/tcg/tcg-cpu.c | 5 +++++
25
1 file changed, 7 insertions(+), 1 deletion(-)
12
1 file changed, 5 insertions(+)
26
13
27
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
14
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
28
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/intc/sifive_plic.c
16
--- a/target/riscv/tcg/tcg-cpu.c
30
+++ b/hw/intc/sifive_plic.c
17
+++ b/target/riscv/tcg/tcg-cpu.c
31
@@ -XXX,XX +XXX,XX @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
18
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
32
19
return;
33
parse_hart_config(s);
20
}
34
21
35
+ if (!s->num_sources) {
22
+ if (mcc->misa_mxl_max == MXL_RV32 && cpu->cfg.ext_svukte) {
36
+ error_setg(errp, "plic: invalid number of interrupt sources");
23
+ error_setg(errp, "svukte is not supported for RV32");
37
+ return;
24
+ return;
38
+ }
25
+ }
39
+
26
+
40
s->bitfield_words = (s->num_sources + 31) >> 5;
27
/*
41
s->num_enables = s->bitfield_words * s->num_addrs;
28
* Disable isa extensions based on priv spec after we
42
s->source_priority = g_new0(uint32_t, s->num_sources);
29
* validated and set everything we need.
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
--
30
--
54
2.38.1
31
2.47.1
diff view generated by jsdifflib
1
From: Bin Meng <bmeng@tinylab.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Since commit ef6310064820 ("hw/riscv: opentitan: Update to the latest build")
3
Rather than relying on implicit includes, explicit them,
4
the IBEX PLIC model was replaced with the SiFive PLIC model in the
4
in order to avoid when refactoring unrelated headers:
5
'opentitan' machine but we forgot the add the dependency there.
6
5
7
Signed-off-by: Bin Meng <bmeng@tinylab.org>
6
target/riscv/vector_internals.h:36:12: error: call to undeclared function 'FIELD_EX32'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
8
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
7
36 | return FIELD_EX32(simd_data(desc), VDATA, NF);
8
| ^
9
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221211030829.802437-3-bmeng@tinylab.org>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Message-ID: <20241203200828.47311-2-philmd@linaro.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
15
---
13
hw/riscv/Kconfig | 1 +
16
target/riscv/vector_internals.h | 1 +
14
1 file changed, 1 insertion(+)
17
1 file changed, 1 insertion(+)
15
18
16
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
19
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/riscv/Kconfig
21
--- a/target/riscv/vector_internals.h
19
+++ b/hw/riscv/Kconfig
22
+++ b/target/riscv/vector_internals.h
20
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
23
@@ -XXX,XX +XXX,XX @@
21
config OPENTITAN
24
#define TARGET_RISCV_VECTOR_INTERNALS_H
22
bool
25
23
select IBEX
26
#include "qemu/bitops.h"
24
+ select SIFIVE_PLIC
27
+#include "hw/registerfields.h"
25
select UNIMP
28
#include "cpu.h"
26
29
#include "tcg/tcg-gvec-desc.h"
27
config SHAKTI_C
30
#include "internals.h"
28
--
31
--
29
2.38.1
32
2.47.1
33
34
diff view generated by jsdifflib
1
From: Conor Dooley <conor.dooley@microchip.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
On PolarFire SoC, some peripherals (eg the PCI root port) are clocked by
3
Rather than relying on implicit includes, explicit them,
4
"Clock Conditioning Circuitry" in the FPGA. The specific clock depends
4
in order to avoid when refactoring unrelated headers:
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
5
8
Linux v6.1+ will have a driver for this peripheral and devicetrees that
6
target/riscv/internals.h:49:15: error: use of undeclared identifier 'PRV_S'
9
previously relied on "fixed-frequency" clock nodes have been switched
7
49 | ret = PRV_S;
10
over to clock-controller nodes. The IOSCB region is represented in QEMU,
8
| ^
11
but the specific region of it that the CCCs occupy has not so v6.1-rcN
9
target/riscv/internals.h:93:9: error: call to undeclared function 'env_archcpu'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
12
kernels fail to boot in QEMU.
10
93 | if (env_archcpu(env)->cfg.ext_zfinx) {
11
| ^
12
target/riscv/internals.h:101:15: error: unknown type name 'float32'; did you mean 'float'?
13
101 | static inline float32 check_nanbox_s(CPURISCVState *env, uint64_t f)
14
| ^~~~~~~
15
| float
13
16
14
Add the regions as unimplemented so that the status-quo in terms of boot
17
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
is maintained.
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
19
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
17
Acked-by: Alistair Francis <alistair.francis@wdc.com>
20
Message-ID: <20241203200828.47311-3-philmd@linaro.org>
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
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
---
22
include/hw/misc/mchp_pfsoc_ioscb.h | 1 +
23
target/riscv/internals.h | 3 +++
23
hw/misc/mchp_pfsoc_ioscb.c | 6 ++++++
24
1 file changed, 3 insertions(+)
24
2 files changed, 7 insertions(+)
25
25
26
diff --git a/include/hw/misc/mchp_pfsoc_ioscb.h b/include/hw/misc/mchp_pfsoc_ioscb.h
26
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
27
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
28
--- a/include/hw/misc/mchp_pfsoc_ioscb.h
28
--- a/target/riscv/internals.h
29
+++ b/include/hw/misc/mchp_pfsoc_ioscb.h
29
+++ b/target/riscv/internals.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 @@
30
@@ -XXX,XX +XXX,XX @@
43
*/
31
#ifndef RISCV_CPU_INTERNALS_H
44
#define IOSCB_WHOLE_REG_SIZE 0x10000000
32
#define RISCV_CPU_INTERNALS_H
45
#define IOSCB_SUBMOD_REG_SIZE 0x1000
33
46
+#define IOSCB_CCC_REG_SIZE 0x2000000
34
+#include "exec/cpu-common.h"
35
#include "hw/registerfields.h"
36
+#include "fpu/softfloat-types.h"
37
+#include "target/riscv/cpu_bits.h"
47
38
48
/*
39
/*
49
* There are many sub-modules in the IOSCB module.
40
* The current MMU Modes are:
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
--
41
--
70
2.38.1
42
2.47.1
43
44
diff view generated by jsdifflib
1
From: Mayuresh Chitale <mchitale@ventanamicro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
This patch adds a mechanism to generate a virtual instruction
3
Commit 68c9e54bea handled a situation where a warning was being shown
4
instruction exception instead of an illegal instruction exception
4
when using the 'sifive_e' cpu when disabling the named extension zic64b.
5
during instruction decode when virt is enabled.
5
It makes little sense to show user warnings for named extensions that
6
users can't control, and the solution taken was to disable zic64b
7
manually in riscv_cpu_update_named_features().
6
8
7
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
9
This solution won't scale well when adding more named features, and can
8
Reviewed-by: Weiwei Li <liweiwei@iscas.ac.cn>
10
eventually end up repeating riscv_cpu_disable_priv_spec_isa_exts().
11
12
Change riscv_cpu_disable_priv_spec_isa_exts() to not show warnings when
13
disabling a named feature. This will accomplish the same thing we're
14
doing today while avoiding having two points where we're disabling
15
exts via priv_ver mismatch.
16
17
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
10
Message-Id: <20221016124726.102129-4-mchitale@ventanamicro.com>
19
Message-ID: <20241113171755.978109-2-dbarboza@ventanamicro.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
21
---
13
target/riscv/translate.c | 8 +++++++-
22
target/riscv/tcg/tcg-cpu.c | 13 ++++++++++---
14
1 file changed, 7 insertions(+), 1 deletion(-)
23
1 file changed, 10 insertions(+), 3 deletions(-)
15
24
16
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
25
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
17
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
18
--- a/target/riscv/translate.c
27
--- a/target/riscv/tcg/tcg-cpu.c
19
+++ b/target/riscv/translate.c
28
+++ b/target/riscv/tcg/tcg-cpu.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
29
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
21
to reset this known value. */
30
}
22
int frm;
31
23
RISCVMXL ol;
32
isa_ext_update_enabled(cpu, edata->ext_enable_offset, false);
24
+ bool virt_inst_excp;
33
+
25
bool virt_enabled;
34
+ /*
26
const RISCVCPUConfig *cfg_ptr;
35
+ * Do not show user warnings for named features that users
27
bool hlsx;
36
+ * can't enable/disable in the command line. See commit
28
@@ -XXX,XX +XXX,XX @@ static void gen_exception_illegal(DisasContext *ctx)
37
+ * 68c9e54bea for more info.
29
{
38
+ */
30
tcg_gen_st_i32(tcg_constant_i32(ctx->opcode), cpu_env,
39
+ if (cpu_cfg_offset_is_named_feat(edata->ext_enable_offset)) {
31
offsetof(CPURISCVState, bins));
40
+ continue;
32
- generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
41
+ }
33
+ if (ctx->virt_inst_excp) {
42
#ifndef CONFIG_USER_ONLY
34
+ generate_exception(ctx, RISCV_EXCP_VIRT_INSTRUCTION_FAULT);
43
warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
35
+ } else {
44
" because privilege spec version does not match",
36
+ generate_exception(ctx, RISCV_EXCP_ILLEGAL_INST);
45
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
37
+ }
46
cpu->cfg.has_priv_1_13 = true;
47
}
48
49
- /* zic64b is 1.12 or later */
50
cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 &&
51
cpu->cfg.cbop_blocksize == 64 &&
52
- cpu->cfg.cboz_blocksize == 64 &&
53
- cpu->cfg.has_priv_1_12;
54
+ cpu->cfg.cboz_blocksize == 64;
38
}
55
}
39
56
40
static void gen_exception_inst_addr_mis(DisasContext *ctx)
57
static void riscv_cpu_validate_g(RISCVCPU *cpu)
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
--
58
--
50
2.38.1
59
2.47.1
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
When guest_base != 0, we were not coordinating the usage of
3
ssstateen is defined in RVA22 as:
4
TCG_REG_TMP0 as base properly, leading to a previous zero-extend
5
of the input address being discarded.
6
4
7
Shuffle the alignment check to the front, because that does not
5
"Supervisor-mode view of the state-enable extension. The supervisor-mode
8
depend on the zero-extend, and it keeps the register usage clear.
6
(sstateen0-3) and hypervisor-mode (hstateen0-3) state-enable registers
9
Set base after each step of the address arithmetic instead of before.
7
must be provided."
10
8
11
Return the base register used from tcg_out_tlb_load, so as to
9
Add ssstateen as a named feature that is available if we also have
12
keep that register choice localized to that function.
10
smstateen.
13
11
14
Reported-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
16
Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
14
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
17
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-ID: <20241113171755.978109-3-dbarboza@ventanamicro.com>
18
Message-Id: <20221023233337.2846860-1-richard.henderson@linaro.org>
19
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
20
---
17
---
21
tcg/riscv/tcg-target.c.inc | 39 +++++++++++++++++++++-----------------
18
target/riscv/cpu_cfg.h | 1 +
22
1 file changed, 22 insertions(+), 17 deletions(-)
19
target/riscv/cpu.c | 2 ++
20
target/riscv/tcg/tcg-cpu.c | 9 ++++++++-
21
3 files changed, 11 insertions(+), 1 deletion(-)
23
22
24
diff --git a/tcg/riscv/tcg-target.c.inc b/tcg/riscv/tcg-target.c.inc
23
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
25
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
26
--- a/tcg/riscv/tcg-target.c.inc
25
--- a/target/riscv/cpu_cfg.h
27
+++ b/tcg/riscv/tcg-target.c.inc
26
+++ b/target/riscv/cpu_cfg.h
28
@@ -XXX,XX +XXX,XX @@ static void tcg_out_goto(TCGContext *s, const tcg_insn_unit *target)
27
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
29
tcg_debug_assert(ok);
28
/* Named features */
29
bool ext_svade;
30
bool ext_zic64b;
31
+ bool ext_ssstateen;
32
33
/*
34
* Always 'true' booleans for named features
35
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/riscv/cpu.c
38
+++ b/target/riscv/cpu.c
39
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
40
ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
41
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
42
ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
43
+ ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
44
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
45
ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
46
ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
47
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
48
*/
49
const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
50
MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
51
+ MULTI_EXT_CFG_BOOL("ssstateen", ext_ssstateen, true),
52
53
DEFINE_PROP_END_OF_LIST(),
54
};
55
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
56
index XXXXXXX..XXXXXXX 100644
57
--- a/target/riscv/tcg/tcg-cpu.c
58
+++ b/target/riscv/tcg/tcg-cpu.c
59
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset)
60
* All other named features are already enabled
61
* in riscv_tcg_cpu_instance_init().
62
*/
63
- if (feat_offset == CPU_CFG_OFFSET(ext_zic64b)) {
64
+ switch (feat_offset) {
65
+ case CPU_CFG_OFFSET(ext_zic64b):
66
cpu->cfg.cbom_blocksize = 64;
67
cpu->cfg.cbop_blocksize = 64;
68
cpu->cfg.cboz_blocksize = 64;
69
+ break;
70
+ case CPU_CFG_OFFSET(ext_ssstateen):
71
+ cpu->cfg.ext_smstateen = true;
72
+ break;
73
}
30
}
74
}
31
75
32
-static void tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
76
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
33
- TCGReg addrh, MemOpIdx oi,
77
cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 &&
34
- tcg_insn_unit **label_ptr, bool is_load)
78
cpu->cfg.cbop_blocksize == 64 &&
35
+static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addrl,
79
cpu->cfg.cboz_blocksize == 64;
36
+ TCGReg addrh, MemOpIdx oi,
80
+
37
+ tcg_insn_unit **label_ptr, bool is_load)
81
+ cpu->cfg.ext_ssstateen = cpu->cfg.ext_smstateen;
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
}
82
}
47
83
48
static void add_qemu_ldst_label(TCGContext *s, int is_ld, MemOpIdx oi,
84
static void riscv_cpu_validate_g(RISCVCPU *cpu)
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
--
85
--
132
2.38.1
86
2.47.1
diff view generated by jsdifflib
1
From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
1
From: MollyChen <xiaoou@iscas.ac.cn>
2
2
3
When QEMU is not in icount mode, execute instruction one by one. The
3
Add a CPU entry for the RV64 XiangShan NANHU CPU which
4
tdata1 can be read directly.
4
supports single-core and dual-core configurations. More
5
details can be found at
6
https://docs.xiangshan.cc/zh-cn/latest/integration/overview
5
7
6
When QEMU is in icount mode, use a timer to simulate the itrigger. The
8
Signed-off-by: MollyChen <xiaoou@iscas.ac.cn>
7
tdata1 may be not right because of lazy update of count in tdata1. Thus,
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
8
We should pack the adjusted count into tdata1 before read it back.
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
9
11
Message-ID: <20241205073622.46052-1-xiaoou@iscas.ac.cn>
10
Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com>
12
[ Changes by AF
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
- Fixup code formatting
12
Message-Id: <20221013062946.7530-4-zhiwei_liu@linux.alibaba.com>
14
]
13
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
14
---
16
---
15
target/riscv/debug.c | 72 ++++++++++++++++++++++++++++++++++++++++++++
17
target/riscv/cpu-qom.h | 1 +
16
1 file changed, 72 insertions(+)
18
target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
19
2 files changed, 31 insertions(+)
17
20
18
diff --git a/target/riscv/debug.c b/target/riscv/debug.c
21
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/target/riscv/debug.c
23
--- a/target/riscv/cpu-qom.h
21
+++ b/target/riscv/debug.c
24
+++ b/target/riscv/cpu-qom.h
22
@@ -XXX,XX +XXX,XX @@ void riscv_itrigger_update_priv(CPURISCVState *env)
25
@@ -XXX,XX +XXX,XX @@
23
riscv_itrigger_update_count(env);
26
#define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906")
27
#define TYPE_RISCV_CPU_VEYRON_V1 RISCV_CPU_TYPE_NAME("veyron-v1")
28
#define TYPE_RISCV_CPU_TT_ASCALON RISCV_CPU_TYPE_NAME("tt-ascalon")
29
+#define TYPE_RISCV_CPU_XIANGSHAN_NANHU RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
30
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
31
32
OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/cpu.c
36
+++ b/target/riscv/cpu.c
37
@@ -XXX,XX +XXX,XX @@ static void rv64_tt_ascalon_cpu_init(Object *obj)
38
#endif
24
}
39
}
25
40
26
+static target_ulong itrigger_validate(CPURISCVState *env,
41
+static void rv64_xiangshan_nanhu_cpu_init(Object *obj)
27
+ target_ulong ctrl)
28
+{
42
+{
29
+ target_ulong val;
43
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
44
+ RISCVCPU *cpu = RISCV_CPU(obj);
30
+
45
+
31
+ /* validate the generic part first */
46
+ riscv_cpu_set_misa_ext(env, RVG | RVC | RVB | RVS | RVU);
32
+ val = tdata1_validate(env, ctrl, TRIGGER_TYPE_INST_CNT);
47
+ env->priv_ver = PRIV_VERSION_1_12_0;
33
+
48
+
34
+ /* validate unimplemented (always zero) bits */
49
+ /* Enable ISA extensions */
35
+ warn_always_zero_bit(ctrl, ITRIGGER_ACTION, "action");
50
+ cpu->cfg.ext_zbc = true;
36
+ warn_always_zero_bit(ctrl, ITRIGGER_HIT, "hit");
51
+ cpu->cfg.ext_zbkb = true;
37
+ warn_always_zero_bit(ctrl, ITRIGGER_PENDING, "pending");
52
+ cpu->cfg.ext_zbkc = true;
53
+ cpu->cfg.ext_zbkx = true;
54
+ cpu->cfg.ext_zknd = true;
55
+ cpu->cfg.ext_zkne = true;
56
+ cpu->cfg.ext_zknh = true;
57
+ cpu->cfg.ext_zksed = true;
58
+ cpu->cfg.ext_zksh = true;
59
+ cpu->cfg.ext_svinval = true;
38
+
60
+
39
+ /* keep the mode and attribute bits */
61
+ cpu->cfg.mmu = true;
40
+ val |= ctrl & (ITRIGGER_VU | ITRIGGER_VS | ITRIGGER_U | ITRIGGER_S |
62
+ cpu->cfg.pmp = true;
41
+ ITRIGGER_M | ITRIGGER_COUNT);
42
+
63
+
43
+ return val;
64
+#ifndef CONFIG_USER_ONLY
65
+ set_satp_mode_max_supported(cpu, VM_1_10_SV39);
66
+#endif
44
+}
67
+}
45
+
68
+
46
+static void itrigger_reg_write(CPURISCVState *env, target_ulong index,
69
#ifdef CONFIG_TCG
47
+ int tdata_index, target_ulong val)
70
static void rv128_base_cpu_init(Object *obj)
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
{
71
{
92
+ int trigger_type;
72
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
93
switch (tdata_index) {
73
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64, rv64_thead_c906_cpu_init),
94
case TDATA1:
74
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64, rv64_tt_ascalon_cpu_init),
95
+ trigger_type = extract_trigger_type(env, env->tdata1[env->trigger_cur]);
75
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, MXL_RV64, rv64_veyron_v1_cpu_init),
96
+ if ((trigger_type == TRIGGER_TYPE_INST_CNT) && icount_enabled()) {
76
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU,
97
+ return deposit64(env->tdata1[env->trigger_cur], 10, 14,
77
+ MXL_RV64, rv64_xiangshan_nanhu_cpu_init),
98
+ itrigger_get_adjust_count(env));
78
#ifdef CONFIG_TCG
99
+ }
79
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, MXL_RV128, rv128_base_cpu_init),
100
return env->tdata1[env->trigger_cur];
80
#endif /* CONFIG_TCG */
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
--
81
--
113
2.38.1
82
2.47.1
diff view generated by jsdifflib
Deleted patch
1
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
2
1
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
Deleted patch
1
From: Bin Meng <bmeng@tinylab.org>
2
1
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