1
From: Alistair Francis <alistair.francis@wdc.com>
1
The following changes since commit 8032c78e556cd0baec111740a6c636863f9bd7c8:
2
2
3
The following changes since commit 284c52eec2d0a1b9c47f06c3eee46762c5fc0915:
3
Merge tag 'firmware-20241216-pull-request' of https://gitlab.com/kraxel/qemu into staging (2024-12-16 14:20:33 -0500)
4
5
Merge tag 'win-socket-pull-request' of https://gitlab.com/marcandre.lureau/qemu into staging (2023-03-13 13:44:17 +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-20230314
7
https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20241219-1
10
8
11
for you to fetch changes up to 0d581506de803204c5a321100afa270573382932:
9
for you to fetch changes up to 5632d271be16b5e769342d54198c4359658abcb7:
12
10
13
Fix incorrect register name in disassembler for fmv,fabs,fneg instructions (2023-03-14 16:36:43 +1000)
11
target/riscv: add support for RV64 Xiangshan Nanhu CPU (2024-12-18 11:07:59 +1000)
14
12
15
----------------------------------------------------------------
13
----------------------------------------------------------------
16
Seventh RISC-V PR for 8.0
14
RISC-V PR for 10.0
17
15
18
* Fix slli_uw decoding
16
* Correct the validness check of iova
19
* Fix incorrect register name in disassembler for fmv,fabs,fneg instructions
17
* Fix APLIC in_clrip and clripnum write emulation
18
* Support riscv-iommu-sys device
19
* Add Tenstorrent Ascalon CPU
20
* Add AIA userspace irqchip_split support
21
* Add Microblaze V generic board
22
* Upgrade ACPI SPCR table to support SPCR table revision 4 format
23
* Remove tswap64() calls from HTIF
24
* Support 64-bit address of initrd
25
* Introduce svukte ISA extension
26
* Support ssstateen extension
27
* Support for RV64 Xiangshan Nanhu CPU
20
28
21
----------------------------------------------------------------
29
----------------------------------------------------------------
22
Ivan Klokov (1):
30
Anton Blanchard (1):
23
disas/riscv: Fix slli_uw decoding
31
target/riscv: Add Tenstorrent Ascalon CPU
24
32
25
Mikhail Tyutin (1):
33
Daniel Henrique Barboza (15):
26
Fix incorrect register name in disassembler for fmv,fabs,fneg instructions
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
27
49
28
disas/riscv.c | 27 ++++++++++++++-------------
50
Fea.Wang (6):
29
1 file changed, 14 insertions(+), 13 deletions(-)
51
target/riscv: Add svukte extension capability variable
52
target/riscv: Support senvcfg[UKTE] bit when svukte extension is enabled
53
target/riscv: Support hstatus[HUKTE] bit when svukte extension is enabled
54
target/riscv: Check memory access to meet svukte rule
55
target/riscv: Expose svukte ISA extension
56
target/riscv: Check svukte is not enabled in RV32
57
58
Jason Chien (1):
59
hw/riscv/riscv-iommu.c: Correct the validness check of iova
60
61
Jim Shu (3):
62
hw/riscv: Support to load DTB after 3GB memory on 64-bit system.
63
hw/riscv: Add a new struct RISCVBootInfo
64
hw/riscv: Add the checking if DTB overlaps to kernel or initrd
65
66
MollyChen (1):
67
target/riscv: add support for RV64 Xiangshan Nanhu CPU
68
69
Philippe Mathieu-Daudé (5):
70
MAINTAINERS: Cover RISC-V HTIF interface
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
76
Sai Pavan Boddu (1):
77
hw/riscv: Add Microblaze V generic board
78
79
Sia Jee Heng (3):
80
qtest: allow SPCR acpi table changes
81
hw/acpi: Upgrade ACPI SPCR table to support SPCR table revision 4 format
82
tests/qtest/bios-tables-test: Update virt SPCR golden reference for RISC-V
83
84
Sunil V L (1):
85
hw/riscv/virt: Add IOMMU as platform device if the option is set
86
87
Tomasz Jeznach (1):
88
hw/riscv: add riscv-iommu-sys platform device
89
90
Yong-Xuan Wang (1):
91
hw/intc/riscv_aplic: Fix APLIC in_clrip and clripnum write emulation
92
93
MAINTAINERS | 8 +
94
docs/specs/index.rst | 1 +
95
docs/specs/riscv-aia.rst | 83 ++++++++++
96
docs/specs/riscv-iommu.rst | 30 +++-
97
docs/system/riscv/microblaze-v-generic.rst | 42 +++++
98
docs/system/riscv/virt.rst | 17 ++
99
docs/system/target-riscv.rst | 1 +
100
hw/riscv/riscv-iommu-bits.h | 6 +
101
hw/riscv/riscv-iommu.h | 5 +
102
include/hw/acpi/acpi-defs.h | 7 +-
103
include/hw/acpi/aml-build.h | 2 +-
104
include/hw/intc/riscv_aplic.h | 8 +
105
include/hw/riscv/boot.h | 28 +++-
106
include/hw/riscv/iommu.h | 10 +-
107
include/hw/riscv/virt.h | 6 +-
108
target/riscv/cpu-qom.h | 2 +
109
target/riscv/cpu_bits.h | 2 +
110
target/riscv/cpu_cfg.h | 2 +
111
target/riscv/internals.h | 3 +
112
target/riscv/vector_internals.h | 1 +
113
hw/acpi/aml-build.c | 20 ++-
114
hw/arm/virt-acpi-build.c | 8 +-
115
hw/char/riscv_htif.c | 15 +-
116
hw/intc/riscv_aplic.c | 74 +++++++--
117
hw/loongarch/acpi-build.c | 6 +-
118
hw/riscv/boot.c | 100 +++++++----
119
hw/riscv/microblaze-v-generic.c | 184 +++++++++++++++++++++
120
hw/riscv/microchip_pfsoc.c | 13 +-
121
hw/riscv/opentitan.c | 4 +-
122
hw/riscv/riscv-iommu-pci.c | 21 +++
123
hw/riscv/riscv-iommu-sys.c | 256 +++++++++++++++++++++++++++++
124
hw/riscv/riscv-iommu.c | 137 ++++++++++-----
125
hw/riscv/sifive_e.c | 4 +-
126
hw/riscv/sifive_u.c | 18 +-
127
hw/riscv/spike.c | 14 +-
128
hw/riscv/virt-acpi-build.c | 12 +-
129
hw/riscv/virt.c | 159 +++++++++++++++---
130
target/riscv/cpu.c | 101 ++++++++++++
131
target/riscv/cpu_helper.c | 55 +++++++
132
target/riscv/csr.c | 7 +
133
target/riscv/kvm/kvm-cpu.c | 43 ++---
134
target/riscv/tcg/tcg-cpu.c | 27 ++-
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
New patch
1
From: Jason Chien <jason.chien@sifive.com>
1
2
3
From RISCV IOMMU spec section 2.1.3:
4
When SXL is 1, the following rules apply:
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.
10
11
From RISCV IOMMU spec section 2.3 step 17:
12
Use the process specified in Section "Two-Stage Address Translation" of
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>
30
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
31
---
32
hw/riscv/riscv-iommu.c | 23 ++++++++++++++++++++---
33
1 file changed, 20 insertions(+), 3 deletions(-)
34
35
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/hw/riscv/riscv-iommu.c
38
+++ b/hw/riscv/riscv-iommu.c
39
@@ -XXX,XX +XXX,XX @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx,
40
41
/* Address range check before first level lookup */
42
if (!sc[pass].step) {
43
- const uint64_t va_mask = (1ULL << (va_skip + va_bits)) - 1;
44
- if ((addr & va_mask) != addr) {
45
- return RISCV_IOMMU_FQ_CAUSE_DMA_DISABLED;
46
+ const uint64_t va_len = va_skip + va_bits;
47
+ const uint64_t va_mask = (1ULL << va_len) - 1;
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
}
67
}
68
69
--
70
2.47.1
diff view generated by jsdifflib
New patch
1
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
1
2
3
In the section "4.7 Precise effects on interrupt-pending bits"
4
of the RISC-V AIA specification defines that:
5
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."
11
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>
16
Acked-by: Alistair Francis <alistair.francis@wdc.com>
17
Message-ID: <20241029085349.30412-1-yongxuan.wang@sifive.com>
18
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
19
---
20
hw/intc/riscv_aplic.c | 6 +++++-
21
1 file changed, 5 insertions(+), 1 deletion(-)
22
23
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
24
index XXXXXXX..XXXXXXX 100644
25
--- a/hw/intc/riscv_aplic.c
26
+++ b/hw/intc/riscv_aplic.c
27
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic,
28
29
if ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) ||
30
(sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
31
- if (!aplic->msimode || (aplic->msimode && !pending)) {
32
+ if (!aplic->msimode) {
33
return;
34
}
35
+ if (aplic->msimode && !pending) {
36
+ goto noskip_write_pending;
37
+ }
38
if ((aplic->state[irq] & APLIC_ISTATE_INPUT) &&
39
(sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) {
40
return;
41
@@ -XXX,XX +XXX,XX @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic,
42
}
43
}
44
45
+noskip_write_pending:
46
riscv_aplic_set_pending_raw(aplic, irq, pending);
47
}
48
49
--
50
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Move all the static initializion of the device to an init() function,
4
leaving only the dynamic initialization to be done during realize.
5
6
With this change s->cap is initialized with RISCV_IOMMU_CAP_DBG during
7
init(), and realize() will increment s->cap with the extra caps.
8
9
This will allow callers to add IOMMU capabilities before the
10
realization.
11
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20241106133407.604587-2-dbarboza@ventanamicro.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
hw/riscv/riscv-iommu.c | 71 +++++++++++++++++++++++-------------------
18
1 file changed, 39 insertions(+), 32 deletions(-)
19
20
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/hw/riscv/riscv-iommu.c
23
+++ b/hw/riscv/riscv-iommu.c
24
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps riscv_iommu_trap_ops = {
25
}
26
};
27
28
+static void riscv_iommu_instance_init(Object *obj)
29
+{
30
+ RISCVIOMMUState *s = RISCV_IOMMU(obj);
31
+
32
+ /* Enable translation debug interface */
33
+ s->cap = RISCV_IOMMU_CAP_DBG;
34
+
35
+ /* Report QEMU target physical address space limits */
36
+ s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS,
37
+ TARGET_PHYS_ADDR_SPACE_BITS);
38
+
39
+ /* TODO: method to report supported PID bits */
40
+ s->pid_bits = 8; /* restricted to size of MemTxAttrs.pid */
41
+ s->cap |= RISCV_IOMMU_CAP_PD8;
42
+
43
+ /* register storage */
44
+ s->regs_rw = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
45
+ s->regs_ro = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
46
+ s->regs_wc = g_new0(uint8_t, RISCV_IOMMU_REG_SIZE);
47
+
48
+ /* Mark all registers read-only */
49
+ memset(s->regs_ro, 0xff, RISCV_IOMMU_REG_SIZE);
50
+
51
+ /* Device translation context cache */
52
+ s->ctx_cache = g_hash_table_new_full(riscv_iommu_ctx_hash,
53
+ riscv_iommu_ctx_equal,
54
+ g_free, NULL);
55
+
56
+ s->iot_cache = g_hash_table_new_full(riscv_iommu_iot_hash,
57
+ riscv_iommu_iot_equal,
58
+ g_free, NULL);
59
+
60
+ s->iommus.le_next = NULL;
61
+ s->iommus.le_prev = NULL;
62
+ QLIST_INIT(&s->spaces);
63
+}
64
+
65
static void riscv_iommu_realize(DeviceState *dev, Error **errp)
66
{
67
RISCVIOMMUState *s = RISCV_IOMMU(dev);
68
69
- s->cap = s->version & RISCV_IOMMU_CAP_VERSION;
70
+ s->cap |= s->version & RISCV_IOMMU_CAP_VERSION;
71
if (s->enable_msi) {
72
s->cap |= RISCV_IOMMU_CAP_MSI_FLAT | RISCV_IOMMU_CAP_MSI_MRIF;
73
}
74
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_realize(DeviceState *dev, Error **errp)
75
s->cap |= RISCV_IOMMU_CAP_SV32X4 | RISCV_IOMMU_CAP_SV39X4 |
76
RISCV_IOMMU_CAP_SV48X4 | RISCV_IOMMU_CAP_SV57X4;
77
}
78
- /* Enable translation debug interface */
79
- s->cap |= RISCV_IOMMU_CAP_DBG;
80
-
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,
130
};
131
132
--
133
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Interrupt Generation Support (IGS) is a capability that is tied to the
4
interrupt deliver mechanism, not with the core IOMMU emulation. We
5
should allow device implementations to set IGS as they wish.
6
7
A new helper is added to make it easier for device impls to set IGS. Use
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>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20241106133407.604587-3-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
hw/riscv/riscv-iommu-bits.h | 6 ++++++
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(+)
21
22
diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/riscv/riscv-iommu-bits.h
25
+++ b/hw/riscv/riscv-iommu-bits.h
26
@@ -XXX,XX +XXX,XX @@ struct riscv_iommu_pq_record {
27
#define RISCV_IOMMU_CAP_PD17 BIT_ULL(39)
28
#define RISCV_IOMMU_CAP_PD20 BIT_ULL(40)
29
30
+enum riscv_iommu_igs_modes {
31
+ RISCV_IOMMU_CAP_IGS_MSI = 0,
32
+ RISCV_IOMMU_CAP_IGS_WSI,
33
+ RISCV_IOMMU_CAP_IGS_BOTH
34
+};
35
+
36
/* 5.4 Features control register (32bits) */
37
#define RISCV_IOMMU_REG_FCTL 0x0008
38
#define RISCV_IOMMU_FCTL_BE BIT(0)
39
diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/riscv/riscv-iommu.h
42
+++ b/hw/riscv/riscv-iommu.h
43
@@ -XXX,XX +XXX,XX @@
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);
89
--
90
2.47.1
diff view generated by jsdifflib
New patch
1
1
From: Tomasz Jeznach <tjeznach@rivosinc.com>
2
3
This device models the RISC-V IOMMU as a sysbus device. The same design
4
decisions taken in the riscv-iommu-pci device were kept, namely the
5
existence of 4 vectors are available for each interrupt cause.
6
7
The WSIs are emitted using the input of the s->notify() callback as a
8
index to an IRQ list. The IRQ list starts at 'base_irq' and goes until
9
base_irq + 3. This means that boards must have 4 contiguous IRQ lines
10
available, starting from 'base_irq'.
11
12
Signed-off-by: Tomasz Jeznach <tjeznach@rivosinc.com>
13
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-ID: <20241106133407.604587-4-dbarboza@ventanamicro.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
include/hw/riscv/iommu.h | 4 ++
19
hw/riscv/riscv-iommu-sys.c | 128 +++++++++++++++++++++++++++++++++++++
20
hw/riscv/riscv-iommu.c | 3 +-
21
hw/riscv/meson.build | 2 +-
22
4 files changed, 134 insertions(+), 3 deletions(-)
23
create mode 100644 hw/riscv/riscv-iommu-sys.c
24
25
diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/riscv/iommu.h
28
+++ b/include/hw/riscv/iommu.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUSpace RISCVIOMMUSpace;
30
OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI)
31
typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci;
32
33
+#define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device"
34
+OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS)
35
+typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys;
36
+
37
#endif
38
diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
39
new file mode 100644
40
index XXXXXXX..XXXXXXX
41
--- /dev/null
42
+++ b/hw/riscv/riscv-iommu-sys.c
43
@@ -XXX,XX +XXX,XX @@
44
+/*
45
+ * QEMU emulation of an RISC-V IOMMU Platform Device
46
+ *
47
+ * Copyright (C) 2022-2023 Rivos Inc.
48
+ *
49
+ * This program is free software; you can redistribute it and/or modify it
50
+ * under the terms and conditions of the GNU General Public License,
51
+ * version 2 or later, as published by the Free Software Foundation.
52
+ *
53
+ * This program is distributed in the hope that it will be useful,
54
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
56
+ * GNU General Public License for more details.
57
+ *
58
+ * You should have received a copy of the GNU General Public License along
59
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
60
+ */
61
+
62
+#include "qemu/osdep.h"
63
+#include "hw/irq.h"
64
+#include "hw/pci/pci_bus.h"
65
+#include "hw/qdev-properties.h"
66
+#include "hw/sysbus.h"
67
+#include "qapi/error.h"
68
+#include "qemu/error-report.h"
69
+#include "qemu/host-utils.h"
70
+#include "qemu/module.h"
71
+#include "qom/object.h"
72
+
73
+#include "riscv-iommu.h"
74
+
75
+#define RISCV_IOMMU_SYSDEV_ICVEC_VECTORS 0x3333
76
+
77
+/* RISC-V IOMMU System Platform Device Emulation */
78
+
79
+struct RISCVIOMMUStateSys {
80
+ SysBusDevice parent;
81
+ uint64_t addr;
82
+ uint32_t base_irq;
83
+ DeviceState *irqchip;
84
+ RISCVIOMMUState iommu;
85
+ qemu_irq irqs[RISCV_IOMMU_INTR_COUNT];
86
+};
87
+
88
+static void riscv_iommu_sysdev_notify(RISCVIOMMUState *iommu,
89
+ unsigned vector)
90
+{
91
+ RISCVIOMMUStateSys *s = container_of(iommu, RISCVIOMMUStateSys, iommu);
92
+ uint32_t fctl = riscv_iommu_reg_get32(iommu, RISCV_IOMMU_REG_FCTL);
93
+
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}
200
--
201
2.47.1
diff view generated by jsdifflib
New patch
1
1
From: Sunil V L <sunilvl@ventanamicro.com>
2
3
Add a new machine option called 'iommu-sys' that enables a
4
riscv-iommu-sys platform device for the 'virt' machine. The option is
5
default 'off'.
6
7
The device will use IRQs 36 to 39.
8
9
We will not support both riscv-iommu-sys and riscv-iommu-pci devices in
10
the same board in this first implementation. If a riscv-iommu-pci device
11
is added in the command line we will disable the riscv-iommu-sys device.
12
13
Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
14
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
16
Message-ID: <20241106133407.604587-5-dbarboza@ventanamicro.com>
17
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
18
---
19
include/hw/riscv/iommu.h | 2 +
20
include/hw/riscv/virt.h | 6 ++-
21
hw/riscv/virt.c | 104 ++++++++++++++++++++++++++++++++++++++-
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
35
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/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 {
57
@@ -XXX,XX +XXX,XX @@ enum {
58
VIRTIO_IRQ = 1, /* 1 to 8 */
59
VIRTIO_COUNT = 8,
60
PCIE_IRQ = 0x20, /* 32 to 35 */
61
+ IOMMU_SYS_IRQ = 0x24, /* 36-39 */
62
VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 95 */
63
};
64
65
@@ -XXX,XX +XXX,XX @@ enum {
66
1 + FDT_APLIC_INT_CELLS)
67
68
bool virt_is_acpi_enabled(RISCVVirtState *s);
69
+bool virt_is_iommu_sys_enabled(RISCVVirtState *s);
70
void virt_acpi_setup(RISCVVirtState *vms);
71
uint32_t imsic_num_bits(uint32_t count);
72
73
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/riscv/virt.c
76
+++ b/hw/riscv/virt.c
77
@@ -XXX,XX +XXX,XX @@
78
#include "target/riscv/pmu.h"
79
#include "hw/riscv/riscv_hart.h"
80
#include "hw/riscv/iommu.h"
81
+#include "hw/riscv/riscv-iommu-bits.h"
82
#include "hw/riscv/virt.h"
83
#include "hw/riscv/boot.h"
84
#include "hw/riscv/numa.h"
85
@@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = {
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 = {
276
--
277
2.47.1
diff view generated by jsdifflib
New patch
1
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
MSIx support is added in the RISC-V IOMMU platform device by including
4
the required MSIx facilities to alow software to properly setup the MSIx
5
subsystem.
6
7
We took inspiration of what is being done in the riscv-iommu-pci device,
8
mainly msix_init() and msix_notify(), while keeping in mind that
9
riscv-iommu-sys isn't a true PCI device and we don't need to copy/paste
10
all the contents of these MSIx functions.
11
12
Two extra MSI MemoryRegions were added: 'msix-table' and 'msix-pba'.
13
They are used to manage r/w of the MSI table and Pending Bit Array (PBA)
14
respectively. Both are subregions of the main IOMMU memory region,
15
iommu->regs_mr, initialized during riscv_iommu_realize(), and each one
16
has their own handlers for MSIx reads and writes.
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
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
35
---
36
hw/riscv/riscv-iommu-sys.c | 116 +++++++++++++++++++++++++++++++++++--
37
hw/riscv/virt.c | 6 +-
38
hw/riscv/trace-events | 2 +
39
3 files changed, 119 insertions(+), 5 deletions(-)
40
41
diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/riscv/riscv-iommu-sys.c
44
+++ b/hw/riscv/riscv-iommu-sys.c
45
@@ -XXX,XX +XXX,XX @@
46
#include "qemu/host-utils.h"
47
#include "qemu/module.h"
48
#include "qom/object.h"
49
+#include "exec/exec-all.h"
50
+#include "trace.h"
51
52
#include "riscv-iommu.h"
53
54
#define RISCV_IOMMU_SYSDEV_ICVEC_VECTORS 0x3333
55
56
+#define RISCV_IOMMU_PCI_MSIX_VECTORS 5
57
+
58
/* RISC-V IOMMU System Platform Device Emulation */
59
60
struct RISCVIOMMUStateSys {
61
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUStateSys {
62
uint32_t base_irq;
63
DeviceState *irqchip;
64
RISCVIOMMUState iommu;
65
+
66
+ /* Wired int support */
67
qemu_irq irqs[RISCV_IOMMU_INTR_COUNT];
68
+
69
+ /* Memory Regions for MSIX table and pending bit entries. */
70
+ MemoryRegion msix_table_mmio;
71
+ MemoryRegion msix_pba_mmio;
72
+ uint8_t *msix_table;
73
+ uint8_t *msix_pba;
74
+};
75
+
76
+static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr,
77
+ unsigned size)
78
+{
79
+ RISCVIOMMUStateSys *s = opaque;
80
+
81
+ g_assert(addr + size <= RISCV_IOMMU_PCI_MSIX_VECTORS * PCI_MSIX_ENTRY_SIZE);
82
+ return pci_get_long(s->msix_table + addr);
83
+}
84
+
85
+static void msix_table_mmio_write(void *opaque, hwaddr addr,
86
+ uint64_t val, unsigned size)
87
+{
88
+ RISCVIOMMUStateSys *s = opaque;
89
+
90
+ g_assert(addr + size <= RISCV_IOMMU_PCI_MSIX_VECTORS * PCI_MSIX_ENTRY_SIZE);
91
+ pci_set_long(s->msix_table + addr, val);
92
+}
93
+
94
+static const MemoryRegionOps msix_table_mmio_ops = {
95
+ .read = msix_table_mmio_read,
96
+ .write = msix_table_mmio_write,
97
+ .endianness = DEVICE_LITTLE_ENDIAN,
98
+ .valid = {
99
+ .min_access_size = 4,
100
+ .max_access_size = 8,
101
+ },
102
+ .impl = {
103
+ .max_access_size = 4,
104
+ },
105
+};
106
+
107
+static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr,
108
+ unsigned size)
109
+{
110
+ RISCVIOMMUStateSys *s = opaque;
111
+
112
+ return pci_get_long(s->msix_pba + addr);
113
+}
114
+
115
+static void msix_pba_mmio_write(void *opaque, hwaddr addr,
116
+ uint64_t val, unsigned size)
117
+{
118
+}
119
+
120
+static const MemoryRegionOps msix_pba_mmio_ops = {
121
+ .read = msix_pba_mmio_read,
122
+ .write = msix_pba_mmio_write,
123
+ .endianness = DEVICE_LITTLE_ENDIAN,
124
+ .valid = {
125
+ .min_access_size = 4,
126
+ .max_access_size = 8,
127
+ },
128
+ .impl = {
129
+ .max_access_size = 4,
130
+ },
131
};
132
133
+static void riscv_iommu_sysdev_init_msi(RISCVIOMMUStateSys *s,
134
+ uint32_t n_vectors)
135
+{
136
+ RISCVIOMMUState *iommu = &s->iommu;
137
+ uint32_t table_size = table_size = n_vectors * PCI_MSIX_ENTRY_SIZE;
138
+ uint32_t table_offset = RISCV_IOMMU_REG_MSI_CONFIG;
139
+ uint32_t pba_size = QEMU_ALIGN_UP(n_vectors, 64) / 8;
140
+ uint32_t pba_offset = RISCV_IOMMU_REG_MSI_CONFIG + 256;
141
+
142
+ s->msix_table = g_malloc0(table_size);
143
+ s->msix_pba = g_malloc0(pba_size);
144
+
145
+ memory_region_init_io(&s->msix_table_mmio, OBJECT(s), &msix_table_mmio_ops,
146
+ s, "msix-table", table_size);
147
+ memory_region_add_subregion(&iommu->regs_mr, table_offset,
148
+ &s->msix_table_mmio);
149
+
150
+ memory_region_init_io(&s->msix_pba_mmio, OBJECT(s), &msix_pba_mmio_ops, s,
151
+ "msix-pba", pba_size);
152
+ memory_region_add_subregion(&iommu->regs_mr, pba_offset,
153
+ &s->msix_pba_mmio);
154
+}
155
+
156
+static void riscv_iommu_sysdev_send_MSI(RISCVIOMMUStateSys *s,
157
+ uint32_t vector)
158
+{
159
+ uint8_t *table_entry = s->msix_table + vector * PCI_MSIX_ENTRY_SIZE;
160
+ uint64_t msi_addr = pci_get_quad(table_entry + PCI_MSIX_ENTRY_LOWER_ADDR);
161
+ uint32_t msi_data = pci_get_long(table_entry + PCI_MSIX_ENTRY_DATA);
162
+ MemTxResult result;
163
+
164
+ address_space_stl_le(&address_space_memory, msi_addr,
165
+ msi_data, MEMTXATTRS_UNSPECIFIED, &result);
166
+ trace_riscv_iommu_sys_msi_sent(vector, msi_addr, msi_data, result);
167
+}
168
+
169
static void riscv_iommu_sysdev_notify(RISCVIOMMUState *iommu,
170
unsigned vector)
171
{
172
RISCVIOMMUStateSys *s = container_of(iommu, RISCVIOMMUStateSys, iommu);
173
uint32_t fctl = riscv_iommu_reg_get32(iommu, RISCV_IOMMU_REG_FCTL);
174
175
- /* We do not support MSIs yet */
176
- if (!(fctl & RISCV_IOMMU_FCTL_WSI)) {
177
+ if (fctl & RISCV_IOMMU_FCTL_WSI) {
178
+ qemu_irq_pulse(s->irqs[vector]);
179
+ trace_riscv_iommu_sys_irq_sent(vector);
180
return;
181
}
182
183
- qemu_irq_pulse(s->irqs[vector]);
184
+ riscv_iommu_sysdev_send_MSI(s, vector);
185
}
186
187
static void riscv_iommu_sys_realize(DeviceState *dev, Error **errp)
188
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_sys_realize(DeviceState *dev, Error **errp)
189
irq = qdev_get_gpio_in(s->irqchip, s->base_irq + i);
190
sysbus_connect_irq(sysdev, i, irq);
191
}
192
+
193
+ riscv_iommu_sysdev_init_msi(s, RISCV_IOMMU_PCI_MSIX_VECTORS);
194
}
195
196
static void riscv_iommu_sys_init(Object *obj)
197
@@ -XXX,XX +XXX,XX @@ static void riscv_iommu_sys_init(Object *obj)
198
qdev_alias_all_properties(DEVICE(iommu), obj);
199
200
iommu->icvec_avail_vectors = RISCV_IOMMU_SYSDEV_ICVEC_VECTORS;
201
- riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_WSI);
202
+ riscv_iommu_set_cap_igs(iommu, RISCV_IOMMU_CAP_IGS_BOTH);
203
}
204
205
static Property riscv_iommu_sys_properties[] = {
206
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
207
index XXXXXXX..XXXXXXX 100644
208
--- a/hw/riscv/virt.c
209
+++ b/hw/riscv/virt.c
210
@@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio_iommu(RISCVVirtState *s, uint16_t bdf)
211
}
212
213
static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip,
214
+ uint32_t msi_phandle,
215
uint32_t *iommu_sys_phandle)
216
{
217
const char comp[] = "riscv,iommu";
218
@@ -XXX,XX +XXX,XX @@ static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip,
219
iommu_irq_map[2], FDT_IRQ_TYPE_EDGE_LOW,
220
iommu_irq_map[3], FDT_IRQ_TYPE_EDGE_LOW);
221
222
+ qemu_fdt_setprop_cell(fdt, iommu_node, "msi-parent", msi_phandle);
223
+
224
*iommu_sys_phandle = iommu_phandle;
225
}
226
227
@@ -XXX,XX +XXX,XX @@ static void finalize_fdt(RISCVVirtState *s)
228
create_fdt_virtio(s, virt_memmap, irq_virtio_phandle);
229
230
if (virt_is_iommu_sys_enabled(s)) {
231
- create_fdt_iommu_sys(s, irq_mmio_phandle, &iommu_sys_phandle);
232
+ create_fdt_iommu_sys(s, irq_mmio_phandle, msi_pcie_phandle,
233
+ &iommu_sys_phandle);
234
}
235
create_fdt_pcie(s, virt_memmap, irq_pcie_phandle, msi_pcie_phandle,
236
iommu_sys_phandle);
237
diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events
238
index XXXXXXX..XXXXXXX 100644
239
--- a/hw/riscv/trace-events
240
+++ b/hw/riscv/trace-events
241
@@ -XXX,XX +XXX,XX @@ riscv_iommu_icvec_write(uint32_t orig, uint32_t actual) "ICVEC write: incoming 0
242
riscv_iommu_ats(const char *id, unsigned b, unsigned d, unsigned f, uint64_t iova) "%s: translate request %04x:%02x.%u iova: 0x%"PRIx64
243
riscv_iommu_ats_inval(const char *id) "%s: dev-iotlb invalidate"
244
riscv_iommu_ats_prgr(const char *id) "%s: dev-iotlb page request group response"
245
+riscv_iommu_sys_irq_sent(uint32_t vector) "IRQ sent to vector %u"
246
+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%lx msi_data 0x%x result %u"
247
--
248
2.47.1
diff view generated by jsdifflib
New patch
1
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
3
Add a riscv_iommu_reset() helper in the base emulation code that
4
implements the expected reset behavior as defined by the riscv-iommu
5
spec.
6
7
Devices can then use this helper in their own reset callbacks.
8
9
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-ID: <20241106133407.604587-7-dbarboza@ventanamicro.com>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
hw/riscv/riscv-iommu.h | 1 +
15
include/hw/riscv/iommu.h | 6 ++++--
16
hw/riscv/riscv-iommu-pci.c | 20 ++++++++++++++++++++
17
hw/riscv/riscv-iommu-sys.c | 20 ++++++++++++++++++++
18
hw/riscv/riscv-iommu.c | 35 +++++++++++++++++++++++++++++++++++
19
hw/riscv/trace-events | 2 ++
20
6 files changed, 82 insertions(+), 2 deletions(-)
21
22
diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/riscv/riscv-iommu.h
25
+++ b/hw/riscv/riscv-iommu.h
26
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUState {
27
void riscv_iommu_pci_setup_iommu(RISCVIOMMUState *iommu, PCIBus *bus,
28
Error **errp);
29
void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode);
30
+void riscv_iommu_reset(RISCVIOMMUState *s);
31
32
/* private helpers */
33
34
diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/riscv/iommu.h
37
+++ b/include/hw/riscv/iommu.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUState RISCVIOMMUState;
39
typedef struct RISCVIOMMUSpace RISCVIOMMUSpace;
40
41
#define TYPE_RISCV_IOMMU_PCI "riscv-iommu-pci"
42
-OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI)
43
+OBJECT_DECLARE_TYPE(RISCVIOMMUStatePci, RISCVIOMMUPciClass, RISCV_IOMMU_PCI)
44
typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci;
45
+typedef struct RISCVIOMMUPciClass RISCVIOMMUPciClass;
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
59
@@ -XXX,XX +XXX,XX @@
60
#include "cpu_bits.h"
61
#include "riscv-iommu.h"
62
#include "riscv-iommu-bits.h"
63
+#include "trace.h"
64
65
/* RISC-V IOMMU PCI Device Emulation */
66
#define RISCV_PCI_CLASS_SYSTEM_IOMMU 0x0806
67
@@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUStatePci {
68
RISCVIOMMUState iommu; /* common IOMMU state */
69
} RISCVIOMMUStatePci;
70
71
+struct RISCVIOMMUPciClass {
72
+ /*< public >*/
73
+ DeviceRealize parent_realize;
74
+ ResettablePhases parent_phases;
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(),
82
};
83
84
+static void riscv_iommu_pci_reset_hold(Object *obj, ResetType type)
85
+{
86
+ RISCVIOMMUStatePci *pci = RISCV_IOMMU_PCI(obj);
87
+ RISCVIOMMUState *iommu = &pci->iommu;
88
+
89
+ riscv_iommu_reset(iommu);
90
+
91
+ trace_riscv_iommu_pci_reset_hold(type);
92
+}
93
+
94
static void riscv_iommu_pci_class_init(ObjectClass *klass, void *data)
95
{
96
DeviceClass *dc = DEVICE_CLASS(klass);
97
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
98
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
99
+
100
+ rc->phases.hold = riscv_iommu_pci_reset_hold;
101
102
k->realize = riscv_iommu_pci_realize;
103
k->exit = riscv_iommu_pci_exit;
104
diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c
105
index XXXXXXX..XXXXXXX 100644
106
--- a/hw/riscv/riscv-iommu-sys.c
107
+++ b/hw/riscv/riscv-iommu-sys.c
108
@@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUStateSys {
109
uint8_t *msix_pba;
110
};
111
112
+struct RISCVIOMMUSysClass {
113
+ /*< public >*/
114
+ DeviceRealize parent_realize;
115
+ ResettablePhases parent_phases;
116
+};
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)
126
+{
127
+ RISCVIOMMUStateSys *sys = RISCV_IOMMU_SYS(obj);
128
+ RISCVIOMMUState *iommu = &sys->iommu;
129
+
130
+ riscv_iommu_reset(iommu);
131
+
132
+ trace_riscv_iommu_sys_reset_hold(type);
133
+}
134
+
135
static void riscv_iommu_sys_class_init(ObjectClass *klass, void *data)
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)
154
+{
155
+ uint32_t reg_clr;
156
+ int ddtp_mode;
157
+
158
+ /*
159
+ * Clear DDTP while setting DDTP_mode back to user
160
+ * initial setting.
161
+ */
162
+ ddtp_mode = s->enable_off ?
163
+ RISCV_IOMMU_DDTP_MODE_OFF : RISCV_IOMMU_DDTP_MODE_BARE;
164
+ s->ddtp = set_field(0, RISCV_IOMMU_DDTP_MODE, ddtp_mode);
165
+ riscv_iommu_reg_set64(s, RISCV_IOMMU_REG_DDTP, s->ddtp);
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);
186
+}
187
+
188
static const Property riscv_iommu_properties[] = {
189
DEFINE_PROP_UINT32("version", RISCVIOMMUState, version,
190
RISCV_IOMMU_SPEC_DOT_VER),
191
diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events
192
index XXXXXXX..XXXXXXX 100644
193
--- a/hw/riscv/trace-events
194
+++ b/hw/riscv/trace-events
195
@@ -XXX,XX +XXX,XX @@ riscv_iommu_ats_inval(const char *id) "%s: dev-iotlb invalidate"
196
riscv_iommu_ats_prgr(const char *id) "%s: dev-iotlb page request group response"
197
riscv_iommu_sys_irq_sent(uint32_t vector) "IRQ sent to vector %u"
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%lx msi_data 0x%x result %u"
199
+riscv_iommu_sys_reset_hold(int reset_type) "reset type %d"
200
+riscv_iommu_pci_reset_hold(int reset_type) "reset type %d"
201
--
202
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
4
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
5
Message-ID: <20241106133407.604587-8-dbarboza@ventanamicro.com>
6
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
7
---
8
docs/specs/riscv-iommu.rst | 30 +++++++++++++++++++++++++++---
9
docs/system/riscv/virt.rst | 10 ++++++++++
10
2 files changed, 37 insertions(+), 3 deletions(-)
11
12
diff --git a/docs/specs/riscv-iommu.rst b/docs/specs/riscv-iommu.rst
13
index XXXXXXX..XXXXXXX 100644
14
--- a/docs/specs/riscv-iommu.rst
15
+++ b/docs/specs/riscv-iommu.rst
16
@@ -XXX,XX +XXX,XX @@ RISC-V IOMMU support for RISC-V machines
17
QEMU implements a RISC-V IOMMU emulation based on the RISC-V IOMMU spec
18
version 1.0 `iommu1.0`_.
19
20
-The emulation includes a PCI reference device, riscv-iommu-pci, that QEMU
21
-RISC-V boards can use. The 'virt' RISC-V machine is compatible with this
22
-device.
23
+The emulation includes a PCI reference device (riscv-iommu-pci) and a platform
24
+bus device (riscv-iommu-sys) that QEMU RISC-V boards can use. The 'virt'
25
+RISC-V machine is compatible with both devices.
26
27
riscv-iommu-pci reference device
28
--------------------------------
29
@@ -XXX,XX +XXX,XX @@ Several options are available to control the capabilities of the device, namely:
30
- "s-stage": enable s-stage support
31
- "g-stage": enable g-stage support
32
33
+riscv-iommu-sys device
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
--------------------
87
88
--
89
2.47.1
diff view generated by jsdifflib
New patch
1
From: Anton Blanchard <antonb@tenstorrent.com>
1
2
3
Add a CPU entry for the Tenstorrent Ascalon CPU, a series of 2 wide to
4
8 wide RV64 cores. More details can be found at
5
https://tenstorrent.com/ip/tt-ascalon
6
7
Signed-off-by: Anton Blanchard <antonb@tenstorrent.com>
8
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20241113110459.1607299-1-antonb@tenstorrent.com>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
target/riscv/cpu-qom.h | 1 +
14
target/riscv/cpu.c | 67 ++++++++++++++++++++++++++++++++++++++++++
15
2 files changed, 68 insertions(+)
16
17
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
18
index XXXXXXX..XXXXXXX 100644
19
--- a/target/riscv/cpu-qom.h
20
+++ b/target/riscv/cpu-qom.h
21
@@ -XXX,XX +XXX,XX @@
22
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
23
#define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906")
24
#define TYPE_RISCV_CPU_VEYRON_V1 RISCV_CPU_TYPE_NAME("veyron-v1")
25
+#define TYPE_RISCV_CPU_TT_ASCALON RISCV_CPU_TYPE_NAME("tt-ascalon")
26
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
27
28
OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
29
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/riscv/cpu.c
32
+++ b/target/riscv/cpu.c
33
@@ -XXX,XX +XXX,XX @@ static void 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),
114
--
115
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
The helper is_kvm_aia() is checking not only for AIA, but for
4
aplic-imsic (i.e. "aia=aplic-imsic" in 'virt' RISC-V machine) with an
5
in-kernel chip present.
6
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>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20241119191706.718860-2-dbarboza@ventanamicro.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
include/hw/intc/riscv_aplic.h | 1 +
18
hw/intc/riscv_aplic.c | 8 ++++----
19
2 files changed, 5 insertions(+), 4 deletions(-)
20
21
diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/intc/riscv_aplic.h
24
+++ b/include/hw/intc/riscv_aplic.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState {
26
};
27
28
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
29
+bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
30
31
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
32
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
33
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/hw/intc/riscv_aplic.c
36
+++ b/hw/intc/riscv_aplic.c
37
@@ -XXX,XX +XXX,XX @@
38
* KVM AIA only supports APLIC MSI, fallback to QEMU emulation if we want to use
39
* APLIC Wired.
40
*/
41
-static bool is_kvm_aia(bool msimode)
42
+bool riscv_is_kvm_aia_aplic_imsic(bool msimode)
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);
71
}
72
73
--
74
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
In create_fdt_sockets() we have the following pattern:
4
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
}
15
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.
18
19
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-ID: <20241119191706.718860-3-dbarboza@ventanamicro.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
hw/riscv/virt.c | 10 ++++------
25
1 file changed, 4 insertions(+), 6 deletions(-)
26
27
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/riscv/virt.c
30
+++ b/hw/riscv/virt.c
31
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
32
msi_m_phandle, msi_s_phandle, phandle,
33
&intc_phandles[0], xplic_phandles,
34
ms->smp.cpus);
35
+
36
+ *irq_mmio_phandle = xplic_phandles[0];
37
+ *irq_virtio_phandle = xplic_phandles[0];
38
+ *irq_pcie_phandle = xplic_phandles[0];
39
} else {
40
phandle_pos = ms->smp.cpus;
41
for (socket = (socket_count - 1); socket >= 0; socket--) {
42
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
43
s->soc[socket].num_harts);
44
}
45
}
46
- }
47
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];
56
--
57
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Similar to the riscv_is_kvm_aia_aplic_imsic() helper from riscv_aplic.c,
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.
6
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>
12
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
13
Message-ID: <20241119191706.718860-4-dbarboza@ventanamicro.com>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
hw/riscv/virt.c | 12 +++++++-----
17
1 file changed, 7 insertions(+), 5 deletions(-)
18
19
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
20
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/riscv/virt.c
22
+++ b/hw/riscv/virt.c
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;
39
}
40
41
- /* KVM AIA only has one APLIC instance */
42
- if (kvm_enabled() && virt_use_kvm_aia(s)) {
43
+ /* KVM AIA aplic-imsic only has one APLIC instance */
44
+ if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) {
45
create_fdt_socket_aplic(s, memmap, 0,
46
msi_m_phandle, msi_s_phandle, phandle,
47
&intc_phandles[0], xplic_phandles,
48
@@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine)
49
}
50
}
51
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,
57
--
58
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Before adding support to kernel-irqchip=split when using KVM AIA we need
4
to change how we create the in-kernel AIA device.
5
6
In the use case we have so far, i.e. in-kernel irqchip without split
7
mode, both the s-mode APLIC and IMSIC controllers are provided by the
8
irqchip. In irqchip_split() mode we'll emulate the s-mode APLIC
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.
12
13
In the kernel source arch/riscv/kvm/aia_aplic.c, function
14
kvm_riscv_aia_aplic_init(), we verify that the APLIC controller won't be
15
instantiated by KVM if we do not set 'nr_sources', which is set via
16
KVM_DEV_RISCV_AIA_CONFIG_SRCS. For QEMU this means that we should not
17
set 'aia_irq_num' during kvm_riscv_aia_create() in irqchip_split() mode.
18
19
In this same condition, skip KVM_DEV_RISCV_AIA_ADDR_APLIC as well since
20
it is used to set the base address for the in-kernel APLIC controller.
21
22
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
23
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
24
Message-ID: <20241119191706.718860-5-dbarboza@ventanamicro.com>
25
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
26
---
27
target/riscv/kvm/kvm-cpu.c | 38 +++++++++++++++++++++++---------------
28
1 file changed, 23 insertions(+), 15 deletions(-)
29
30
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/riscv/kvm/kvm-cpu.c
33
+++ b/target/riscv/kvm/kvm-cpu.c
34
@@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift,
35
}
36
}
37
38
- ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG,
39
- KVM_DEV_RISCV_AIA_CONFIG_SRCS,
40
- &aia_irq_num, true, NULL);
41
- if (ret < 0) {
42
- error_report("KVM AIA: failed to set number of input irq lines");
43
- exit(1);
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);
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);
73
}
74
75
- ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR,
76
- KVM_DEV_RISCV_AIA_ADDR_APLIC,
77
- &aplic_base, true, NULL);
78
- if (ret < 0) {
79
- error_report("KVM AIA: failed to set the base address of APLIC");
80
- exit(1);
81
- }
82
-
83
for (socket = 0; socket < socket_count; socket++) {
84
socket_imsic_base = imsic_base + socket * (1U << group_shift);
85
hart_count = riscv_socket_hart_count(machine, socket);
86
--
87
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
The current logic to determine if we don't need an emulated APLIC
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().
8
9
This won't suffice to support irqchip_split() mode: it will match
10
exactly the same conditions as the one above, but setting the irqchip to
11
'split' mode will now require us to emulate an APLIC s-mode controller,
12
like we're doing with 'aia=aplic'.
13
14
Create a new riscv_use_emulated_aplic() helper that will encapsulate
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().
18
19
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-ID: <20241119191706.718860-6-dbarboza@ventanamicro.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
include/hw/intc/riscv_aplic.h | 1 +
25
hw/intc/riscv_aplic.c | 24 +++++++++++++++++++++---
26
hw/riscv/virt.c | 14 ++++++++++++--
27
3 files changed, 34 insertions(+), 5 deletions(-)
28
29
diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/intc/riscv_aplic.h
32
+++ b/include/hw/intc/riscv_aplic.h
33
@@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState {
34
35
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
36
bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
37
+bool riscv_use_emulated_aplic(bool msimode);
38
39
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
40
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
41
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/intc/riscv_aplic.c
44
+++ b/hw/intc/riscv_aplic.c
45
@@ -XXX,XX +XXX,XX @@
46
#include "target/riscv/cpu.h"
47
#include "sysemu/sysemu.h"
48
#include "sysemu/kvm.h"
49
+#include "sysemu/tcg.h"
50
#include "kvm/kvm_riscv.h"
51
#include "migration/vmstate.h"
52
53
@@ -XXX,XX +XXX,XX @@ bool riscv_is_kvm_aia_aplic_imsic(bool msimode)
54
return kvm_irqchip_in_kernel() && msimode;
55
}
56
57
+bool riscv_use_emulated_aplic(bool msimode)
58
+{
59
+#ifdef CONFIG_KVM
60
+ if (tcg_enabled()) {
61
+ return true;
62
+ }
63
+
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
72
+}
73
+
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)
113
+{
114
+ bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
115
+
116
+ return riscv_use_emulated_aplic(msimode);
117
+}
118
+
119
static bool virt_aclint_allowed(void)
120
{
121
return tcg_enabled() || qtest_enabled();
122
@@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
123
*msi_pcie_phandle = msi_s_phandle;
124
}
125
126
- /* KVM AIA aplic-imsic only has one APLIC instance */
127
- if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) {
128
+ /*
129
+ * With KVM AIA aplic-imsic, using an irqchip without split
130
+ * mode, we'll use only one APLIC instance.
131
+ */
132
+ if (!virt_use_emulated_aplic(s->aia_type)) {
133
create_fdt_socket_aplic(s, memmap, 0,
134
msi_m_phandle, msi_s_phandle, phandle,
135
&intc_phandles[0], xplic_phandles,
136
--
137
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
The last step to enable KVM AIA aplic-imsic with irqchip in split mode
4
is to deal with how MSIs are going to be sent. In our current design we
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.
9
10
Add a new RISCVACPLICState attribute called 'kvm_msicfgaddr'. This
11
attribute represents the base configuration address for MSIs, in our
12
case the base addr of the IMSIC controller. This attribute is being set
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>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
include/hw/intc/riscv_aplic.h | 6 +++++
25
hw/intc/riscv_aplic.c | 42 +++++++++++++++++++++++++++--------
26
hw/riscv/virt.c | 6 ++++-
27
3 files changed, 44 insertions(+), 10 deletions(-)
28
29
diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/include/hw/intc/riscv_aplic.h
32
+++ b/include/hw/intc/riscv_aplic.h
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
57
}
58
59
+void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr)
60
+{
61
+#ifdef CONFIG_KVM
62
+ if (riscv_use_emulated_aplic(aplic->msimode)) {
63
+ aplic->kvm_msicfgaddr = extract64(addr, 0, 32);
64
+ aplic->kvm_msicfgaddrH = extract64(addr, 32, 32);
65
+ }
66
+#endif
67
+}
68
+
69
static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
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);
103
+ }
104
+
105
address_space_stl_le(&address_space_memory, addr,
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);
158
+ }
159
+
160
return kvm_enabled() ? aplic_s : aplic_m;
161
}
162
163
--
164
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Remove the 'irqchip_split()' restriction in kvm_arch_init() now that
4
we have support for "-accel kvm,kernel-irqchip=split".
5
6
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <20241119191706.718860-8-dbarboza@ventanamicro.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/kvm/kvm-cpu.c | 5 -----
12
1 file changed, 5 deletions(-)
13
14
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/kvm/kvm-cpu.c
17
+++ b/target/riscv/kvm/kvm-cpu.c
18
@@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s)
19
20
int kvm_arch_irqchip_create(KVMState *s)
21
{
22
- if (kvm_kernel_irqchip_split()) {
23
- error_report("-machine kernel_irqchip=split is not supported on RISC-V.");
24
- exit(1);
25
- }
26
-
27
/*
28
* We can create the VAIA using the newer device control API.
29
*/
30
--
31
2.47.1
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Also add a new page, docs/specs/riscv-aia.rst, where we're documenting
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.
6
7
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20241119191706.718860-9-dbarboza@ventanamicro.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
docs/specs/index.rst | 1 +
13
docs/specs/riscv-aia.rst | 83 ++++++++++++++++++++++++++++++++++++++
14
docs/system/riscv/virt.rst | 7 ++++
15
3 files changed, 91 insertions(+)
16
create mode 100644 docs/specs/riscv-aia.rst
17
18
diff --git a/docs/specs/index.rst b/docs/specs/index.rst
19
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/specs/index.rst
21
+++ b/docs/specs/index.rst
22
@@ -XXX,XX +XXX,XX @@ guest hardware that is specific to QEMU.
23
rapl-msr
24
rocker
25
riscv-iommu
26
+ riscv-aia
27
diff --git a/docs/specs/riscv-aia.rst b/docs/specs/riscv-aia.rst
28
new file mode 100644
29
index XXXXXXX..XXXXXXX
30
--- /dev/null
31
+++ b/docs/specs/riscv-aia.rst
32
@@ -XXX,XX +XXX,XX @@
33
+.. _riscv-aia:
34
+
35
+RISC-V AIA support for RISC-V machines
36
+======================================
37
+
38
+AIA (Advanced Interrupt Architecture) support is implemented in the ``virt``
39
+RISC-V machine for TCG and KVM accelerators.
40
+
41
+The support consists of two main modes:
42
+
43
+- "aia=aplic": adds one or more APLIC (Advanced Platform Level Interrupt Controller)
44
+ devices
45
+- "aia=aplic-imsic": adds one or more APLIC device and an IMSIC (Incoming MSI
46
+ Controller) device for each CPU
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
134
--
135
2.47.1
diff view generated by jsdifflib
New patch
1
1
From: Sai Pavan Boddu <sai.pavan.boddu@amd.com>
2
3
Add a basic board with interrupt controller (intc), timer, serial
4
(uartlite), small memory called LMB@0 (128kB) and DDR@0x80000000
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>
30
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
31
Message-ID: <20241125134739.18189-1-sai.pavan.boddu@amd.com>
32
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
33
---
34
MAINTAINERS | 6 +
35
docs/system/riscv/microblaze-v-generic.rst | 42 +++++
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)
311
diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
312
index XXXXXXX..XXXXXXX 100644
313
--- a/hw/riscv/Kconfig
314
+++ b/hw/riscv/Kconfig
315
@@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC
316
select SIFIVE_PLIC
317
select UNIMP
318
319
+config MICROBLAZE_V
320
+ bool
321
+ default y
322
+ depends on RISCV32 || RISCV64
323
+ select XILINX
324
+ select XILINX_AXI
325
+ select XILINX_ETHLITE
326
+
327
config OPENTITAN
328
bool
329
default y
330
diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
331
index XXXXXXX..XXXXXXX 100644
332
--- a/hw/riscv/meson.build
333
+++ b/hw/riscv/meson.build
334
@@ -XXX,XX +XXX,XX @@ riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c'))
335
riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfsoc.c'))
336
riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
337
riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c'))
338
+riscv_ss.add(when: 'CONFIG_MICROBLAZE_V', if_true: files('microblaze-v-generic.c'))
339
340
hw_arch += {'riscv': riscv_ss}
341
--
342
2.47.1
343
344
diff view generated by jsdifflib
New patch
1
From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
1
2
3
Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
4
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
5
Acked-by: Alistair Francis <alistair.francis@wdc.com>
6
Message-ID: <20241028015744.624943-2-jeeheng.sia@starfivetech.com>
7
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
8
---
9
tests/qtest/bios-tables-test-allowed-diff.h | 1 +
10
1 file changed, 1 insertion(+)
11
12
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/tests/qtest/bios-tables-test-allowed-diff.h
15
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
16
@@ -1 +1,2 @@
17
/* List of comma-separated changed AML files to ignore */
18
+"tests/data/acpi/riscv64/virt/SPCR",
19
--
20
2.47.1
diff view generated by jsdifflib
New patch
1
From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
1
2
3
Update the SPCR table to accommodate the SPCR Table revision 4 [1].
4
The SPCR table has been modified to adhere to the revision 4 format [2].
5
6
[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
7
[2]: https://github.com/acpica/acpica/pull/931
8
9
Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com>
10
Reviewed-by: Sunil V L <sunilvl@ventanamicro.com>
11
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
12
Acked-by: Alistair Francis <alistair.francis@wdc.com>
13
Reviewed-by: Bibo Mao <maobibo@loongson.cn>
14
Message-ID: <20241028015744.624943-3-jeeheng.sia@starfivetech.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
include/hw/acpi/acpi-defs.h | 7 +++++--
18
include/hw/acpi/aml-build.h | 2 +-
19
hw/acpi/aml-build.c | 20 ++++++++++++++++----
20
hw/arm/virt-acpi-build.c | 8 ++++++--
21
hw/loongarch/acpi-build.c | 6 +++++-
22
hw/riscv/virt-acpi-build.c | 12 +++++++++---
23
6 files changed, 42 insertions(+), 13 deletions(-)
24
25
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
26
index XXXXXXX..XXXXXXX 100644
27
--- a/include/hw/acpi/acpi-defs.h
28
+++ b/include/hw/acpi/acpi-defs.h
29
@@ -XXX,XX +XXX,XX @@ typedef struct AcpiSpcrData {
30
uint8_t flow_control;
31
uint8_t terminal_type;
32
uint8_t language;
33
- uint8_t reserved1;
34
uint16_t pci_device_id; /* Must be 0xffff if not PCI device */
35
uint16_t pci_vendor_id; /* Must be 0xffff if not PCI device */
36
uint8_t pci_bus;
37
@@ -XXX,XX +XXX,XX @@ typedef struct AcpiSpcrData {
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
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/hw/acpi/aml-build.h
53
+++ b/include/hw/acpi/aml-build.h
54
@@ -XXX,XX +XXX,XX @@ void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog,
55
56
void build_spcr(GArray *table_data, BIOSLinker *linker,
57
const AcpiSpcrData *f, const uint8_t rev,
58
- const char *oem_id, const char *oem_table_id);
59
+ const char *oem_id, const char *oem_table_id, const char *name);
60
#endif
61
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/acpi/aml-build.c
64
+++ b/hw/acpi/aml-build.c
65
@@ -XXX,XX +XXX,XX @@ static void build_processor_hierarchy_node(GArray *tbl, uint32_t flags,
66
67
void build_spcr(GArray *table_data, BIOSLinker *linker,
68
const AcpiSpcrData *f, const uint8_t rev,
69
- const char *oem_id, const char *oem_table_id)
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);
95
+ }
96
acpi_table_end(linker, &table);
97
}
98
/*
99
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/arm/virt-acpi-build.c
102
+++ b/hw/arm/virt-acpi-build.c
103
@@ -XXX,XX +XXX,XX @@ spcr_setup(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
104
.pci_flags = 0,
105
.pci_segment = 0,
106
};
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
}
116
117
/*
118
diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c
119
index XXXXXXX..XXXXXXX 100644
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);
133
}
134
135
typedef
136
diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/riscv/virt-acpi-build.c
139
+++ b/hw/riscv/virt-acpi-build.c
140
@@ -XXX,XX +XXX,XX @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
141
142
/*
143
* Serial Port Console Redirection Table (SPCR)
144
- * Rev: 1.07
145
+ * Rev: 1.10
146
*/
147
148
static void
149
spcr_setup(GArray *table_data, BIOSLinker *linker, RISCVVirtState *s)
150
{
151
+ const char name[] = ".";
152
AcpiSpcrData serial = {
153
- .interface_type = 0, /* 16550 compatible */
154
+ .interface_type = 0x12, /* 16550 compatible */
155
.base_addr.id = AML_AS_SYSTEM_MEMORY,
156
.base_addr.width = 32,
157
.base_addr.offset = 0,
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);
171
}
172
173
/* RHCT Node[N] starts at offset 56 */
174
--
175
2.47.1
diff view generated by jsdifflib
New patch
1
From: Sia Jee Heng <jeeheng.sia@starfivetech.com>
1
2
3
Update the virt SPCR golden reference file for RISC-V to accommodate the
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].
7
8
[1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
9
[2]: https://github.com/acpica/acpica/pull/931
10
11
Diffs from iasl:
12
/*
13
* Intel ACPI Component Architecture
14
* AML/ASL+ Disassembler version 20200925 (64-bit version)
15
* Copyright (c) 2000 - 2020 Intel Corporation
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>
87
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
88
---
89
tests/qtest/bios-tables-test-allowed-diff.h | 1 -
90
tests/data/acpi/riscv64/virt/SPCR | Bin 80 -> 90 bytes
91
2 files changed, 1 deletion(-)
92
93
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
94
index XXXXXXX..XXXXXXX 100644
95
--- a/tests/qtest/bios-tables-test-allowed-diff.h
96
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
97
@@ -1,2 +1 @@
98
/* List of comma-separated changed AML files to ignore */
99
-"tests/data/acpi/riscv64/virt/SPCR",
100
diff --git a/tests/data/acpi/riscv64/virt/SPCR b/tests/data/acpi/riscv64/virt/SPCR
101
index XXXXXXX..XXXXXXX 100644
102
Binary files a/tests/data/acpi/riscv64/virt/SPCR and b/tests/data/acpi/riscv64/virt/SPCR differ
103
--
104
2.47.1
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
The HTIF interface is RISC-V specific, add
4
it within the MAINTAINERS section covering
5
hw/riscv/.
6
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
10
Message-ID: <20241129154304.34946-2-philmd@linaro.org>
11
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
12
---
13
MAINTAINERS | 2 ++
14
1 file changed, 2 insertions(+)
15
16
diff --git a/MAINTAINERS b/MAINTAINERS
17
index XXXXXXX..XXXXXXX 100644
18
--- a/MAINTAINERS
19
+++ b/MAINTAINERS
20
@@ -XXX,XX +XXX,XX @@ S: Supported
21
F: configs/targets/riscv*
22
F: docs/system/target-riscv.rst
23
F: target/riscv/
24
+F: hw/char/riscv_htif.c
25
F: hw/riscv/
26
F: hw/intc/riscv*
27
+F: include/hw/char/riscv_htif.h
28
F: include/hw/riscv/
29
F: linux-user/host/riscv32/
30
F: linux-user/host/riscv64/
31
--
32
2.47.1
33
34
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
Since our RISC-V system emulation is only built for little
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.
7
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.
11
12
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
15
Message-ID: <20241129154304.34946-3-philmd@linaro.org>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
hw/char/riscv_htif.c | 11 ++++++-----
19
1 file changed, 6 insertions(+), 5 deletions(-)
20
21
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
22
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/char/riscv_htif.c
24
+++ b/hw/char/riscv_htif.c
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,
55
};
56
57
HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
58
--
59
2.47.1
60
61
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
Looking at htif_mm_ops[] read/write handlers, we notice they
4
expect 32-bit values to accumulate into to the 'fromhost' and
5
'tohost' 64-bit variables. Explicit by setting the .impl
6
min/max fields.
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20241129154304.34946-4-philmd@linaro.org>
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
14
hw/char/riscv_htif.c | 4 ++++
15
1 file changed, 4 insertions(+)
16
17
diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/char/riscv_htif.c
20
+++ b/hw/char/riscv_htif.c
21
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps htif_mm_ops = {
22
.read = htif_mm_read,
23
.write = htif_mm_write,
24
.endianness = DEVICE_LITTLE_ENDIAN,
25
+ .impl = {
26
+ .min_access_size = 4,
27
+ .max_access_size = 4,
28
+ },
29
};
30
31
HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
32
--
33
2.47.1
34
35
diff view generated by jsdifflib
New patch
1
From: Jim Shu <jim.shu@sifive.com>
1
2
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.
6
7
Signed-off-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
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
]
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
include/hw/riscv/boot.h | 2 +-
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(-)
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
};
130
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
131
index XXXXXXX..XXXXXXX 100644
132
--- a/hw/riscv/spike.c
133
+++ b/hw/riscv/spike.c
134
@@ -XXX,XX +XXX,XX @@ static void spike_board_init(MachineState *machine)
135
hwaddr firmware_load_addr = memmap[SPIKE_DRAM].base;
136
target_ulong kernel_start_addr;
137
char *firmware_name;
138
- uint32_t fdt_load_addr;
139
+ uint64_t fdt_load_addr;
140
uint64_t kernel_entry;
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 */
165
--
166
2.47.1
diff view generated by jsdifflib
New patch
1
From: Jim Shu <jim.shu@sifive.com>
1
2
3
Add a new struct RISCVBootInfo to sync boot information between multiple
4
boot functions.
5
6
Signed-off-by: Jim Shu <jim.shu@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@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>
11
---
12
include/hw/riscv/boot.h | 25 ++++++++++-----
13
hw/riscv/boot.c | 65 ++++++++++++++++++++++----------------
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(-)
21
22
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/include/hw/riscv/boot.h
25
+++ b/include/hw/riscv/boot.h
26
@@ -XXX,XX +XXX,XX @@
27
#define RISCV32_BIOS_BIN "opensbi-riscv32-generic-fw_dynamic.bin"
28
#define RISCV64_BIOS_BIN "opensbi-riscv64-generic-fw_dynamic.bin"
29
30
+typedef struct RISCVBootInfo {
31
+ ssize_t kernel_size;
32
+ hwaddr image_low_addr;
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 */
250
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
251
index XXXXXXX..XXXXXXX 100644
252
--- a/hw/riscv/opentitan.c
253
+++ b/hw/riscv/opentitan.c
254
@@ -XXX,XX +XXX,XX @@ static void opentitan_machine_init(MachineState *machine)
255
OpenTitanState *s = OPENTITAN_MACHINE(machine);
256
const MemMapEntry *memmap = ibex_memmap;
257
MemoryRegion *sys_mem = get_system_memory();
258
+ RISCVBootInfo boot_info;
259
260
if (machine->ram_size != mc->default_ram_size) {
261
char *sz = size_to_str(mc->default_ram_size);
262
@@ -XXX,XX +XXX,XX @@ static void opentitan_machine_init(MachineState *machine)
263
riscv_load_firmware(machine->firmware, &firmware_load_addr, NULL);
264
}
265
266
+ riscv_boot_info_init(&boot_info, &s->soc.cpus);
267
if (machine->kernel_filename) {
268
- riscv_load_kernel(machine, &s->soc.cpus,
269
+ riscv_load_kernel(machine, &boot_info,
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 */
412
--
413
2.47.1
diff view generated by jsdifflib
New patch
1
From: Jim Shu <jim.shu@sifive.com>
1
2
3
DTB is placed to the end of memory, so we will check if the start
4
address of DTB overlaps to the address of kernel/initrd.
5
6
Signed-off-by: Jim Shu <jim.shu@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.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>
11
---
12
include/hw/riscv/boot.h | 3 +++
13
hw/riscv/boot.c | 25 ++++++++++++++++++++++++-
14
2 files changed, 27 insertions(+), 1 deletion(-)
15
16
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
17
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/riscv/boot.h
19
+++ b/include/hw/riscv/boot.h
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)
43
}
44
}
45
46
+ info->initrd_start = start;
47
+ info->initrd_size = size;
48
+
49
/* Some RISC-V machines (e.g. opentitan) don't have a fdt. */
50
if (fdt) {
51
end = start + size;
52
@@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size,
53
int ret = fdt_pack(ms->fdt);
54
hwaddr dram_end, temp;
55
int fdtsize;
56
+ uint64_t dtb_start, dtb_start_limit;
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
/*
94
--
95
2.47.1
diff view generated by jsdifflib
New patch
1
From: "Fea.Wang" <fea.wang@sifive.com>
1
2
3
Refer to the draft of svukte extension from:
4
https://github.com/riscv/riscv-isa-manual/pull/1564
5
6
Svukte provides a means to make user-mode accesses to supervisor memory
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>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-ID: <20241203034932.25185-2-fea.wang@sifive.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu_cfg.h | 1 +
19
1 file changed, 1 insertion(+)
20
21
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/target/riscv/cpu_cfg.h
24
+++ b/target/riscv/cpu_cfg.h
25
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
26
bool ext_svnapot;
27
bool ext_svpbmt;
28
bool ext_svvptc;
29
+ bool ext_svukte;
30
bool ext_zdinx;
31
bool ext_zaamo;
32
bool ext_zacas;
33
--
34
2.47.1
diff view generated by jsdifflib
New patch
1
From: "Fea.Wang" <fea.wang@sifive.com>
1
2
3
Svukte extension add UKTE bit, bit[8] in senvcfg CSR. The bit will be
4
supported when the svukte extension is enabled.
5
6
When senvcfg[UKTE] bit is set, the memory access from U-mode should do
7
the svukte check only except HLV/HLVX/HSV H-mode instructions which
8
depend on hstatus[HUKTE].
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>
14
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
15
Message-ID: <20241203034932.25185-3-fea.wang@sifive.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
17
---
18
target/riscv/cpu_bits.h | 1 +
19
target/riscv/csr.c | 4 ++++
20
2 files changed, 5 insertions(+)
21
22
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/riscv/cpu_bits.h
25
+++ b/target/riscv/cpu_bits.h
26
@@ -XXX,XX +XXX,XX @@ typedef enum RISCVException {
27
#define SENVCFG_CBIE MENVCFG_CBIE
28
#define SENVCFG_CBCFE MENVCFG_CBCFE
29
#define SENVCFG_CBZE MENVCFG_CBZE
30
+#define SENVCFG_UKTE BIT(8)
31
32
#define HENVCFG_FIOM MENVCFG_FIOM
33
#define HENVCFG_LPE MENVCFG_LPE
34
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/target/riscv/csr.c
37
+++ b/target/riscv/csr.c
38
@@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno,
39
mask |= SENVCFG_SSE;
40
}
41
42
+ if (env_archcpu(env)->cfg.ext_svukte) {
43
+ mask |= SENVCFG_UKTE;
44
+ }
45
+
46
env->senvcfg = (env->senvcfg & ~mask) | (val & mask);
47
return RISCV_EXCP_NONE;
48
}
49
--
50
2.47.1
diff view generated by jsdifflib
New patch
1
From: "Fea.Wang" <fea.wang@sifive.com>
1
2
3
Svukte extension add HUKTE bit, bit[24] in hstatus CSR. The written
4
value will be masked when the svukte extension is not enabled.
5
6
When hstatus[HUKTE] bit is set, HLV/HLVX/HSV work in the U-mode should
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>
13
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
14
Message-ID: <20241203034932.25185-4-fea.wang@sifive.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
---
17
target/riscv/cpu_bits.h | 1 +
18
target/riscv/csr.c | 3 +++
19
2 files changed, 4 insertions(+)
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
33
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/riscv/csr.c
36
+++ b/target/riscv/csr.c
37
@@ -XXX,XX +XXX,XX @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno,
38
static RISCVException write_hstatus(CPURISCVState *env, int csrno,
39
target_ulong val)
40
{
41
+ if (!env_archcpu(env)->cfg.ext_svukte) {
42
+ val = val & (~HSTATUS_HUKTE);
43
+ }
44
env->hstatus = val;
45
if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) {
46
qemu_log_mask(LOG_UNIMP,
47
--
48
2.47.1
diff view generated by jsdifflib
New patch
1
From: "Fea.Wang" <fea.wang@sifive.com>
1
2
3
Follow the Svukte spec, do the memory access address checking
4
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>
20
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
21
Message-ID: <20241203034932.25185-5-fea.wang@sifive.com>
22
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
23
---
24
target/riscv/cpu_helper.c | 55 +++++++++++++++++++++++++++++++++++++++
25
1 file changed, 55 insertions(+)
26
27
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/target/riscv/cpu_helper.c
30
+++ b/target/riscv/cpu_helper.c
31
@@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr,
32
return TRANSLATE_SUCCESS;
33
}
34
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)
38
+{
39
+ /* Svukte extension depends on Sv39. */
40
+ if (!(env_archcpu(env)->cfg.ext_svukte ||
41
+ !first_stage ||
42
+ VM_1_10_SV39 != get_field(env->satp, SATP64_MODE))) {
43
+ return false;
44
+ }
45
+
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;
74
+}
75
+
76
+static bool check_svukte_addr(CPURISCVState *env, vaddr addr)
77
+{
78
+ /* svukte extension excludes RV32 */
79
+ uint32_t sxlen = 32 * riscv_cpu_sxl(env);
80
+ uint64_t high_bit = addr & (1UL << (sxlen - 1));
81
+ return !high_bit;
82
+}
83
+
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
107
--
108
2.47.1
diff view generated by jsdifflib
New patch
1
From: "Fea.Wang" <fea.wang@sifive.com>
1
2
3
Add "svukte" in the ISA string when svukte extension is enabled.
4
5
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
6
Reviewed-by: Frank Chang <frank.chang@sifive.com>
7
Reviewed-by: Jim Shu <jim.shu@sifive.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Message-ID: <20241203034932.25185-6-fea.wang@sifive.com>
10
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
11
---
12
target/riscv/cpu.c | 2 ++
13
1 file changed, 2 insertions(+)
14
15
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/riscv/cpu.c
18
+++ b/target/riscv/cpu.c
19
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
20
ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
21
ISA_EXT_DATA_ENTRY(svnapot, PRIV_VERSION_1_12_0, ext_svnapot),
22
ISA_EXT_DATA_ENTRY(svpbmt, PRIV_VERSION_1_12_0, ext_svpbmt),
23
+ ISA_EXT_DATA_ENTRY(svukte, PRIV_VERSION_1_13_0, ext_svukte),
24
ISA_EXT_DATA_ENTRY(svvptc, PRIV_VERSION_1_13_0, ext_svvptc),
25
ISA_EXT_DATA_ENTRY(xtheadba, PRIV_VERSION_1_11_0, ext_xtheadba),
26
ISA_EXT_DATA_ENTRY(xtheadbb, PRIV_VERSION_1_11_0, ext_xtheadbb),
27
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[] = {
28
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
35
--
36
2.47.1
diff view generated by jsdifflib
New patch
1
From: "Fea.Wang" <fea.wang@sifive.com>
1
2
3
The spec explicitly says svukte doesn't support RV32. So check that it
4
is not enabled in RV32.
5
6
Signed-off-by: Fea.Wang <fea.wang@sifive.com>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
8
Message-ID: <20241203034932.25185-7-fea.wang@sifive.com>
9
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
10
---
11
target/riscv/tcg/tcg-cpu.c | 5 +++++
12
1 file changed, 5 insertions(+)
13
14
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/riscv/tcg/tcg-cpu.c
17
+++ b/target/riscv/tcg/tcg-cpu.c
18
@@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp)
19
return;
20
}
21
22
+ if (mcc->misa_mxl_max == MXL_RV32 && cpu->cfg.ext_svukte) {
23
+ error_setg(errp, "svukte is not supported for RV32");
24
+ return;
25
+ }
26
+
27
/*
28
* Disable isa extensions based on priv spec after we
29
* validated and set everything we need.
30
--
31
2.47.1
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
Rather than relying on implicit includes, explicit them,
4
in order to avoid when refactoring unrelated headers:
5
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]
7
36 | return FIELD_EX32(simd_data(desc), VDATA, NF);
8
| ^
9
10
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
12
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Message-ID: <20241203200828.47311-2-philmd@linaro.org>
14
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
---
16
target/riscv/vector_internals.h | 1 +
17
1 file changed, 1 insertion(+)
18
19
diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h
20
index XXXXXXX..XXXXXXX 100644
21
--- a/target/riscv/vector_internals.h
22
+++ b/target/riscv/vector_internals.h
23
@@ -XXX,XX +XXX,XX @@
24
#define TARGET_RISCV_VECTOR_INTERNALS_H
25
26
#include "qemu/bitops.h"
27
+#include "hw/registerfields.h"
28
#include "cpu.h"
29
#include "tcg/tcg-gvec-desc.h"
30
#include "internals.h"
31
--
32
2.47.1
33
34
diff view generated by jsdifflib
New patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
2
3
Rather than relying on implicit includes, explicit them,
4
in order to avoid when refactoring unrelated headers:
5
6
target/riscv/internals.h:49:15: error: use of undeclared identifier 'PRV_S'
7
49 | ret = PRV_S;
8
| ^
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]
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
16
17
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
20
Message-ID: <20241203200828.47311-3-philmd@linaro.org>
21
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
22
---
23
target/riscv/internals.h | 3 +++
24
1 file changed, 3 insertions(+)
25
26
diff --git a/target/riscv/internals.h b/target/riscv/internals.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/riscv/internals.h
29
+++ b/target/riscv/internals.h
30
@@ -XXX,XX +XXX,XX @@
31
#ifndef RISCV_CPU_INTERNALS_H
32
#define RISCV_CPU_INTERNALS_H
33
34
+#include "exec/cpu-common.h"
35
#include "hw/registerfields.h"
36
+#include "fpu/softfloat-types.h"
37
+#include "target/riscv/cpu_bits.h"
38
39
/*
40
* The current MMU Modes are:
41
--
42
2.47.1
43
44
diff view generated by jsdifflib
New patch
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
1
2
3
Commit 68c9e54bea handled a situation where a warning was being shown
4
when using the 'sifive_e' cpu when disabling the named extension zic64b.
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().
8
9
This solution won't scale well when adding more named features, and can
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>
18
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
19
Message-ID: <20241113171755.978109-2-dbarboza@ventanamicro.com>
20
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
21
---
22
target/riscv/tcg/tcg-cpu.c | 13 ++++++++++---
23
1 file changed, 10 insertions(+), 3 deletions(-)
24
25
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
26
index XXXXXXX..XXXXXXX 100644
27
--- a/target/riscv/tcg/tcg-cpu.c
28
+++ b/target/riscv/tcg/tcg-cpu.c
29
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu)
30
}
31
32
isa_ext_update_enabled(cpu, edata->ext_enable_offset, false);
33
+
34
+ /*
35
+ * Do not show user warnings for named features that users
36
+ * can't enable/disable in the command line. See commit
37
+ * 68c9e54bea for more info.
38
+ */
39
+ if (cpu_cfg_offset_is_named_feat(edata->ext_enable_offset)) {
40
+ continue;
41
+ }
42
#ifndef CONFIG_USER_ONLY
43
warn_report("disabling %s extension for hart 0x" TARGET_FMT_lx
44
" because privilege spec version does not match",
45
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
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;
55
}
56
57
static void riscv_cpu_validate_g(RISCVCPU *cpu)
58
--
59
2.47.1
diff view generated by jsdifflib
1
From: Mikhail Tyutin <m.tyutin@yadro.com>
1
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
2
2
3
Fix incorrect register name in RISC-V disassembler for fmv,fabs,fneg instructions
3
ssstateen is defined in RVA22 as:
4
4
5
Signed-off-by: Mikhail Tyutin <m.tyutin@yadro.com>
5
"Supervisor-mode view of the state-enable extension. The supervisor-mode
6
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
6
(sstateen0-3) and hypervisor-mode (hstateen0-3) state-enable registers
7
Message-Id: <3454991f-7f64-24c3-9a36-f5fa2cc389e1@yadro.com>
7
must be provided."
8
9
Add ssstateen as a named feature that is available if we also have
10
smstateen.
11
12
Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
13
Acked-by: Alistair Francis <alistair.francis@wdc.com>
14
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
15
Message-ID: <20241113171755.978109-3-dbarboza@ventanamicro.com>
8
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
16
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
9
---
17
---
10
disas/riscv.c | 19 ++++++++++---------
18
target/riscv/cpu_cfg.h | 1 +
11
1 file changed, 10 insertions(+), 9 deletions(-)
19
target/riscv/cpu.c | 2 ++
20
target/riscv/tcg/tcg-cpu.c | 9 ++++++++-
21
3 files changed, 11 insertions(+), 1 deletion(-)
12
22
13
diff --git a/disas/riscv.c b/disas/riscv.c
23
diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
14
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
15
--- a/disas/riscv.c
25
--- a/target/riscv/cpu_cfg.h
16
+++ b/disas/riscv.c
26
+++ b/target/riscv/cpu_cfg.h
17
@@ -XXX,XX +XXX,XX @@ static const char rv_vreg_name_sym[32][4] = {
27
@@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig {
18
#define rv_fmt_rd_offset "O\t0,o"
28
/* Named features */
19
#define rv_fmt_rd_rs1_rs2 "O\t0,1,2"
29
bool ext_svade;
20
#define rv_fmt_frd_rs1 "O\t3,1"
30
bool ext_zic64b;
21
+#define rv_fmt_frd_frs1 "O\t3,4"
31
+ bool ext_ssstateen;
22
#define rv_fmt_rd_frs1 "O\t0,4"
32
23
#define rv_fmt_rd_frs1_frs2 "O\t0,4,5"
33
/*
24
#define rv_fmt_frd_frs1_frs2 "O\t3,4,5"
34
* Always 'true' booleans for named features
25
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = {
35
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
26
{ "snez", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
36
index XXXXXXX..XXXXXXX 100644
27
{ "sltz", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
37
--- a/target/riscv/cpu.c
28
{ "sgtz", rv_codec_r, rv_fmt_rd_rs2, NULL, 0, 0, 0 },
38
+++ b/target/riscv/cpu.c
29
- { "fmv.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
39
@@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = {
30
- { "fabs.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
40
ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11),
31
- { "fneg.s", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
41
ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
32
- { "fmv.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
42
ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12),
33
- { "fabs.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
43
+ ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen),
34
- { "fneg.d", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
44
ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
35
- { "fmv.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
45
ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12),
36
- { "fabs.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
46
ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12),
37
- { "fneg.q", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
47
@@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = {
38
+ { "fmv.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
48
*/
39
+ { "fabs.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
49
const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = {
40
+ { "fneg.s", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
50
MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true),
41
+ { "fmv.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
51
+ MULTI_EXT_CFG_BOOL("ssstateen", ext_ssstateen, true),
42
+ { "fabs.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
52
43
+ { "fneg.d", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
53
DEFINE_PROP_END_OF_LIST(),
44
+ { "fmv.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
54
};
45
+ { "fabs.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
55
diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
46
+ { "fneg.q", rv_codec_r, rv_fmt_frd_frs1, NULL, 0, 0, 0 },
56
index XXXXXXX..XXXXXXX 100644
47
{ "beqz", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
57
--- a/target/riscv/tcg/tcg-cpu.c
48
{ "bnez", rv_codec_sb, rv_fmt_rs1_offset, NULL, 0, 0, 0 },
58
+++ b/target/riscv/tcg/tcg-cpu.c
49
{ "blez", rv_codec_sb, rv_fmt_rs2_offset, NULL, 0, 0, 0 },
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
}
74
}
75
76
@@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu)
77
cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 &&
78
cpu->cfg.cbop_blocksize == 64 &&
79
cpu->cfg.cboz_blocksize == 64;
80
+
81
+ cpu->cfg.ext_ssstateen = cpu->cfg.ext_smstateen;
82
}
83
84
static void riscv_cpu_validate_g(RISCVCPU *cpu)
50
--
85
--
51
2.39.2
86
2.47.1
diff view generated by jsdifflib
1
From: Ivan Klokov <ivan.klokov@syntacore.com>
1
From: MollyChen <xiaoou@iscas.ac.cn>
2
2
3
The decoding of the slli_uw currently contains decoding
3
Add a CPU entry for the RV64 XiangShan NANHU CPU which
4
error: shamt part of opcode has six bits, not five.
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
Fixes 3de1fb71("target/riscv: update disas.c for xnor/orn/andn and slli.uw")
8
Signed-off-by: MollyChen <xiaoou@iscas.ac.cn>
7
8
Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com>
9
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
10
Acked-by: Alistair Francis <alistair.francis@wdc.com>
9
Acked-by: Alistair Francis <alistair.francis@wdc.com>
11
Message-Id: <20230227090228.17117-1-ivan.klokov@syntacore.com>
10
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
11
Message-ID: <20241205073622.46052-1-xiaoou@iscas.ac.cn>
12
[ Changes by AF
13
- Fixup code formatting
14
]
12
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
15
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
13
---
16
---
14
disas/riscv.c | 8 ++++----
17
target/riscv/cpu-qom.h | 1 +
15
1 file changed, 4 insertions(+), 4 deletions(-)
18
target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
19
2 files changed, 31 insertions(+)
16
20
17
diff --git a/disas/riscv.c b/disas/riscv.c
21
diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/disas/riscv.c
23
--- a/target/riscv/cpu-qom.h
20
+++ b/disas/riscv.c
24
+++ b/target/riscv/cpu-qom.h
21
@@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = {
25
@@ -XXX,XX +XXX,XX @@
22
{ "clzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
26
#define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906")
23
{ "ctzw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
27
#define TYPE_RISCV_CPU_VEYRON_V1 RISCV_CPU_TYPE_NAME("veyron-v1")
24
{ "cpopw", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 },
28
#define TYPE_RISCV_CPU_TT_ASCALON RISCV_CPU_TYPE_NAME("tt-ascalon")
25
- { "slli.uw", rv_codec_i_sh5, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
29
+#define TYPE_RISCV_CPU_XIANGSHAN_NANHU RISCV_CPU_TYPE_NAME("xiangshan-nanhu")
26
+ { "slli.uw", rv_codec_i_sh6, rv_fmt_rd_rs1_imm, NULL, 0, 0, 0 },
30
#define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host")
27
{ "add.uw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
31
28
{ "rolw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
32
OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU)
29
{ "rorw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 },
33
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
30
@@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa)
34
index XXXXXXX..XXXXXXX 100644
31
switch (((inst >> 12) & 0b111)) {
35
--- a/target/riscv/cpu.c
32
case 0: op = rv_op_addiw; break;
36
+++ b/target/riscv/cpu.c
33
case 1:
37
@@ -XXX,XX +XXX,XX @@ static void rv64_tt_ascalon_cpu_init(Object *obj)
34
- switch (((inst >> 25) & 0b1111111)) {
38
#endif
35
+ switch (((inst >> 26) & 0b111111)) {
39
}
36
case 0: op = rv_op_slliw; break;
40
37
- case 4: op = rv_op_slli_uw; break;
41
+static void rv64_xiangshan_nanhu_cpu_init(Object *obj)
38
- case 48:
42
+{
39
+ case 2: op = rv_op_slli_uw; break;
43
+ CPURISCVState *env = &RISCV_CPU(obj)->env;
40
+ case 24:
44
+ RISCVCPU *cpu = RISCV_CPU(obj);
41
switch ((inst >> 20) & 0b11111) {
45
+
42
case 0b00000: op = rv_op_clzw; break;
46
+ riscv_cpu_set_misa_ext(env, RVG | RVC | RVB | RVS | RVU);
43
case 0b00001: op = rv_op_ctzw; break;
47
+ env->priv_ver = PRIV_VERSION_1_12_0;
48
+
49
+ /* Enable ISA extensions */
50
+ cpu->cfg.ext_zbc = true;
51
+ cpu->cfg.ext_zbkb = true;
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;
60
+
61
+ cpu->cfg.mmu = true;
62
+ cpu->cfg.pmp = true;
63
+
64
+#ifndef CONFIG_USER_ONLY
65
+ set_satp_mode_max_supported(cpu, VM_1_10_SV39);
66
+#endif
67
+}
68
+
69
#ifdef CONFIG_TCG
70
static void rv128_base_cpu_init(Object *obj)
71
{
72
@@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = {
73
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64, rv64_thead_c906_cpu_init),
74
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64, rv64_tt_ascalon_cpu_init),
75
DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, MXL_RV64, rv64_veyron_v1_cpu_init),
76
+ DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU,
77
+ MXL_RV64, rv64_xiangshan_nanhu_cpu_init),
78
#ifdef CONFIG_TCG
79
DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, MXL_RV128, rv128_base_cpu_init),
80
#endif /* CONFIG_TCG */
44
--
81
--
45
2.39.2
82
2.47.1
diff view generated by jsdifflib