1 | The following changes since commit 9468484fe904ab4691de6d9c34616667f377ceac: | 1 | The following changes since commit 8032c78e556cd0baec111740a6c636863f9bd7c8: |
---|---|---|---|
2 | 2 | ||
3 | Merge tag 'block-pull-request' of https://gitlab.com/stefanha/qemu into staging (2024-01-09 10:32:23 +0000) | 3 | Merge tag 'firmware-20241216-pull-request' of https://gitlab.com/kraxel/qemu into staging (2024-12-16 14:20:33 -0500) |
4 | 4 | ||
5 | are available in the Git repository at: | 5 | are available in the Git repository at: |
6 | 6 | ||
7 | https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20240110 | 7 | https://github.com/alistair23/qemu.git tags/pull-riscv-to-apply-20241219-1 |
8 | 8 | ||
9 | for you to fetch changes up to 71b76da33a1558bcd59100188f5753737ef6fa21: | 9 | for you to fetch changes up to 5632d271be16b5e769342d54198c4359658abcb7: |
10 | 10 | ||
11 | target/riscv: Ensure mideleg is set correctly on reset (2024-01-10 18:47:47 +1000) | 11 | target/riscv: add support for RV64 Xiangshan Nanhu CPU (2024-12-18 11:07:59 +1000) |
12 | 12 | ||
13 | ---------------------------------------------------------------- | 13 | ---------------------------------------------------------------- |
14 | RISC-V PR for 9.0 | 14 | RISC-V PR for 10.0 |
15 | 15 | ||
16 | * Make vector whole-register move (vmv) depend on vtype register | 16 | * Correct the validness check of iova |
17 | * Fix th.dcache.cval1 priviledge check | 17 | * Fix APLIC in_clrip and clripnum write emulation |
18 | * Don't allow write mstatus_vs without RVV | 18 | * Support riscv-iommu-sys device |
19 | * Use hwaddr instead of target_ulong for RV32 | 19 | * Add Tenstorrent Ascalon CPU |
20 | * Fix machine IDs QOM getters\ | 20 | * Add AIA userspace irqchip_split support |
21 | * Fix KVM reg id sizes | 21 | * Add Microblaze V generic board |
22 | * ACPI: Enable AIA, PLIC and update RHCT | 22 | * Upgrade ACPI SPCR table to support SPCR table revision 4 format |
23 | * Fix the interrupts-extended property format of PLIC | 23 | * Remove tswap64() calls from HTIF |
24 | * Add support for Zacas extension | 24 | * Support 64-bit address of initrd |
25 | * Add amocas.[w,d,q] instructions | 25 | * Introduce svukte ISA extension |
26 | * Document acpi parameter of virt machine | 26 | * Support ssstateen extension |
27 | * RVA22 profiles support | 27 | * Support for RV64 Xiangshan Nanhu CPU |
28 | * Remove group setting of KVM AIA if the machine only has 1 socket | ||
29 | * Add RVV CSRs to KVM | ||
30 | * sifive_u: Update S-mode U-Boot image build instructions | ||
31 | * Upgrade OpenSBI from v1.3.1 to v1.4 | ||
32 | * pmp: Ignore writes when RW=01 and MML=0 | ||
33 | * Assert that the CSR numbers will be correct | ||
34 | * Don't adjust vscause for exceptions | ||
35 | * Ensure mideleg is set correctly on reset | ||
36 | 28 | ||
37 | ---------------------------------------------------------------- | 29 | ---------------------------------------------------------------- |
38 | Alistair Francis (3): | 30 | Anton Blanchard (1): |
39 | target/riscv: Assert that the CSR numbers will be correct | 31 | target/riscv: Add Tenstorrent Ascalon CPU |
40 | target/riscv: Don't adjust vscause for exceptions | ||
41 | target/riscv: Ensure mideleg is set correctly on reset | ||
42 | 32 | ||
43 | Bin Meng (2): | 33 | Daniel Henrique Barboza (15): |
44 | docs/system/riscv: sifive_u: Update S-mode U-Boot image build instructions | 34 | hw/riscv/riscv-iommu.c: add riscv_iommu_instance_init() |
45 | roms/opensbi: Upgrade from v1.3.1 to v1.4 | 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 | ||
46 | 49 | ||
47 | Daniel Henrique Barboza (36): | 50 | Fea.Wang (6): |
48 | target/riscv/cpu.c: fix machine IDs getters | 51 | target/riscv: Add svukte extension capability variable |
49 | target/riscv/kvm: change KVM_REG_RISCV_FP_F to u32 | 52 | target/riscv: Support senvcfg[UKTE] bit when svukte extension is enabled |
50 | target/riscv/kvm: change KVM_REG_RISCV_FP_D to u64 | 53 | target/riscv: Support hstatus[HUKTE] bit when svukte extension is enabled |
51 | target/riscv/kvm: change timer regs size to u64 | 54 | target/riscv: Check memory access to meet svukte rule |
52 | target/riscv/kvm: add RISCV_CONFIG_REG() | 55 | target/riscv: Expose svukte ISA extension |
53 | target/riscv/kvm: rename riscv_reg_id() to riscv_reg_id_ulong() | 56 | target/riscv: Check svukte is not enabled in RV32 |
54 | target/riscv: create TYPE_RISCV_VENDOR_CPU | ||
55 | target/riscv/tcg: do not use "!generic" CPU checks | ||
56 | target/riscv/tcg: update priv_ver on user_set extensions | ||
57 | target/riscv: add rv64i CPU | ||
58 | target/riscv: add zicbop extension flag | ||
59 | target/riscv/tcg: add 'zic64b' support | ||
60 | riscv-qmp-cmds.c: expose named features in cpu_model_expansion | ||
61 | target/riscv: add rva22u64 profile definition | ||
62 | target/riscv/kvm: add 'rva22u64' flag as unavailable | ||
63 | target/riscv/tcg: add user flag for profile support | ||
64 | target/riscv/tcg: add MISA user options hash | ||
65 | target/riscv/tcg: add riscv_cpu_write_misa_bit() | ||
66 | target/riscv/tcg: handle profile MISA bits | ||
67 | target/riscv/tcg: add hash table insert helpers | ||
68 | target/riscv/tcg: honor user choice for G MISA bits | ||
69 | target/riscv/tcg: validate profiles during finalize | ||
70 | riscv-qmp-cmds.c: add profile flags in cpu-model-expansion | ||
71 | target/riscv: add 'rva22u64' CPU | ||
72 | target/riscv: implement svade | ||
73 | target/riscv: add priv ver restriction to profiles | ||
74 | target/riscv/cpu.c: finalize satp_mode earlier | ||
75 | target/riscv/cpu.c: add riscv_cpu_is_32bit() | ||
76 | target/riscv: add satp_mode profile support | ||
77 | target/riscv: add 'parent' in profile description | ||
78 | target/riscv: add RVA22S64 profile | ||
79 | target/riscv: add rva22s64 cpu | ||
80 | linux-headers: Update to Linux v6.7-rc5 | ||
81 | linux-headers: riscv: add ptrace.h | ||
82 | target/riscv/kvm: do PR_RISCV_V_SET_CONTROL during realize() | ||
83 | target/riscv/kvm: add RVV and Vector CSR regs | ||
84 | 57 | ||
85 | Heinrich Schuchardt (1): | 58 | Jason Chien (1): |
86 | docs/system/riscv: document acpi parameter of virt machine | 59 | hw/riscv/riscv-iommu.c: Correct the validness check of iova |
87 | 60 | ||
88 | Ivan Klokov (2): | 61 | Jim Shu (3): |
89 | target/riscv/pmp: Use hwaddr instead of target_ulong for RV32 | 62 | hw/riscv: Support to load DTB after 3GB memory on 64-bit system. |
90 | target/riscv: pmp: Ignore writes when RW=01 and MML=0 | 63 | hw/riscv: Add a new struct RISCVBootInfo |
64 | hw/riscv: Add the checking if DTB overlaps to kernel or initrd | ||
91 | 65 | ||
92 | LIU Zhiwei (2): | 66 | MollyChen (1): |
93 | target/riscv: Fix th.dcache.cval1 priviledge check | 67 | target/riscv: add support for RV64 Xiangshan Nanhu CPU |
94 | target/riscv: Not allow write mstatus_vs without RVV | ||
95 | 68 | ||
96 | Max Chou (2): | 69 | Philippe Mathieu-Daudé (5): |
97 | target/riscv: Add vill check for whole vector register move instructions | 70 | MAINTAINERS: Cover RISC-V HTIF interface |
98 | target/riscv: The whole vector register move instructions depend on vsew | 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' | ||
99 | 75 | ||
100 | Rob Bradford (1): | 76 | Sai Pavan Boddu (1): |
101 | disas/riscv: Add amocas.[w,d,q] instructions | 77 | hw/riscv: Add Microblaze V generic board |
102 | 78 | ||
103 | Sunil V L (13): | 79 | Sia Jee Heng (3): |
104 | hw/arm/virt-acpi-build.c: Migrate fw_cfg creation to common location | 80 | qtest: allow SPCR acpi table changes |
105 | hw/arm/virt-acpi-build.c: Migrate virtio creation to common location | 81 | hw/acpi: Upgrade ACPI SPCR table to support SPCR table revision 4 format |
106 | hw/i386/acpi-microvm.c: Use common function to add virtio in DSDT | 82 | tests/qtest/bios-tables-test: Update virt SPCR golden reference for RISC-V |
107 | hw/riscv: virt: Make few IMSIC macros and functions public | ||
108 | hw/riscv/virt-acpi-build.c: Add AIA support in RINTC | ||
109 | hw/riscv/virt-acpi-build.c: Add IMSIC in the MADT | ||
110 | hw/riscv/virt-acpi-build.c: Add APLIC in the MADT | ||
111 | hw/riscv/virt-acpi-build.c: Add CMO information in RHCT | ||
112 | hw/riscv/virt-acpi-build.c: Add MMU node in RHCT | ||
113 | hw/pci-host/gpex: Define properties for MMIO ranges | ||
114 | hw/riscv/virt: Update GPEX MMIO related properties | ||
115 | hw/riscv/virt-acpi-build.c: Add IO controllers and devices | ||
116 | hw/riscv/virt-acpi-build.c: Add PLIC in MADT | ||
117 | 83 | ||
118 | Weiwei Li (1): | 84 | Sunil V L (1): |
119 | target/riscv: Add support for Zacas extension | 85 | hw/riscv/virt: Add IOMMU as platform device if the option is set |
120 | 86 | ||
121 | Yong-Xuan Wang (2): | 87 | Tomasz Jeznach (1): |
122 | hw/riscv/virt.c: fix the interrupts-extended property format of PLIC | 88 | hw/riscv: add riscv-iommu-sys platform device |
123 | target/riscv/kvm.c: remove group setting of KVM AIA if the machine only has 1 socket | ||
124 | 89 | ||
125 | docs/system/riscv/sifive_u.rst | 33 +- | 90 | Yong-Xuan Wang (1): |
126 | docs/system/riscv/virt.rst | 5 + | 91 | hw/intc/riscv_aplic: Fix APLIC in_clrip and clripnum write emulation |
127 | include/hw/nvram/fw_cfg_acpi.h | 15 + | 92 | |
128 | include/hw/pci-host/gpex.h | 28 +- | 93 | MAINTAINERS | 8 + |
129 | include/hw/riscv/virt.h | 26 ++ | 94 | docs/specs/index.rst | 1 + |
130 | include/hw/virtio/virtio-acpi.h | 16 + | 95 | docs/specs/riscv-aia.rst | 83 ++++++++++ |
131 | include/standard-headers/drm/drm_fourcc.h | 2 + | 96 | docs/specs/riscv-iommu.rst | 30 +++- |
132 | include/standard-headers/linux/pci_regs.h | 24 +- | 97 | docs/system/riscv/microblaze-v-generic.rst | 42 +++++ |
133 | include/standard-headers/linux/vhost_types.h | 7 + | 98 | docs/system/riscv/virt.rst | 17 ++ |
134 | include/standard-headers/linux/virtio_config.h | 5 + | 99 | docs/system/target-riscv.rst | 1 + |
135 | include/standard-headers/linux/virtio_pci.h | 11 + | 100 | hw/riscv/riscv-iommu-bits.h | 6 + |
136 | linux-headers/asm-arm64/kvm.h | 32 ++ | 101 | hw/riscv/riscv-iommu.h | 5 + |
137 | linux-headers/asm-generic/unistd.h | 14 +- | 102 | include/hw/acpi/acpi-defs.h | 7 +- |
138 | linux-headers/asm-loongarch/bitsperlong.h | 1 + | 103 | include/hw/acpi/aml-build.h | 2 +- |
139 | linux-headers/asm-loongarch/kvm.h | 108 ++++++ | 104 | include/hw/intc/riscv_aplic.h | 8 + |
140 | linux-headers/asm-loongarch/mman.h | 1 + | 105 | include/hw/riscv/boot.h | 28 +++- |
141 | linux-headers/asm-loongarch/unistd.h | 5 + | 106 | include/hw/riscv/iommu.h | 10 +- |
142 | linux-headers/asm-mips/unistd_n32.h | 4 + | 107 | include/hw/riscv/virt.h | 6 +- |
143 | linux-headers/asm-mips/unistd_n64.h | 4 + | 108 | target/riscv/cpu-qom.h | 2 + |
144 | linux-headers/asm-mips/unistd_o32.h | 4 + | 109 | target/riscv/cpu_bits.h | 2 + |
145 | linux-headers/asm-powerpc/unistd_32.h | 4 + | 110 | target/riscv/cpu_cfg.h | 2 + |
146 | linux-headers/asm-powerpc/unistd_64.h | 4 + | 111 | target/riscv/internals.h | 3 + |
147 | linux-headers/asm-riscv/kvm.h | 12 + | 112 | target/riscv/vector_internals.h | 1 + |
148 | linux-headers/asm-riscv/ptrace.h | 132 +++++++ | 113 | hw/acpi/aml-build.c | 20 ++- |
149 | linux-headers/asm-s390/unistd_32.h | 4 + | 114 | hw/arm/virt-acpi-build.c | 8 +- |
150 | linux-headers/asm-s390/unistd_64.h | 4 + | 115 | hw/char/riscv_htif.c | 15 +- |
151 | linux-headers/asm-x86/unistd_32.h | 4 + | 116 | hw/intc/riscv_aplic.c | 74 +++++++-- |
152 | linux-headers/asm-x86/unistd_64.h | 3 + | 117 | hw/loongarch/acpi-build.c | 6 +- |
153 | linux-headers/asm-x86/unistd_x32.h | 3 + | 118 | hw/riscv/boot.c | 100 +++++++---- |
154 | linux-headers/linux/iommufd.h | 180 +++++++++- | 119 | hw/riscv/microblaze-v-generic.c | 184 +++++++++++++++++++++ |
155 | linux-headers/linux/kvm.h | 11 + | 120 | hw/riscv/microchip_pfsoc.c | 13 +- |
156 | linux-headers/linux/psp-sev.h | 1 + | 121 | hw/riscv/opentitan.c | 4 +- |
157 | linux-headers/linux/stddef.h | 9 +- | 122 | hw/riscv/riscv-iommu-pci.c | 21 +++ |
158 | linux-headers/linux/userfaultfd.h | 9 +- | 123 | hw/riscv/riscv-iommu-sys.c | 256 +++++++++++++++++++++++++++++ |
159 | linux-headers/linux/vfio.h | 47 ++- | 124 | hw/riscv/riscv-iommu.c | 137 ++++++++++----- |
160 | linux-headers/linux/vhost.h | 8 + | 125 | hw/riscv/sifive_e.c | 4 +- |
161 | target/riscv/cpu-qom.h | 5 + | 126 | hw/riscv/sifive_u.c | 18 +- |
162 | target/riscv/cpu.h | 18 + | 127 | hw/riscv/spike.c | 14 +- |
163 | target/riscv/cpu_cfg.h | 5 + | 128 | hw/riscv/virt-acpi-build.c | 12 +- |
164 | target/riscv/pmp.h | 8 +- | 129 | hw/riscv/virt.c | 159 +++++++++++++++--- |
165 | target/riscv/insn32.decode | 6 + | 130 | target/riscv/cpu.c | 101 ++++++++++++ |
166 | disas/riscv.c | 9 + | 131 | target/riscv/cpu_helper.c | 55 +++++++ |
167 | hw/arm/virt-acpi-build.c | 51 +-- | 132 | target/riscv/csr.c | 7 + |
168 | hw/i386/acpi-microvm.c | 15 +- | 133 | target/riscv/kvm/kvm-cpu.c | 43 ++--- |
169 | hw/nvram/fw_cfg-acpi.c | 23 ++ | 134 | target/riscv/tcg/tcg-cpu.c | 27 ++- |
170 | hw/pci-host/gpex-acpi.c | 13 + | 135 | hw/riscv/Kconfig | 8 + |
171 | hw/pci-host/gpex.c | 12 + | 136 | hw/riscv/meson.build | 3 +- |
172 | hw/riscv/virt-acpi-build.c | 323 ++++++++++++++++-- | 137 | hw/riscv/trace-events | 4 + |
173 | hw/riscv/virt.c | 124 +++---- | 138 | tests/data/acpi/riscv64/virt/SPCR | Bin 80 -> 90 bytes |
174 | hw/virtio/virtio-acpi.c | 33 ++ | 139 | 46 files changed, 1380 insertions(+), 177 deletions(-) |
175 | target/riscv/cpu.c | 223 ++++++++++-- | 140 | create mode 100644 docs/specs/riscv-aia.rst |
176 | target/riscv/cpu_helper.c | 4 +- | 141 | create mode 100644 docs/system/riscv/microblaze-v-generic.rst |
177 | target/riscv/csr.c | 10 +- | 142 | create mode 100644 hw/riscv/microblaze-v-generic.c |
178 | target/riscv/kvm/kvm-cpu.c | 250 ++++++++++---- | 143 | create mode 100644 hw/riscv/riscv-iommu-sys.c |
179 | target/riscv/pmp.c | 28 +- | 144 | |
180 | target/riscv/riscv-qmp-cmds.c | 44 ++- | ||
181 | target/riscv/tcg/tcg-cpu.c | 455 ++++++++++++++++++++++--- | ||
182 | target/riscv/translate.c | 1 + | ||
183 | target/riscv/insn_trans/trans_rvv.c.inc | 8 +- | ||
184 | target/riscv/insn_trans/trans_rvzacas.c.inc | 150 ++++++++ | ||
185 | target/riscv/insn_trans/trans_xthead.c.inc | 2 +- | ||
186 | hw/nvram/meson.build | 1 + | ||
187 | hw/riscv/Kconfig | 1 + | ||
188 | hw/virtio/meson.build | 1 + | ||
189 | pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | Bin 135376 -> 267416 bytes | ||
190 | pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | Bin 138368 -> 270808 bytes | ||
191 | roms/opensbi | 2 +- | ||
192 | scripts/update-linux-headers.sh | 3 + | ||
193 | 68 files changed, 2248 insertions(+), 360 deletions(-) | ||
194 | create mode 100644 include/hw/nvram/fw_cfg_acpi.h | ||
195 | create mode 100644 include/hw/virtio/virtio-acpi.h | ||
196 | create mode 100644 linux-headers/asm-loongarch/bitsperlong.h | ||
197 | create mode 100644 linux-headers/asm-loongarch/kvm.h | ||
198 | create mode 100644 linux-headers/asm-loongarch/mman.h | ||
199 | create mode 100644 linux-headers/asm-loongarch/unistd.h | ||
200 | create mode 100644 linux-headers/asm-riscv/ptrace.h | ||
201 | create mode 100644 hw/nvram/fw_cfg-acpi.c | ||
202 | create mode 100644 hw/virtio/virtio-acpi.c | ||
203 | create mode 100644 target/riscv/insn_trans/trans_rvzacas.c.inc | diff view generated by jsdifflib |
1 | From: Bin Meng <bmeng@tinylab.org> | 1 | From: Jason Chien <jason.chien@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Currently, the documentation outlines the process for building the | 3 | From RISCV IOMMU spec section 2.1.3: |
4 | S-mode U-Boot image using `make menuconfig` and manual actions within | 4 | When SXL is 1, the following rules apply: |
5 | the menuconfig UI. However, this approach is fragile due to Kconfig | 5 | - If the first-stage is not Bare, then a page fault corresponding to the |
6 | options potentially changing across different releases. For example, | 6 | original access type occurs if the IOVA has bits beyond bit 31 set to 1. |
7 | CONFIG_OF_PRIOR_STAGE has been replaced by CONFIG_BOARD since v2022.01 | 7 | - If the second-stage is not Bare, then a guest page fault corresponding |
8 | release, and CONFIG_TEXT_BASE has been moved to the 'General setup' | 8 | to the original access type occurs if the incoming GPA has bits beyond bit |
9 | menu from the 'Boot options' menu in v2024.01 release. | 9 | 33 set to 1. |
10 | 10 | ||
11 | This update aims to make the S-mode U-Boot image build instructions | 11 | From RISCV IOMMU spec section 2.3 step 17: |
12 | future-proof. It leverages the 'config' script provided in the U-Boot | 12 | Use the process specified in Section "Two-Stage Address Translation" of |
13 | source tree to edit the .config file, followed by a `make olddefconfig`. | 13 | the RISC-V Privileged specification to determine the GPA accessed by the |
14 | transaction. | ||
14 | 15 | ||
15 | Validated with U-Boot v2024.01 release. | 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. | ||
16 | 20 | ||
17 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | 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. | ||
18 | 26 | ||
19 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 27 | Signed-off-by: Jason Chien <jason.chien@sifive.com> |
20 | Message-ID: <20240104071523.273702-1-bmeng@tinylab.org> | 28 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
29 | Message-ID: <20241114065617.25133-1-jason.chien@sifive.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 30 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
22 | --- | 31 | --- |
23 | docs/system/riscv/sifive_u.rst | 33 ++++++++++++--------------------- | 32 | hw/riscv/riscv-iommu.c | 23 ++++++++++++++++++++--- |
24 | 1 file changed, 12 insertions(+), 21 deletions(-) | 33 | 1 file changed, 20 insertions(+), 3 deletions(-) |
25 | 34 | ||
26 | diff --git a/docs/system/riscv/sifive_u.rst b/docs/system/riscv/sifive_u.rst | 35 | diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c |
27 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
28 | --- a/docs/system/riscv/sifive_u.rst | 37 | --- a/hw/riscv/riscv-iommu.c |
29 | +++ b/docs/system/riscv/sifive_u.rst | 38 | +++ b/hw/riscv/riscv-iommu.c |
30 | @@ -XXX,XX +XXX,XX @@ command line options with ``qemu-system-riscv32``. | 39 | @@ -XXX,XX +XXX,XX @@ static int riscv_iommu_spa_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx, |
31 | Running U-Boot | 40 | |
32 | -------------- | 41 | /* Address range check before first level lookup */ |
33 | 42 | if (!sc[pass].step) { | |
34 | -U-Boot mainline v2021.07 release is tested at the time of writing. To build a | 43 | - const uint64_t va_mask = (1ULL << (va_skip + va_bits)) - 1; |
35 | +U-Boot mainline v2024.01 release is tested at the time of writing. To build a | 44 | - if ((addr & va_mask) != addr) { |
36 | U-Boot mainline bootloader that can be booted by the ``sifive_u`` machine, use | 45 | - return RISCV_IOMMU_FQ_CAUSE_DMA_DISABLED; |
37 | the sifive_unleashed_defconfig with similar commands as described above for | 46 | + const uint64_t va_len = va_skip + va_bits; |
38 | Linux: | 47 | + const uint64_t va_mask = (1ULL << va_len) - 1; |
39 | @@ -XXX,XX +XXX,XX @@ configuration of U-Boot: | 48 | + |
40 | 49 | + if (pass == S_STAGE && va_len > 32) { | |
41 | $ export CROSS_COMPILE=riscv64-linux- | 50 | + target_ulong mask, masked_msbs; |
42 | $ make sifive_unleashed_defconfig | 51 | + |
43 | - $ make menuconfig | 52 | + mask = (1L << (TARGET_LONG_BITS - (va_len - 1))) - 1; |
44 | - | 53 | + masked_msbs = (addr >> (va_len - 1)) & mask; |
45 | -then manually select the following configuration: | 54 | + |
46 | - | 55 | + if (masked_msbs != 0 && masked_msbs != mask) { |
47 | - * Device Tree Control ---> Provider of DTB for DT Control ---> Prior Stage bootloader DTB | 56 | + return (iotlb->perm & IOMMU_WO) ? |
48 | - | 57 | + RISCV_IOMMU_FQ_CAUSE_WR_FAULT_S : |
49 | -and unselect the following configuration: | 58 | + RISCV_IOMMU_FQ_CAUSE_RD_FAULT_S; |
50 | - | 59 | + } |
51 | - * Library routines ---> Allow access to binman information in the device tree | 60 | + } else { |
52 | + $ ./scripts/config --enable OF_BOARD | 61 | + if ((addr & va_mask) != addr) { |
53 | + $ ./scripts/config --disable BINMAN_FDT | 62 | + return (iotlb->perm & IOMMU_WO) ? |
54 | + $ ./scripts/config --disable SPL | 63 | + RISCV_IOMMU_FQ_CAUSE_WR_FAULT_VS : |
55 | + $ make olddefconfig | 64 | + RISCV_IOMMU_FQ_CAUSE_RD_FAULT_VS; |
56 | 65 | + } | |
57 | This changes U-Boot to use the QEMU generated device tree blob, and bypass | 66 | } |
58 | running the U-Boot SPL stage. | 67 | } |
59 | @@ -XXX,XX +XXX,XX @@ It's possible to create a 32-bit U-Boot S-mode image as well. | ||
60 | |||
61 | $ export CROSS_COMPILE=riscv64-linux- | ||
62 | $ make sifive_unleashed_defconfig | ||
63 | - $ make menuconfig | ||
64 | - | ||
65 | -then manually update the following configuration in U-Boot: | ||
66 | - | ||
67 | - * Device Tree Control ---> Provider of DTB for DT Control ---> Prior Stage bootloader DTB | ||
68 | - * RISC-V architecture ---> Base ISA ---> RV32I | ||
69 | - * Boot options ---> Boot images ---> Text Base ---> 0x80400000 | ||
70 | - | ||
71 | -and unselect the following configuration: | ||
72 | - | ||
73 | - * Library routines ---> Allow access to binman information in the device tree | ||
74 | + $ ./scripts/config --disable ARCH_RV64I | ||
75 | + $ ./scripts/config --enable ARCH_RV32I | ||
76 | + $ ./scripts/config --set-val TEXT_BASE 0x80400000 | ||
77 | + $ ./scripts/config --enable OF_BOARD | ||
78 | + $ ./scripts/config --disable BINMAN_FDT | ||
79 | + $ ./scripts/config --disable SPL | ||
80 | + $ make olddefconfig | ||
81 | |||
82 | Use the same command line options to boot the 32-bit U-Boot S-mode image: | ||
83 | 68 | ||
84 | -- | 69 | -- |
85 | 2.43.0 | 70 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | We'll add a new bare CPU type that won't have any default priv_ver. This | 3 | In the section "4.7 Precise effects on interrupt-pending bits" |
4 | means that the CPU will default to priv_ver = 0, i.e. 1.10.0. | 4 | of the RISC-V AIA specification defines that: |
5 | 5 | ||
6 | At the same we'll allow these CPUs to enable extensions at will, but | 6 | "If the source mode is Level1 or Level0 and the interrupt domain |
7 | then, if the extension has a priv_ver newer than 1.10, we'll end up | 7 | is configured in MSI delivery mode (domaincfg.DM = 1): |
8 | disabling it. Users will then need to manually set priv_ver to something | 8 | The pending bit is cleared whenever the rectified input value is |
9 | other than 1.10 to enable the extensions they want, which is not ideal. | 9 | low, when the interrupt is forwarded by MSI, or by a relevant |
10 | write to an in_clrip register or to clripnum." | ||
10 | 11 | ||
11 | Change the setter() of extensions to allow user enabled extensions to | 12 | Update the riscv_aplic_set_pending() to match the spec. |
12 | bump the priv_ver of the CPU. This will make it convenient for users to | ||
13 | enable extensions for CPUs that doesn't set a default priv_ver. | ||
14 | 13 | ||
15 | This change does not affect any existing CPU: vendor CPUs does not allow | 14 | Fixes: bf31cf06eb ("hw/intc/riscv_aplic: Fix setipnum_le write emulation for APLIC MSI-mode") |
16 | extensions to be enabled, and generic CPUs are already set to priv_ver | 15 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> |
17 | LATEST. | 16 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
18 | 17 | Message-ID: <20241029085349.30412-1-yongxuan.wang@sifive.com> | |
19 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
20 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
21 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | Message-ID: <20231218125334.37184-4-dbarboza@ventanamicro.com> | ||
23 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 18 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
24 | --- | 19 | --- |
25 | target/riscv/tcg/tcg-cpu.c | 32 ++++++++++++++++++++++++++++++++ | 20 | hw/intc/riscv_aplic.c | 6 +++++- |
26 | 1 file changed, 32 insertions(+) | 21 | 1 file changed, 5 insertions(+), 1 deletion(-) |
27 | 22 | ||
28 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 23 | diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c |
29 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
30 | --- a/target/riscv/tcg/tcg-cpu.c | 25 | --- a/hw/intc/riscv_aplic.c |
31 | +++ b/target/riscv/tcg/tcg-cpu.c | 26 | +++ b/hw/intc/riscv_aplic.c |
32 | @@ -XXX,XX +XXX,XX @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset) | 27 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic, |
33 | g_assert_not_reached(); | 28 | |
34 | } | 29 | if ((sm == APLIC_SOURCECFG_SM_LEVEL_HIGH) || |
35 | 30 | (sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) { | |
36 | +static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env, | 31 | - if (!aplic->msimode || (aplic->msimode && !pending)) { |
37 | + uint32_t ext_offset) | 32 | + if (!aplic->msimode) { |
38 | +{ | ||
39 | + int ext_priv_ver; | ||
40 | + | ||
41 | + if (env->priv_ver == PRIV_VERSION_LATEST) { | ||
42 | + return; | ||
43 | + } | ||
44 | + | ||
45 | + ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset); | ||
46 | + | ||
47 | + if (env->priv_ver < ext_priv_ver) { | ||
48 | + /* | ||
49 | + * Note: the 'priv_spec' command line option, if present, | ||
50 | + * will take precedence over this priv_ver bump. | ||
51 | + */ | ||
52 | + env->priv_ver = ext_priv_ver; | ||
53 | + } | ||
54 | +} | ||
55 | + | ||
56 | static void cpu_cfg_ext_auto_update(RISCVCPU *cpu, uint32_t ext_offset, | ||
57 | bool value) | ||
58 | { | ||
59 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name, | ||
60 | return; | 33 | return; |
61 | } | 34 | } |
62 | 35 | + if (aplic->msimode && !pending) { | |
63 | + if (misa_bit == RVH && env->priv_ver < PRIV_VERSION_1_12_0) { | 36 | + goto noskip_write_pending; |
64 | + /* | ||
65 | + * Note: the 'priv_spec' command line option, if present, | ||
66 | + * will take precedence over this priv_ver bump. | ||
67 | + */ | ||
68 | + env->priv_ver = PRIV_VERSION_1_12_0; | ||
69 | + } | 37 | + } |
70 | + | 38 | if ((aplic->state[irq] & APLIC_ISTATE_INPUT) && |
71 | env->misa_ext |= misa_bit; | 39 | (sm == APLIC_SOURCECFG_SM_LEVEL_LOW)) { |
72 | env->misa_ext_mask |= misa_bit; | 40 | return; |
73 | } else { | 41 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_set_pending(RISCVAPLICState *aplic, |
74 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name, | 42 | } |
75 | return; | ||
76 | } | 43 | } |
77 | 44 | ||
78 | + if (value) { | 45 | +noskip_write_pending: |
79 | + cpu_bump_multi_ext_priv_ver(&cpu->env, multi_ext_cfg->offset); | 46 | riscv_aplic_set_pending_raw(aplic, irq, pending); |
80 | + } | ||
81 | + | ||
82 | isa_ext_update_enabled(cpu, multi_ext_cfg->offset, value); | ||
83 | } | 47 | } |
84 | 48 | ||
85 | -- | 49 | -- |
86 | 2.43.0 | 50 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | The RVA22S64 profile consists of the following: | 3 | Move all the static initializion of the device to an init() function, |
4 | leaving only the dynamic initialization to be done during realize. | ||
4 | 5 | ||
5 | - all mandatory extensions of RVA22U64; | 6 | With this change s->cap is initialized with RISCV_IOMMU_CAP_DBG during |
6 | - priv spec v1.12.0; | 7 | init(), and realize() will increment s->cap with the extra caps. |
7 | - satp mode sv39; | ||
8 | - Ssccptr, a cache related named feature that we're assuming always | ||
9 | enable since we don't implement a cache; | ||
10 | - Other named features already implemented: Sstvecd, Sstvala, | ||
11 | Sscounterenw; | ||
12 | - the new Svade named feature that was recently added. | ||
13 | 8 | ||
14 | Most of the work is already done, so this patch is enough to implement | 9 | This will allow callers to add IOMMU capabilities before the |
15 | the profile. | 10 | realization. |
16 | |||
17 | After this patch, the 'rva22s64' user flag alone can be used with the | ||
18 | rva64i CPU to boot Linux: | ||
19 | |||
20 | -cpu rv64i,rva22s64=true | ||
21 | |||
22 | This is the /proc/cpuinfo with this profile enabled: | ||
23 | |||
24 | # cat /proc/cpuinfo | ||
25 | processor : 0 | ||
26 | hart : 0 | ||
27 | isa : rv64imafdc_zicbom_zicbop_zicboz_zicntr_zicsr_zifencei_zihintpause_zihpm_zfhmin_zca_zcd_zba_zbb_zbs_zkt_svinval_svpbmt | ||
28 | mmu : sv39 | ||
29 | 11 | ||
30 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 12 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
31 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
32 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
33 | Message-ID: <20231218125334.37184-26-dbarboza@ventanamicro.com> | 14 | Message-ID: <20241106133407.604587-2-dbarboza@ventanamicro.com> |
34 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
35 | --- | 16 | --- |
36 | target/riscv/cpu.c | 32 ++++++++++++++++++++++++++++++++ | 17 | hw/riscv/riscv-iommu.c | 71 +++++++++++++++++++++++------------------- |
37 | 1 file changed, 32 insertions(+) | 18 | 1 file changed, 39 insertions(+), 32 deletions(-) |
38 | 19 | ||
39 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 20 | diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c |
40 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/target/riscv/cpu.c | 22 | --- a/hw/riscv/riscv-iommu.c |
42 | +++ b/target/riscv/cpu.c | 23 | +++ b/hw/riscv/riscv-iommu.c |
43 | @@ -XXX,XX +XXX,XX @@ static RISCVCPUProfile RVA22U64 = { | 24 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps riscv_iommu_trap_ops = { |
44 | } | 25 | } |
45 | }; | 26 | }; |
46 | 27 | ||
47 | +/* | 28 | +static void riscv_iommu_instance_init(Object *obj) |
48 | + * As with RVA22U64, RVA22S64 also defines 'named features'. | 29 | +{ |
49 | + * | 30 | + RISCVIOMMUState *s = RISCV_IOMMU(obj); |
50 | + * Cache related features that we consider enabled since we don't | ||
51 | + * implement cache: Ssccptr | ||
52 | + * | ||
53 | + * Other named features that we already implement: Sstvecd, Sstvala, | ||
54 | + * Sscounterenw | ||
55 | + * | ||
56 | + * Named features that we need to enable: svade | ||
57 | + * | ||
58 | + * The remaining features/extensions comes from RVA22U64. | ||
59 | + */ | ||
60 | +static RISCVCPUProfile RVA22S64 = { | ||
61 | + .parent = &RVA22U64, | ||
62 | + .name = "rva22s64", | ||
63 | + .misa_ext = RVS, | ||
64 | + .priv_spec = PRIV_VERSION_1_12_0, | ||
65 | + .satp_mode = VM_1_10_SV39, | ||
66 | + .ext_offsets = { | ||
67 | + /* rva22s64 exts */ | ||
68 | + CPU_CFG_OFFSET(ext_zifencei), CPU_CFG_OFFSET(ext_svpbmt), | ||
69 | + CPU_CFG_OFFSET(ext_svinval), | ||
70 | + | 31 | + |
71 | + /* rva22s64 named features */ | 32 | + /* Enable translation debug interface */ |
72 | + CPU_CFG_OFFSET(svade), | 33 | + s->cap = RISCV_IOMMU_CAP_DBG; |
73 | + | 34 | + |
74 | + RISCV_PROFILE_EXT_LIST_END | 35 | + /* Report QEMU target physical address space limits */ |
75 | + } | 36 | + s->cap = set_field(s->cap, RISCV_IOMMU_CAP_PAS, |
76 | +}; | 37 | + TARGET_PHYS_ADDR_SPACE_BITS); |
77 | + | 38 | + |
78 | RISCVCPUProfile *riscv_profiles[] = { | 39 | + /* TODO: method to report supported PID bits */ |
79 | &RVA22U64, | 40 | + s->pid_bits = 8; /* restricted to size of MemTxAttrs.pid */ |
80 | + &RVA22S64, | 41 | + s->cap |= RISCV_IOMMU_CAP_PD8; |
81 | NULL, | 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, | ||
82 | }; | 130 | }; |
83 | 131 | ||
84 | -- | 132 | -- |
85 | 2.43.0 | 133 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Linux RISC-V vector documentation (Document/arch/riscv/vector.rst) | 3 | Interrupt Generation Support (IGS) is a capability that is tied to the |
4 | mandates a prctl() in order to allow an userspace thread to use the | 4 | interrupt deliver mechanism, not with the core IOMMU emulation. We |
5 | Vector extension from the host. | 5 | should allow device implementations to set IGS as they wish. |
6 | 6 | ||
7 | This is something to be done in realize() time, after init(), when we | 7 | A new helper is added to make it easier for device impls to set IGS. Use |
8 | already decided whether we're using RVV or not. We don't have a | 8 | it in our existing IOMMU device (riscv-iommu-pci) to set |
9 | realize() callback for KVM yet, so add kvm_cpu_realize() and enable RVV | 9 | RISCV_IOMMU_CAPS_IGS_MSI. |
10 | for the thread via PR_RISCV_V_SET_CONTROL. | ||
11 | 10 | ||
12 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 11 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
14 | Message-ID: <20231218204321.75757-4-dbarboza@ventanamicro.com> | 13 | Message-ID: <20241106133407.604587-3-dbarboza@ventanamicro.com> |
15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
16 | --- | 15 | --- |
17 | target/riscv/kvm/kvm-cpu.c | 29 +++++++++++++++++++++++++++++ | 16 | hw/riscv/riscv-iommu-bits.h | 6 ++++++ |
18 | 1 file changed, 29 insertions(+) | 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(+) | ||
19 | 21 | ||
20 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | 22 | diff --git a/hw/riscv/riscv-iommu-bits.h b/hw/riscv/riscv-iommu-bits.h |
21 | index XXXXXXX..XXXXXXX 100644 | 23 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/target/riscv/kvm/kvm-cpu.c | 24 | --- a/hw/riscv/riscv-iommu-bits.h |
23 | +++ b/target/riscv/kvm/kvm-cpu.c | 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 | ||
24 | @@ -XXX,XX +XXX,XX @@ | 43 | @@ -XXX,XX +XXX,XX @@ |
25 | 44 | ||
26 | #include "qemu/osdep.h" | 45 | #include "qom/object.h" |
27 | #include <sys/ioctl.h> | 46 | #include "hw/riscv/iommu.h" |
28 | +#include <sys/prctl.h> | 47 | +#include "hw/riscv/riscv-iommu-bits.h" |
29 | |||
30 | #include <linux/kvm.h> | ||
31 | |||
32 | @@ -XXX,XX +XXX,XX @@ | ||
33 | #include "sysemu/runstate.h" | ||
34 | #include "hw/riscv/numa.h" | ||
35 | |||
36 | +#define PR_RISCV_V_SET_CONTROL 69 | ||
37 | +#define PR_RISCV_V_VSTATE_CTRL_ON 2 | ||
38 | + | 48 | + |
39 | void riscv_kvm_aplic_request(void *opaque, int irq, int level) | 49 | +typedef enum riscv_iommu_igs_modes riscv_iommu_igs_mode; |
40 | { | 50 | |
41 | kvm_set_irq(kvm_state, irq, !!level); | 51 | struct RISCVIOMMUState { |
42 | @@ -XXX,XX +XXX,XX @@ static void kvm_cpu_instance_init(CPUState *cs) | 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 = { | ||
43 | } | 78 | } |
44 | } | 79 | }; |
45 | 80 | ||
46 | +/* | 81 | +void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode) |
47 | + * We'll get here via the following path: | ||
48 | + * | ||
49 | + * riscv_cpu_realize() | ||
50 | + * -> cpu_exec_realizefn() | ||
51 | + * -> kvm_cpu_realize() (via accel_cpu_common_realize()) | ||
52 | + */ | ||
53 | +static bool kvm_cpu_realize(CPUState *cs, Error **errp) | ||
54 | +{ | 82 | +{ |
55 | + RISCVCPU *cpu = RISCV_CPU(cs); | 83 | + s->cap = set_field(s->cap, RISCV_IOMMU_CAP_IGS, mode); |
56 | + int ret; | ||
57 | + | ||
58 | + if (riscv_has_ext(&cpu->env, RVV)) { | ||
59 | + ret = prctl(PR_RISCV_V_SET_CONTROL, PR_RISCV_V_VSTATE_CTRL_ON); | ||
60 | + if (ret) { | ||
61 | + error_setg(errp, "Error in prctl PR_RISCV_V_SET_CONTROL, code: %s", | ||
62 | + strerrorname_np(errno)); | ||
63 | + return false; | ||
64 | + } | ||
65 | + } | ||
66 | + | ||
67 | + return true; | ||
68 | +} | 84 | +} |
69 | + | 85 | + |
70 | static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data) | 86 | static void riscv_iommu_instance_init(Object *obj) |
71 | { | 87 | { |
72 | AccelCPUClass *acc = ACCEL_CPU_CLASS(oc); | 88 | RISCVIOMMUState *s = RISCV_IOMMU(obj); |
73 | |||
74 | acc->cpu_instance_init = kvm_cpu_instance_init; | ||
75 | + acc->cpu_target_realize = kvm_cpu_realize; | ||
76 | } | ||
77 | |||
78 | static const TypeInfo kvm_cpu_accel_type_info = { | ||
79 | -- | 89 | -- |
80 | 2.43.0 | 90 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Tomasz Jeznach <tjeznach@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | We'll add a new RISC-V linux-header file, but first let's update all | 3 | This device models the RISC-V IOMMU as a sysbus device. The same design |
4 | headers. | 4 | decisions taken in the riscv-iommu-pci device were kept, namely the |
5 | 5 | existence of 4 vectors are available for each interrupt cause. | |
6 | Headers for 'asm-loongarch' were added in this update. | 6 | |
7 | 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> | ||
8 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 13 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
9 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-ID: <20231218204321.75757-2-dbarboza@ventanamicro.com> | 15 | Message-ID: <20241106133407.604587-4-dbarboza@ventanamicro.com> |
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 17 | --- |
13 | include/standard-headers/drm/drm_fourcc.h | 2 + | 18 | include/hw/riscv/iommu.h | 4 ++ |
14 | include/standard-headers/linux/pci_regs.h | 24 ++- | 19 | hw/riscv/riscv-iommu-sys.c | 128 +++++++++++++++++++++++++++++++++++++ |
15 | include/standard-headers/linux/vhost_types.h | 7 + | 20 | hw/riscv/riscv-iommu.c | 3 +- |
16 | .../standard-headers/linux/virtio_config.h | 5 + | 21 | hw/riscv/meson.build | 2 +- |
17 | include/standard-headers/linux/virtio_pci.h | 11 ++ | 22 | 4 files changed, 134 insertions(+), 3 deletions(-) |
18 | linux-headers/asm-arm64/kvm.h | 32 ++++ | 23 | create mode 100644 hw/riscv/riscv-iommu-sys.c |
19 | linux-headers/asm-generic/unistd.h | 14 +- | 24 | |
20 | linux-headers/asm-loongarch/bitsperlong.h | 1 + | 25 | diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h |
21 | linux-headers/asm-loongarch/kvm.h | 108 +++++++++++ | ||
22 | linux-headers/asm-loongarch/mman.h | 1 + | ||
23 | linux-headers/asm-loongarch/unistd.h | 5 + | ||
24 | linux-headers/asm-mips/unistd_n32.h | 4 + | ||
25 | linux-headers/asm-mips/unistd_n64.h | 4 + | ||
26 | linux-headers/asm-mips/unistd_o32.h | 4 + | ||
27 | linux-headers/asm-powerpc/unistd_32.h | 4 + | ||
28 | linux-headers/asm-powerpc/unistd_64.h | 4 + | ||
29 | linux-headers/asm-riscv/kvm.h | 12 ++ | ||
30 | linux-headers/asm-s390/unistd_32.h | 4 + | ||
31 | linux-headers/asm-s390/unistd_64.h | 4 + | ||
32 | linux-headers/asm-x86/unistd_32.h | 4 + | ||
33 | linux-headers/asm-x86/unistd_64.h | 3 + | ||
34 | linux-headers/asm-x86/unistd_x32.h | 3 + | ||
35 | linux-headers/linux/iommufd.h | 180 +++++++++++++++++- | ||
36 | linux-headers/linux/kvm.h | 11 ++ | ||
37 | linux-headers/linux/psp-sev.h | 1 + | ||
38 | linux-headers/linux/stddef.h | 9 +- | ||
39 | linux-headers/linux/userfaultfd.h | 9 +- | ||
40 | linux-headers/linux/vfio.h | 47 +++-- | ||
41 | linux-headers/linux/vhost.h | 8 + | ||
42 | 29 files changed, 498 insertions(+), 27 deletions(-) | ||
43 | create mode 100644 linux-headers/asm-loongarch/bitsperlong.h | ||
44 | create mode 100644 linux-headers/asm-loongarch/kvm.h | ||
45 | create mode 100644 linux-headers/asm-loongarch/mman.h | ||
46 | create mode 100644 linux-headers/asm-loongarch/unistd.h | ||
47 | |||
48 | diff --git a/include/standard-headers/drm/drm_fourcc.h b/include/standard-headers/drm/drm_fourcc.h | ||
49 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
50 | --- a/include/standard-headers/drm/drm_fourcc.h | 27 | --- a/include/hw/riscv/iommu.h |
51 | +++ b/include/standard-headers/drm/drm_fourcc.h | 28 | +++ b/include/hw/riscv/iommu.h |
52 | @@ -XXX,XX +XXX,XX @@ extern "C" { | 29 | @@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUSpace RISCVIOMMUSpace; |
53 | * index 1 = Cr:Cb plane, [39:0] Cr1:Cb1:Cr0:Cb0 little endian | 30 | OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI) |
54 | */ | 31 | typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci; |
55 | #define DRM_FORMAT_NV15 fourcc_code('N', 'V', '1', '5') /* 2x2 subsampled Cr:Cb plane */ | 32 | |
56 | +#define DRM_FORMAT_NV20 fourcc_code('N', 'V', '2', '0') /* 2x1 subsampled Cr:Cb plane */ | 33 | +#define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device" |
57 | +#define DRM_FORMAT_NV30 fourcc_code('N', 'V', '3', '0') /* non-subsampled Cr:Cb plane */ | 34 | +OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStateSys, RISCV_IOMMU_SYS) |
58 | 35 | +typedef struct RISCVIOMMUStateSys RISCVIOMMUStateSys; | |
59 | /* | 36 | + |
60 | * 2 plane YCbCr MSB aligned | ||
61 | diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h | ||
62 | index XXXXXXX..XXXXXXX 100644 | ||
63 | --- a/include/standard-headers/linux/pci_regs.h | ||
64 | +++ b/include/standard-headers/linux/pci_regs.h | ||
65 | @@ -XXX,XX +XXX,XX @@ | ||
66 | #define PCI_HEADER_TYPE_NORMAL 0 | ||
67 | #define PCI_HEADER_TYPE_BRIDGE 1 | ||
68 | #define PCI_HEADER_TYPE_CARDBUS 2 | ||
69 | +#define PCI_HEADER_TYPE_MFD 0x80 /* Multi-Function Device (possible) */ | ||
70 | |||
71 | #define PCI_BIST 0x0f /* 8 bits */ | ||
72 | #define PCI_BIST_CODE_MASK 0x0f /* Return result */ | ||
73 | @@ -XXX,XX +XXX,XX @@ | ||
74 | #define PCI_EXP_RTCAP 0x1e /* Root Capabilities */ | ||
75 | #define PCI_EXP_RTCAP_CRSVIS 0x0001 /* CRS Software Visibility capability */ | ||
76 | #define PCI_EXP_RTSTA 0x20 /* Root Status */ | ||
77 | +#define PCI_EXP_RTSTA_PME_RQ_ID 0x0000ffff /* PME Requester ID */ | ||
78 | #define PCI_EXP_RTSTA_PME 0x00010000 /* PME status */ | ||
79 | #define PCI_EXP_RTSTA_PENDING 0x00020000 /* PME pending */ | ||
80 | /* | ||
81 | @@ -XXX,XX +XXX,XX @@ | ||
82 | |||
83 | /* Process Address Space ID */ | ||
84 | #define PCI_PASID_CAP 0x04 /* PASID feature register */ | ||
85 | -#define PCI_PASID_CAP_EXEC 0x02 /* Exec permissions Supported */ | ||
86 | -#define PCI_PASID_CAP_PRIV 0x04 /* Privilege Mode Supported */ | ||
87 | +#define PCI_PASID_CAP_EXEC 0x0002 /* Exec permissions Supported */ | ||
88 | +#define PCI_PASID_CAP_PRIV 0x0004 /* Privilege Mode Supported */ | ||
89 | +#define PCI_PASID_CAP_WIDTH 0x1f00 | ||
90 | #define PCI_PASID_CTRL 0x06 /* PASID control register */ | ||
91 | -#define PCI_PASID_CTRL_ENABLE 0x01 /* Enable bit */ | ||
92 | -#define PCI_PASID_CTRL_EXEC 0x02 /* Exec permissions Enable */ | ||
93 | -#define PCI_PASID_CTRL_PRIV 0x04 /* Privilege Mode Enable */ | ||
94 | +#define PCI_PASID_CTRL_ENABLE 0x0001 /* Enable bit */ | ||
95 | +#define PCI_PASID_CTRL_EXEC 0x0002 /* Exec permissions Enable */ | ||
96 | +#define PCI_PASID_CTRL_PRIV 0x0004 /* Privilege Mode Enable */ | ||
97 | #define PCI_EXT_CAP_PASID_SIZEOF 8 | ||
98 | |||
99 | /* Single Root I/O Virtualization */ | ||
100 | @@ -XXX,XX +XXX,XX @@ | ||
101 | #define PCI_LTR_VALUE_MASK 0x000003ff | ||
102 | #define PCI_LTR_SCALE_MASK 0x00001c00 | ||
103 | #define PCI_LTR_SCALE_SHIFT 10 | ||
104 | +#define PCI_LTR_NOSNOOP_VALUE 0x03ff0000 /* Max No-Snoop Latency Value */ | ||
105 | +#define PCI_LTR_NOSNOOP_SCALE 0x1c000000 /* Scale for Max Value */ | ||
106 | #define PCI_EXT_CAP_LTR_SIZEOF 8 | ||
107 | |||
108 | /* Access Control Service */ | ||
109 | @@ -XXX,XX +XXX,XX @@ | ||
110 | #define PCI_EXP_DPC_STATUS 0x08 /* DPC Status */ | ||
111 | #define PCI_EXP_DPC_STATUS_TRIGGER 0x0001 /* Trigger Status */ | ||
112 | #define PCI_EXP_DPC_STATUS_TRIGGER_RSN 0x0006 /* Trigger Reason */ | ||
113 | +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_UNCOR 0x0000 /* Uncorrectable error */ | ||
114 | +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_NFE 0x0002 /* Rcvd ERR_NONFATAL */ | ||
115 | +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_FE 0x0004 /* Rcvd ERR_FATAL */ | ||
116 | +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_IN_EXT 0x0006 /* Reason in Trig Reason Extension field */ | ||
117 | #define PCI_EXP_DPC_STATUS_INTERRUPT 0x0008 /* Interrupt Status */ | ||
118 | #define PCI_EXP_DPC_RP_BUSY 0x0010 /* Root Port Busy */ | ||
119 | #define PCI_EXP_DPC_STATUS_TRIGGER_RSN_EXT 0x0060 /* Trig Reason Extension */ | ||
120 | +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_RP_PIO 0x0000 /* RP PIO error */ | ||
121 | +#define PCI_EXP_DPC_STATUS_TRIGGER_RSN_SW_TRIGGER 0x0020 /* DPC SW Trigger bit */ | ||
122 | +#define PCI_EXP_DPC_RP_PIO_FEP 0x1f00 /* RP PIO First Err Ptr */ | ||
123 | |||
124 | #define PCI_EXP_DPC_SOURCE_ID 0x0A /* DPC Source Identifier */ | ||
125 | |||
126 | @@ -XXX,XX +XXX,XX @@ | ||
127 | #define PCI_L1SS_CTL1_LTR_L12_TH_VALUE 0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */ | ||
128 | #define PCI_L1SS_CTL1_LTR_L12_TH_SCALE 0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */ | ||
129 | #define PCI_L1SS_CTL2 0x0c /* Control 2 Register */ | ||
130 | +#define PCI_L1SS_CTL2_T_PWR_ON_SCALE 0x00000003 /* T_POWER_ON Scale */ | ||
131 | +#define PCI_L1SS_CTL2_T_PWR_ON_VALUE 0x000000f8 /* T_POWER_ON Value */ | ||
132 | |||
133 | /* Designated Vendor-Specific (DVSEC, PCI_EXT_CAP_ID_DVSEC) */ | ||
134 | #define PCI_DVSEC_HEADER1 0x4 /* Designated Vendor-Specific Header1 */ | ||
135 | diff --git a/include/standard-headers/linux/vhost_types.h b/include/standard-headers/linux/vhost_types.h | ||
136 | index XXXXXXX..XXXXXXX 100644 | ||
137 | --- a/include/standard-headers/linux/vhost_types.h | ||
138 | +++ b/include/standard-headers/linux/vhost_types.h | ||
139 | @@ -XXX,XX +XXX,XX @@ struct vhost_vdpa_iova_range { | ||
140 | * DRIVER_OK | ||
141 | */ | ||
142 | #define VHOST_BACKEND_F_ENABLE_AFTER_DRIVER_OK 0x6 | ||
143 | +/* Device may expose the virtqueue's descriptor area, driver area and | ||
144 | + * device area to a different group for ASID binding than where its | ||
145 | + * buffers may reside. Requires VHOST_BACKEND_F_IOTLB_ASID. | ||
146 | + */ | ||
147 | +#define VHOST_BACKEND_F_DESC_ASID 0x7 | ||
148 | +/* IOTLB don't flush memory mapping across device reset */ | ||
149 | +#define VHOST_BACKEND_F_IOTLB_PERSIST 0x8 | ||
150 | |||
151 | #endif | 37 | #endif |
152 | diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h | 38 | diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c |
153 | index XXXXXXX..XXXXXXX 100644 | ||
154 | --- a/include/standard-headers/linux/virtio_config.h | ||
155 | +++ b/include/standard-headers/linux/virtio_config.h | ||
156 | @@ -XXX,XX +XXX,XX @@ | ||
157 | */ | ||
158 | #define VIRTIO_F_NOTIFICATION_DATA 38 | ||
159 | |||
160 | +/* This feature indicates that the driver uses the data provided by the device | ||
161 | + * as a virtqueue identifier in available buffer notifications. | ||
162 | + */ | ||
163 | +#define VIRTIO_F_NOTIF_CONFIG_DATA 39 | ||
164 | + | ||
165 | /* | ||
166 | * This feature indicates that the driver can reset a queue individually. | ||
167 | */ | ||
168 | diff --git a/include/standard-headers/linux/virtio_pci.h b/include/standard-headers/linux/virtio_pci.h | ||
169 | index XXXXXXX..XXXXXXX 100644 | ||
170 | --- a/include/standard-headers/linux/virtio_pci.h | ||
171 | +++ b/include/standard-headers/linux/virtio_pci.h | ||
172 | @@ -XXX,XX +XXX,XX @@ struct virtio_pci_common_cfg { | ||
173 | uint32_t queue_used_hi; /* read-write */ | ||
174 | }; | ||
175 | |||
176 | +/* | ||
177 | + * Warning: do not use sizeof on this: use offsetofend for | ||
178 | + * specific fields you need. | ||
179 | + */ | ||
180 | +struct virtio_pci_modern_common_cfg { | ||
181 | + struct virtio_pci_common_cfg cfg; | ||
182 | + | ||
183 | + uint16_t queue_notify_data; /* read-write */ | ||
184 | + uint16_t queue_reset; /* read-write */ | ||
185 | +}; | ||
186 | + | ||
187 | /* Fields in VIRTIO_PCI_CAP_PCI_CFG: */ | ||
188 | struct virtio_pci_cfg_cap { | ||
189 | struct virtio_pci_cap cap; | ||
190 | diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h | ||
191 | index XXXXXXX..XXXXXXX 100644 | ||
192 | --- a/linux-headers/asm-arm64/kvm.h | ||
193 | +++ b/linux-headers/asm-arm64/kvm.h | ||
194 | @@ -XXX,XX +XXX,XX @@ struct kvm_smccc_filter { | ||
195 | #define KVM_HYPERCALL_EXIT_SMC (1U << 0) | ||
196 | #define KVM_HYPERCALL_EXIT_16BIT (1U << 1) | ||
197 | |||
198 | +/* | ||
199 | + * Get feature ID registers userspace writable mask. | ||
200 | + * | ||
201 | + * From DDI0487J.a, D19.2.66 ("ID_AA64MMFR2_EL1, AArch64 Memory Model | ||
202 | + * Feature Register 2"): | ||
203 | + * | ||
204 | + * "The Feature ID space is defined as the System register space in | ||
205 | + * AArch64 with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, | ||
206 | + * op2=={0-7}." | ||
207 | + * | ||
208 | + * This covers all currently known R/O registers that indicate | ||
209 | + * anything useful feature wise, including the ID registers. | ||
210 | + * | ||
211 | + * If we ever need to introduce a new range, it will be described as | ||
212 | + * such in the range field. | ||
213 | + */ | ||
214 | +#define KVM_ARM_FEATURE_ID_RANGE_IDX(op0, op1, crn, crm, op2) \ | ||
215 | + ({ \ | ||
216 | + __u64 __op1 = (op1) & 3; \ | ||
217 | + __op1 -= (__op1 == 3); \ | ||
218 | + (__op1 << 6 | ((crm) & 7) << 3 | (op2)); \ | ||
219 | + }) | ||
220 | + | ||
221 | +#define KVM_ARM_FEATURE_ID_RANGE 0 | ||
222 | +#define KVM_ARM_FEATURE_ID_RANGE_SIZE (3 * 8 * 8) | ||
223 | + | ||
224 | +struct reg_mask_range { | ||
225 | + __u64 addr; /* Pointer to mask array */ | ||
226 | + __u32 range; /* Requested range */ | ||
227 | + __u32 reserved[13]; | ||
228 | +}; | ||
229 | + | ||
230 | #endif | ||
231 | |||
232 | #endif /* __ARM_KVM_H__ */ | ||
233 | diff --git a/linux-headers/asm-generic/unistd.h b/linux-headers/asm-generic/unistd.h | ||
234 | index XXXXXXX..XXXXXXX 100644 | ||
235 | --- a/linux-headers/asm-generic/unistd.h | ||
236 | +++ b/linux-headers/asm-generic/unistd.h | ||
237 | @@ -XXX,XX +XXX,XX @@ __SYSCALL(__NR_fremovexattr, sys_fremovexattr) | ||
238 | #define __NR_getcwd 17 | ||
239 | __SYSCALL(__NR_getcwd, sys_getcwd) | ||
240 | #define __NR_lookup_dcookie 18 | ||
241 | -__SC_COMP(__NR_lookup_dcookie, sys_lookup_dcookie, compat_sys_lookup_dcookie) | ||
242 | +__SYSCALL(__NR_lookup_dcookie, sys_ni_syscall) | ||
243 | #define __NR_eventfd2 19 | ||
244 | __SYSCALL(__NR_eventfd2, sys_eventfd2) | ||
245 | #define __NR_epoll_create1 20 | ||
246 | @@ -XXX,XX +XXX,XX @@ __SYSCALL(__NR_process_mrelease, sys_process_mrelease) | ||
247 | __SYSCALL(__NR_futex_waitv, sys_futex_waitv) | ||
248 | #define __NR_set_mempolicy_home_node 450 | ||
249 | __SYSCALL(__NR_set_mempolicy_home_node, sys_set_mempolicy_home_node) | ||
250 | - | ||
251 | #define __NR_cachestat 451 | ||
252 | __SYSCALL(__NR_cachestat, sys_cachestat) | ||
253 | - | ||
254 | #define __NR_fchmodat2 452 | ||
255 | __SYSCALL(__NR_fchmodat2, sys_fchmodat2) | ||
256 | +#define __NR_map_shadow_stack 453 | ||
257 | +__SYSCALL(__NR_map_shadow_stack, sys_map_shadow_stack) | ||
258 | +#define __NR_futex_wake 454 | ||
259 | +__SYSCALL(__NR_futex_wake, sys_futex_wake) | ||
260 | +#define __NR_futex_wait 455 | ||
261 | +__SYSCALL(__NR_futex_wait, sys_futex_wait) | ||
262 | +#define __NR_futex_requeue 456 | ||
263 | +__SYSCALL(__NR_futex_requeue, sys_futex_requeue) | ||
264 | |||
265 | #undef __NR_syscalls | ||
266 | -#define __NR_syscalls 453 | ||
267 | +#define __NR_syscalls 457 | ||
268 | |||
269 | /* | ||
270 | * 32 bit systems traditionally used different | ||
271 | diff --git a/linux-headers/asm-loongarch/bitsperlong.h b/linux-headers/asm-loongarch/bitsperlong.h | ||
272 | new file mode 100644 | 39 | new file mode 100644 |
273 | index XXXXXXX..XXXXXXX | 40 | index XXXXXXX..XXXXXXX |
274 | --- /dev/null | 41 | --- /dev/null |
275 | +++ b/linux-headers/asm-loongarch/bitsperlong.h | 42 | +++ b/hw/riscv/riscv-iommu-sys.c |
276 | @@ -0,0 +1 @@ | ||
277 | +#include <asm-generic/bitsperlong.h> | ||
278 | diff --git a/linux-headers/asm-loongarch/kvm.h b/linux-headers/asm-loongarch/kvm.h | ||
279 | new file mode 100644 | ||
280 | index XXXXXXX..XXXXXXX | ||
281 | --- /dev/null | ||
282 | +++ b/linux-headers/asm-loongarch/kvm.h | ||
283 | @@ -XXX,XX +XXX,XX @@ | 43 | @@ -XXX,XX +XXX,XX @@ |
284 | +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
285 | +/* | 44 | +/* |
286 | + * Copyright (C) 2020-2023 Loongson Technology Corporation Limited | 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/>. | ||
287 | + */ | 60 | + */ |
288 | + | 61 | + |
289 | +#ifndef __UAPI_ASM_LOONGARCH_KVM_H | 62 | +#include "qemu/osdep.h" |
290 | +#define __UAPI_ASM_LOONGARCH_KVM_H | 63 | +#include "hw/irq.h" |
291 | + | 64 | +#include "hw/pci/pci_bus.h" |
292 | +#include <linux/types.h> | 65 | +#include "hw/qdev-properties.h" |
293 | + | 66 | +#include "hw/sysbus.h" |
294 | +/* | 67 | +#include "qapi/error.h" |
295 | + * KVM LoongArch specific structures and definitions. | 68 | +#include "qemu/error-report.h" |
296 | + * | 69 | +#include "qemu/host-utils.h" |
297 | + * Some parts derived from the x86 version of this file. | 70 | +#include "qemu/module.h" |
298 | + */ | 71 | +#include "qom/object.h" |
299 | + | 72 | + |
300 | +#define __KVM_HAVE_READONLY_MEM | 73 | +#include "riscv-iommu.h" |
301 | + | 74 | + |
302 | +#define KVM_COALESCED_MMIO_PAGE_OFFSET 1 | 75 | +#define RISCV_IOMMU_SYSDEV_ICVEC_VECTORS 0x3333 |
303 | +#define KVM_DIRTY_LOG_PAGE_OFFSET 64 | 76 | + |
304 | + | 77 | +/* RISC-V IOMMU System Platform Device Emulation */ |
305 | +/* | 78 | + |
306 | + * for KVM_GET_REGS and KVM_SET_REGS | 79 | +struct RISCVIOMMUStateSys { |
307 | + */ | 80 | + SysBusDevice parent; |
308 | +struct kvm_regs { | 81 | + uint64_t addr; |
309 | + /* out (KVM_GET_REGS) / in (KVM_SET_REGS) */ | 82 | + uint32_t base_irq; |
310 | + __u64 gpr[32]; | 83 | + DeviceState *irqchip; |
311 | + __u64 pc; | 84 | + RISCVIOMMUState iommu; |
85 | + qemu_irq irqs[RISCV_IOMMU_INTR_COUNT]; | ||
312 | +}; | 86 | +}; |
313 | + | 87 | + |
314 | +/* | 88 | +static void riscv_iommu_sysdev_notify(RISCVIOMMUState *iommu, |
315 | + * for KVM_GET_FPU and KVM_SET_FPU | 89 | + unsigned vector) |
316 | + */ | 90 | +{ |
317 | +struct kvm_fpu { | 91 | + RISCVIOMMUStateSys *s = container_of(iommu, RISCVIOMMUStateSys, iommu); |
318 | + __u32 fcsr; | 92 | + uint32_t fctl = riscv_iommu_reg_get32(iommu, RISCV_IOMMU_REG_FCTL); |
319 | + __u64 fcc; /* 8x8 */ | 93 | + |
320 | + struct kvm_fpureg { | 94 | + /* We do not support MSIs yet */ |
321 | + __u64 val64[4]; | 95 | + if (!(fctl & RISCV_IOMMU_FCTL_WSI)) { |
322 | + } fpr[32]; | 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(), | ||
323 | +}; | 148 | +}; |
324 | + | 149 | + |
325 | +/* | 150 | +static void riscv_iommu_sys_class_init(ObjectClass *klass, void *data) |
326 | + * For LoongArch, we use KVM_SET_ONE_REG and KVM_GET_ONE_REG to access various | 151 | +{ |
327 | + * registers. The id field is broken down as follows: | 152 | + DeviceClass *dc = DEVICE_CLASS(klass); |
328 | + * | 153 | + dc->realize = riscv_iommu_sys_realize; |
329 | + * bits[63..52] - As per linux/kvm.h | 154 | + set_bit(DEVICE_CATEGORY_MISC, dc->categories); |
330 | + * bits[51..32] - Must be zero. | 155 | + device_class_set_props(dc, riscv_iommu_sys_properties); |
331 | + * bits[31..16] - Register set. | 156 | +} |
332 | + * | 157 | + |
333 | + * Register set = 0: GP registers from kvm_regs (see definitions below). | 158 | +static const TypeInfo riscv_iommu_sys = { |
334 | + * | 159 | + .name = TYPE_RISCV_IOMMU_SYS, |
335 | + * Register set = 1: CSR registers. | 160 | + .parent = TYPE_SYS_BUS_DEVICE, |
336 | + * | 161 | + .class_init = riscv_iommu_sys_class_init, |
337 | + * Register set = 2: KVM specific registers (see definitions below). | 162 | + .instance_init = riscv_iommu_sys_init, |
338 | + * | 163 | + .instance_size = sizeof(RISCVIOMMUStateSys), |
339 | + * Register set = 3: FPU / SIMD registers (see definitions below). | ||
340 | + * | ||
341 | + * Other sets registers may be added in the future. Each set would | ||
342 | + * have its own identifier in bits[31..16]. | ||
343 | + */ | ||
344 | + | ||
345 | +#define KVM_REG_LOONGARCH_GPR (KVM_REG_LOONGARCH | 0x00000ULL) | ||
346 | +#define KVM_REG_LOONGARCH_CSR (KVM_REG_LOONGARCH | 0x10000ULL) | ||
347 | +#define KVM_REG_LOONGARCH_KVM (KVM_REG_LOONGARCH | 0x20000ULL) | ||
348 | +#define KVM_REG_LOONGARCH_FPSIMD (KVM_REG_LOONGARCH | 0x30000ULL) | ||
349 | +#define KVM_REG_LOONGARCH_CPUCFG (KVM_REG_LOONGARCH | 0x40000ULL) | ||
350 | +#define KVM_REG_LOONGARCH_MASK (KVM_REG_LOONGARCH | 0x70000ULL) | ||
351 | +#define KVM_CSR_IDX_MASK 0x7fff | ||
352 | +#define KVM_CPUCFG_IDX_MASK 0x7fff | ||
353 | + | ||
354 | +/* | ||
355 | + * KVM_REG_LOONGARCH_KVM - KVM specific control registers. | ||
356 | + */ | ||
357 | + | ||
358 | +#define KVM_REG_LOONGARCH_COUNTER (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 1) | ||
359 | +#define KVM_REG_LOONGARCH_VCPU_RESET (KVM_REG_LOONGARCH_KVM | KVM_REG_SIZE_U64 | 2) | ||
360 | + | ||
361 | +#define LOONGARCH_REG_SHIFT 3 | ||
362 | +#define LOONGARCH_REG_64(TYPE, REG) (TYPE | KVM_REG_SIZE_U64 | (REG << LOONGARCH_REG_SHIFT)) | ||
363 | +#define KVM_IOC_CSRID(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CSR, REG) | ||
364 | +#define KVM_IOC_CPUCFG(REG) LOONGARCH_REG_64(KVM_REG_LOONGARCH_CPUCFG, REG) | ||
365 | + | ||
366 | +struct kvm_debug_exit_arch { | ||
367 | +}; | 164 | +}; |
368 | + | 165 | + |
369 | +/* for KVM_SET_GUEST_DEBUG */ | 166 | +static void riscv_iommu_register_sys(void) |
370 | +struct kvm_guest_debug_arch { | 167 | +{ |
371 | +}; | 168 | + type_register_static(&riscv_iommu_sys); |
372 | + | 169 | +} |
373 | +/* definition of registers in kvm_run */ | 170 | + |
374 | +struct kvm_sync_regs { | 171 | +type_init(riscv_iommu_register_sys) |
375 | +}; | 172 | diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c |
376 | + | ||
377 | +/* dummy definition */ | ||
378 | +struct kvm_sregs { | ||
379 | +}; | ||
380 | + | ||
381 | +struct kvm_iocsr_entry { | ||
382 | + __u32 addr; | ||
383 | + __u32 pad; | ||
384 | + __u64 data; | ||
385 | +}; | ||
386 | + | ||
387 | +#define KVM_NR_IRQCHIPS 1 | ||
388 | +#define KVM_IRQCHIP_NUM_PINS 64 | ||
389 | +#define KVM_MAX_CORES 256 | ||
390 | + | ||
391 | +#endif /* __UAPI_ASM_LOONGARCH_KVM_H */ | ||
392 | diff --git a/linux-headers/asm-loongarch/mman.h b/linux-headers/asm-loongarch/mman.h | ||
393 | new file mode 100644 | ||
394 | index XXXXXXX..XXXXXXX | ||
395 | --- /dev/null | ||
396 | +++ b/linux-headers/asm-loongarch/mman.h | ||
397 | @@ -0,0 +1 @@ | ||
398 | +#include <asm-generic/mman.h> | ||
399 | diff --git a/linux-headers/asm-loongarch/unistd.h b/linux-headers/asm-loongarch/unistd.h | ||
400 | new file mode 100644 | ||
401 | index XXXXXXX..XXXXXXX | ||
402 | --- /dev/null | ||
403 | +++ b/linux-headers/asm-loongarch/unistd.h | ||
404 | @@ -XXX,XX +XXX,XX @@ | ||
405 | +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
406 | +#define __ARCH_WANT_SYS_CLONE | ||
407 | +#define __ARCH_WANT_SYS_CLONE3 | ||
408 | + | ||
409 | +#include <asm-generic/unistd.h> | ||
410 | diff --git a/linux-headers/asm-mips/unistd_n32.h b/linux-headers/asm-mips/unistd_n32.h | ||
411 | index XXXXXXX..XXXXXXX 100644 | 173 | index XXXXXXX..XXXXXXX 100644 |
412 | --- a/linux-headers/asm-mips/unistd_n32.h | 174 | --- a/hw/riscv/riscv-iommu.c |
413 | +++ b/linux-headers/asm-mips/unistd_n32.h | 175 | +++ b/hw/riscv/riscv-iommu.c |
414 | @@ -XXX,XX +XXX,XX @@ | 176 | @@ -XXX,XX +XXX,XX @@ static uint8_t riscv_iommu_get_icvec_vector(uint32_t icvec, uint32_t vec_type) |
415 | #define __NR_set_mempolicy_home_node (__NR_Linux + 450) | 177 | |
416 | #define __NR_cachestat (__NR_Linux + 451) | 178 | static void riscv_iommu_notify(RISCVIOMMUState *s, int vec_type) |
417 | #define __NR_fchmodat2 (__NR_Linux + 452) | 179 | { |
418 | +#define __NR_map_shadow_stack (__NR_Linux + 453) | 180 | - const uint32_t fctl = riscv_iommu_reg_get32(s, RISCV_IOMMU_REG_FCTL); |
419 | +#define __NR_futex_wake (__NR_Linux + 454) | 181 | uint32_t ipsr, icvec, vector; |
420 | +#define __NR_futex_wait (__NR_Linux + 455) | 182 | |
421 | +#define __NR_futex_requeue (__NR_Linux + 456) | 183 | - if (fctl & RISCV_IOMMU_FCTL_WSI || !s->notify) { |
422 | 184 | + if (!s->notify) { | |
423 | #endif /* _ASM_UNISTD_N32_H */ | 185 | return; |
424 | diff --git a/linux-headers/asm-mips/unistd_n64.h b/linux-headers/asm-mips/unistd_n64.h | 186 | } |
187 | |||
188 | diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build | ||
425 | index XXXXXXX..XXXXXXX 100644 | 189 | index XXXXXXX..XXXXXXX 100644 |
426 | --- a/linux-headers/asm-mips/unistd_n64.h | 190 | --- a/hw/riscv/meson.build |
427 | +++ b/linux-headers/asm-mips/unistd_n64.h | 191 | +++ b/hw/riscv/meson.build |
428 | @@ -XXX,XX +XXX,XX @@ | 192 | @@ -XXX,XX +XXX,XX @@ riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c')) |
429 | #define __NR_set_mempolicy_home_node (__NR_Linux + 450) | 193 | riscv_ss.add(when: 'CONFIG_SPIKE', if_true: files('spike.c')) |
430 | #define __NR_cachestat (__NR_Linux + 451) | 194 | riscv_ss.add(when: 'CONFIG_MICROCHIP_PFSOC', if_true: files('microchip_pfsoc.c')) |
431 | #define __NR_fchmodat2 (__NR_Linux + 452) | 195 | riscv_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) |
432 | +#define __NR_map_shadow_stack (__NR_Linux + 453) | 196 | -riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 'riscv-iommu-pci.c')) |
433 | +#define __NR_futex_wake (__NR_Linux + 454) | 197 | +riscv_ss.add(when: 'CONFIG_RISCV_IOMMU', if_true: files('riscv-iommu.c', 'riscv-iommu-pci.c', 'riscv-iommu-sys.c')) |
434 | +#define __NR_futex_wait (__NR_Linux + 455) | 198 | |
435 | +#define __NR_futex_requeue (__NR_Linux + 456) | 199 | hw_arch += {'riscv': riscv_ss} |
436 | |||
437 | #endif /* _ASM_UNISTD_N64_H */ | ||
438 | diff --git a/linux-headers/asm-mips/unistd_o32.h b/linux-headers/asm-mips/unistd_o32.h | ||
439 | index XXXXXXX..XXXXXXX 100644 | ||
440 | --- a/linux-headers/asm-mips/unistd_o32.h | ||
441 | +++ b/linux-headers/asm-mips/unistd_o32.h | ||
442 | @@ -XXX,XX +XXX,XX @@ | ||
443 | #define __NR_set_mempolicy_home_node (__NR_Linux + 450) | ||
444 | #define __NR_cachestat (__NR_Linux + 451) | ||
445 | #define __NR_fchmodat2 (__NR_Linux + 452) | ||
446 | +#define __NR_map_shadow_stack (__NR_Linux + 453) | ||
447 | +#define __NR_futex_wake (__NR_Linux + 454) | ||
448 | +#define __NR_futex_wait (__NR_Linux + 455) | ||
449 | +#define __NR_futex_requeue (__NR_Linux + 456) | ||
450 | |||
451 | #endif /* _ASM_UNISTD_O32_H */ | ||
452 | diff --git a/linux-headers/asm-powerpc/unistd_32.h b/linux-headers/asm-powerpc/unistd_32.h | ||
453 | index XXXXXXX..XXXXXXX 100644 | ||
454 | --- a/linux-headers/asm-powerpc/unistd_32.h | ||
455 | +++ b/linux-headers/asm-powerpc/unistd_32.h | ||
456 | @@ -XXX,XX +XXX,XX @@ | ||
457 | #define __NR_set_mempolicy_home_node 450 | ||
458 | #define __NR_cachestat 451 | ||
459 | #define __NR_fchmodat2 452 | ||
460 | +#define __NR_map_shadow_stack 453 | ||
461 | +#define __NR_futex_wake 454 | ||
462 | +#define __NR_futex_wait 455 | ||
463 | +#define __NR_futex_requeue 456 | ||
464 | |||
465 | |||
466 | #endif /* _ASM_UNISTD_32_H */ | ||
467 | diff --git a/linux-headers/asm-powerpc/unistd_64.h b/linux-headers/asm-powerpc/unistd_64.h | ||
468 | index XXXXXXX..XXXXXXX 100644 | ||
469 | --- a/linux-headers/asm-powerpc/unistd_64.h | ||
470 | +++ b/linux-headers/asm-powerpc/unistd_64.h | ||
471 | @@ -XXX,XX +XXX,XX @@ | ||
472 | #define __NR_set_mempolicy_home_node 450 | ||
473 | #define __NR_cachestat 451 | ||
474 | #define __NR_fchmodat2 452 | ||
475 | +#define __NR_map_shadow_stack 453 | ||
476 | +#define __NR_futex_wake 454 | ||
477 | +#define __NR_futex_wait 455 | ||
478 | +#define __NR_futex_requeue 456 | ||
479 | |||
480 | |||
481 | #endif /* _ASM_UNISTD_64_H */ | ||
482 | diff --git a/linux-headers/asm-riscv/kvm.h b/linux-headers/asm-riscv/kvm.h | ||
483 | index XXXXXXX..XXXXXXX 100644 | ||
484 | --- a/linux-headers/asm-riscv/kvm.h | ||
485 | +++ b/linux-headers/asm-riscv/kvm.h | ||
486 | @@ -XXX,XX +XXX,XX @@ struct kvm_riscv_csr { | ||
487 | unsigned long sip; | ||
488 | unsigned long satp; | ||
489 | unsigned long scounteren; | ||
490 | + unsigned long senvcfg; | ||
491 | }; | ||
492 | |||
493 | /* AIA CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ | ||
494 | @@ -XXX,XX +XXX,XX @@ struct kvm_riscv_aia_csr { | ||
495 | unsigned long iprio2h; | ||
496 | }; | ||
497 | |||
498 | +/* Smstateen CSR for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ | ||
499 | +struct kvm_riscv_smstateen_csr { | ||
500 | + unsigned long sstateen0; | ||
501 | +}; | ||
502 | + | ||
503 | /* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ | ||
504 | struct kvm_riscv_timer { | ||
505 | __u64 frequency; | ||
506 | @@ -XXX,XX +XXX,XX @@ enum KVM_RISCV_ISA_EXT_ID { | ||
507 | KVM_RISCV_ISA_EXT_ZICSR, | ||
508 | KVM_RISCV_ISA_EXT_ZIFENCEI, | ||
509 | KVM_RISCV_ISA_EXT_ZIHPM, | ||
510 | + KVM_RISCV_ISA_EXT_SMSTATEEN, | ||
511 | + KVM_RISCV_ISA_EXT_ZICOND, | ||
512 | KVM_RISCV_ISA_EXT_MAX, | ||
513 | }; | ||
514 | |||
515 | @@ -XXX,XX +XXX,XX @@ enum KVM_RISCV_SBI_EXT_ID { | ||
516 | KVM_RISCV_SBI_EXT_PMU, | ||
517 | KVM_RISCV_SBI_EXT_EXPERIMENTAL, | ||
518 | KVM_RISCV_SBI_EXT_VENDOR, | ||
519 | + KVM_RISCV_SBI_EXT_DBCN, | ||
520 | KVM_RISCV_SBI_EXT_MAX, | ||
521 | }; | ||
522 | |||
523 | @@ -XXX,XX +XXX,XX @@ enum KVM_RISCV_SBI_EXT_ID { | ||
524 | #define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT) | ||
525 | #define KVM_REG_RISCV_CSR_GENERAL (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT) | ||
526 | #define KVM_REG_RISCV_CSR_AIA (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT) | ||
527 | +#define KVM_REG_RISCV_CSR_SMSTATEEN (0x2 << KVM_REG_RISCV_SUBTYPE_SHIFT) | ||
528 | #define KVM_REG_RISCV_CSR_REG(name) \ | ||
529 | (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long)) | ||
530 | #define KVM_REG_RISCV_CSR_AIA_REG(name) \ | ||
531 | (offsetof(struct kvm_riscv_aia_csr, name) / sizeof(unsigned long)) | ||
532 | +#define KVM_REG_RISCV_CSR_SMSTATEEN_REG(name) \ | ||
533 | + (offsetof(struct kvm_riscv_smstateen_csr, name) / sizeof(unsigned long)) | ||
534 | |||
535 | /* Timer registers are mapped as type 4 */ | ||
536 | #define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT) | ||
537 | diff --git a/linux-headers/asm-s390/unistd_32.h b/linux-headers/asm-s390/unistd_32.h | ||
538 | index XXXXXXX..XXXXXXX 100644 | ||
539 | --- a/linux-headers/asm-s390/unistd_32.h | ||
540 | +++ b/linux-headers/asm-s390/unistd_32.h | ||
541 | @@ -XXX,XX +XXX,XX @@ | ||
542 | #define __NR_set_mempolicy_home_node 450 | ||
543 | #define __NR_cachestat 451 | ||
544 | #define __NR_fchmodat2 452 | ||
545 | +#define __NR_map_shadow_stack 453 | ||
546 | +#define __NR_futex_wake 454 | ||
547 | +#define __NR_futex_wait 455 | ||
548 | +#define __NR_futex_requeue 456 | ||
549 | |||
550 | #endif /* _ASM_S390_UNISTD_32_H */ | ||
551 | diff --git a/linux-headers/asm-s390/unistd_64.h b/linux-headers/asm-s390/unistd_64.h | ||
552 | index XXXXXXX..XXXXXXX 100644 | ||
553 | --- a/linux-headers/asm-s390/unistd_64.h | ||
554 | +++ b/linux-headers/asm-s390/unistd_64.h | ||
555 | @@ -XXX,XX +XXX,XX @@ | ||
556 | #define __NR_set_mempolicy_home_node 450 | ||
557 | #define __NR_cachestat 451 | ||
558 | #define __NR_fchmodat2 452 | ||
559 | +#define __NR_map_shadow_stack 453 | ||
560 | +#define __NR_futex_wake 454 | ||
561 | +#define __NR_futex_wait 455 | ||
562 | +#define __NR_futex_requeue 456 | ||
563 | |||
564 | #endif /* _ASM_S390_UNISTD_64_H */ | ||
565 | diff --git a/linux-headers/asm-x86/unistd_32.h b/linux-headers/asm-x86/unistd_32.h | ||
566 | index XXXXXXX..XXXXXXX 100644 | ||
567 | --- a/linux-headers/asm-x86/unistd_32.h | ||
568 | +++ b/linux-headers/asm-x86/unistd_32.h | ||
569 | @@ -XXX,XX +XXX,XX @@ | ||
570 | #define __NR_set_mempolicy_home_node 450 | ||
571 | #define __NR_cachestat 451 | ||
572 | #define __NR_fchmodat2 452 | ||
573 | +#define __NR_map_shadow_stack 453 | ||
574 | +#define __NR_futex_wake 454 | ||
575 | +#define __NR_futex_wait 455 | ||
576 | +#define __NR_futex_requeue 456 | ||
577 | |||
578 | |||
579 | #endif /* _ASM_UNISTD_32_H */ | ||
580 | diff --git a/linux-headers/asm-x86/unistd_64.h b/linux-headers/asm-x86/unistd_64.h | ||
581 | index XXXXXXX..XXXXXXX 100644 | ||
582 | --- a/linux-headers/asm-x86/unistd_64.h | ||
583 | +++ b/linux-headers/asm-x86/unistd_64.h | ||
584 | @@ -XXX,XX +XXX,XX @@ | ||
585 | #define __NR_cachestat 451 | ||
586 | #define __NR_fchmodat2 452 | ||
587 | #define __NR_map_shadow_stack 453 | ||
588 | +#define __NR_futex_wake 454 | ||
589 | +#define __NR_futex_wait 455 | ||
590 | +#define __NR_futex_requeue 456 | ||
591 | |||
592 | |||
593 | #endif /* _ASM_UNISTD_64_H */ | ||
594 | diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h | ||
595 | index XXXXXXX..XXXXXXX 100644 | ||
596 | --- a/linux-headers/asm-x86/unistd_x32.h | ||
597 | +++ b/linux-headers/asm-x86/unistd_x32.h | ||
598 | @@ -XXX,XX +XXX,XX @@ | ||
599 | #define __NR_set_mempolicy_home_node (__X32_SYSCALL_BIT + 450) | ||
600 | #define __NR_cachestat (__X32_SYSCALL_BIT + 451) | ||
601 | #define __NR_fchmodat2 (__X32_SYSCALL_BIT + 452) | ||
602 | +#define __NR_futex_wake (__X32_SYSCALL_BIT + 454) | ||
603 | +#define __NR_futex_wait (__X32_SYSCALL_BIT + 455) | ||
604 | +#define __NR_futex_requeue (__X32_SYSCALL_BIT + 456) | ||
605 | #define __NR_rt_sigaction (__X32_SYSCALL_BIT + 512) | ||
606 | #define __NR_rt_sigreturn (__X32_SYSCALL_BIT + 513) | ||
607 | #define __NR_ioctl (__X32_SYSCALL_BIT + 514) | ||
608 | diff --git a/linux-headers/linux/iommufd.h b/linux-headers/linux/iommufd.h | ||
609 | index XXXXXXX..XXXXXXX 100644 | ||
610 | --- a/linux-headers/linux/iommufd.h | ||
611 | +++ b/linux-headers/linux/iommufd.h | ||
612 | @@ -XXX,XX +XXX,XX @@ enum { | ||
613 | IOMMUFD_CMD_VFIO_IOAS, | ||
614 | IOMMUFD_CMD_HWPT_ALLOC, | ||
615 | IOMMUFD_CMD_GET_HW_INFO, | ||
616 | + IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING, | ||
617 | + IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP, | ||
618 | }; | ||
619 | |||
620 | /** | ||
621 | @@ -XXX,XX +XXX,XX @@ struct iommu_vfio_ioas { | ||
622 | }; | ||
623 | #define IOMMU_VFIO_IOAS _IO(IOMMUFD_TYPE, IOMMUFD_CMD_VFIO_IOAS) | ||
624 | |||
625 | +/** | ||
626 | + * enum iommufd_hwpt_alloc_flags - Flags for HWPT allocation | ||
627 | + * @IOMMU_HWPT_ALLOC_NEST_PARENT: If set, allocate a HWPT that can serve as | ||
628 | + * the parent HWPT in a nesting configuration. | ||
629 | + * @IOMMU_HWPT_ALLOC_DIRTY_TRACKING: Dirty tracking support for device IOMMU is | ||
630 | + * enforced on device attachment | ||
631 | + */ | ||
632 | +enum iommufd_hwpt_alloc_flags { | ||
633 | + IOMMU_HWPT_ALLOC_NEST_PARENT = 1 << 0, | ||
634 | + IOMMU_HWPT_ALLOC_DIRTY_TRACKING = 1 << 1, | ||
635 | +}; | ||
636 | + | ||
637 | +/** | ||
638 | + * enum iommu_hwpt_vtd_s1_flags - Intel VT-d stage-1 page table | ||
639 | + * entry attributes | ||
640 | + * @IOMMU_VTD_S1_SRE: Supervisor request | ||
641 | + * @IOMMU_VTD_S1_EAFE: Extended access enable | ||
642 | + * @IOMMU_VTD_S1_WPE: Write protect enable | ||
643 | + */ | ||
644 | +enum iommu_hwpt_vtd_s1_flags { | ||
645 | + IOMMU_VTD_S1_SRE = 1 << 0, | ||
646 | + IOMMU_VTD_S1_EAFE = 1 << 1, | ||
647 | + IOMMU_VTD_S1_WPE = 1 << 2, | ||
648 | +}; | ||
649 | + | ||
650 | +/** | ||
651 | + * struct iommu_hwpt_vtd_s1 - Intel VT-d stage-1 page table | ||
652 | + * info (IOMMU_HWPT_DATA_VTD_S1) | ||
653 | + * @flags: Combination of enum iommu_hwpt_vtd_s1_flags | ||
654 | + * @pgtbl_addr: The base address of the stage-1 page table. | ||
655 | + * @addr_width: The address width of the stage-1 page table | ||
656 | + * @__reserved: Must be 0 | ||
657 | + */ | ||
658 | +struct iommu_hwpt_vtd_s1 { | ||
659 | + __aligned_u64 flags; | ||
660 | + __aligned_u64 pgtbl_addr; | ||
661 | + __u32 addr_width; | ||
662 | + __u32 __reserved; | ||
663 | +}; | ||
664 | + | ||
665 | +/** | ||
666 | + * enum iommu_hwpt_data_type - IOMMU HWPT Data Type | ||
667 | + * @IOMMU_HWPT_DATA_NONE: no data | ||
668 | + * @IOMMU_HWPT_DATA_VTD_S1: Intel VT-d stage-1 page table | ||
669 | + */ | ||
670 | +enum iommu_hwpt_data_type { | ||
671 | + IOMMU_HWPT_DATA_NONE, | ||
672 | + IOMMU_HWPT_DATA_VTD_S1, | ||
673 | +}; | ||
674 | + | ||
675 | /** | ||
676 | * struct iommu_hwpt_alloc - ioctl(IOMMU_HWPT_ALLOC) | ||
677 | * @size: sizeof(struct iommu_hwpt_alloc) | ||
678 | - * @flags: Must be 0 | ||
679 | + * @flags: Combination of enum iommufd_hwpt_alloc_flags | ||
680 | * @dev_id: The device to allocate this HWPT for | ||
681 | - * @pt_id: The IOAS to connect this HWPT to | ||
682 | + * @pt_id: The IOAS or HWPT to connect this HWPT to | ||
683 | * @out_hwpt_id: The ID of the new HWPT | ||
684 | * @__reserved: Must be 0 | ||
685 | + * @data_type: One of enum iommu_hwpt_data_type | ||
686 | + * @data_len: Length of the type specific data | ||
687 | + * @data_uptr: User pointer to the type specific data | ||
688 | * | ||
689 | * Explicitly allocate a hardware page table object. This is the same object | ||
690 | * type that is returned by iommufd_device_attach() and represents the | ||
691 | * underlying iommu driver's iommu_domain kernel object. | ||
692 | * | ||
693 | - * A HWPT will be created with the IOVA mappings from the given IOAS. | ||
694 | + * A kernel-managed HWPT will be created with the mappings from the given | ||
695 | + * IOAS via the @pt_id. The @data_type for this allocation must be set to | ||
696 | + * IOMMU_HWPT_DATA_NONE. The HWPT can be allocated as a parent HWPT for a | ||
697 | + * nesting configuration by passing IOMMU_HWPT_ALLOC_NEST_PARENT via @flags. | ||
698 | + * | ||
699 | + * A user-managed nested HWPT will be created from a given parent HWPT via | ||
700 | + * @pt_id, in which the parent HWPT must be allocated previously via the | ||
701 | + * same ioctl from a given IOAS (@pt_id). In this case, the @data_type | ||
702 | + * must be set to a pre-defined type corresponding to an I/O page table | ||
703 | + * type supported by the underlying IOMMU hardware. | ||
704 | + * | ||
705 | + * If the @data_type is set to IOMMU_HWPT_DATA_NONE, @data_len and | ||
706 | + * @data_uptr should be zero. Otherwise, both @data_len and @data_uptr | ||
707 | + * must be given. | ||
708 | */ | ||
709 | struct iommu_hwpt_alloc { | ||
710 | __u32 size; | ||
711 | @@ -XXX,XX +XXX,XX @@ struct iommu_hwpt_alloc { | ||
712 | __u32 pt_id; | ||
713 | __u32 out_hwpt_id; | ||
714 | __u32 __reserved; | ||
715 | + __u32 data_type; | ||
716 | + __u32 data_len; | ||
717 | + __aligned_u64 data_uptr; | ||
718 | }; | ||
719 | #define IOMMU_HWPT_ALLOC _IO(IOMMUFD_TYPE, IOMMUFD_CMD_HWPT_ALLOC) | ||
720 | |||
721 | +/** | ||
722 | + * enum iommu_hw_info_vtd_flags - Flags for VT-d hw_info | ||
723 | + * @IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17: If set, disallow read-only mappings | ||
724 | + * on a nested_parent domain. | ||
725 | + * https://www.intel.com/content/www/us/en/content-details/772415/content-details.html | ||
726 | + */ | ||
727 | +enum iommu_hw_info_vtd_flags { | ||
728 | + IOMMU_HW_INFO_VTD_ERRATA_772415_SPR17 = 1 << 0, | ||
729 | +}; | ||
730 | + | ||
731 | /** | ||
732 | * struct iommu_hw_info_vtd - Intel VT-d hardware information | ||
733 | * | ||
734 | - * @flags: Must be 0 | ||
735 | + * @flags: Combination of enum iommu_hw_info_vtd_flags | ||
736 | * @__reserved: Must be 0 | ||
737 | * | ||
738 | * @cap_reg: Value of Intel VT-d capability register defined in VT-d spec | ||
739 | @@ -XXX,XX +XXX,XX @@ enum iommu_hw_info_type { | ||
740 | IOMMU_HW_INFO_TYPE_INTEL_VTD, | ||
741 | }; | ||
742 | |||
743 | +/** | ||
744 | + * enum iommufd_hw_capabilities | ||
745 | + * @IOMMU_HW_CAP_DIRTY_TRACKING: IOMMU hardware support for dirty tracking | ||
746 | + * If available, it means the following APIs | ||
747 | + * are supported: | ||
748 | + * | ||
749 | + * IOMMU_HWPT_GET_DIRTY_BITMAP | ||
750 | + * IOMMU_HWPT_SET_DIRTY_TRACKING | ||
751 | + * | ||
752 | + */ | ||
753 | +enum iommufd_hw_capabilities { | ||
754 | + IOMMU_HW_CAP_DIRTY_TRACKING = 1 << 0, | ||
755 | +}; | ||
756 | + | ||
757 | /** | ||
758 | * struct iommu_hw_info - ioctl(IOMMU_GET_HW_INFO) | ||
759 | * @size: sizeof(struct iommu_hw_info) | ||
760 | @@ -XXX,XX +XXX,XX @@ enum iommu_hw_info_type { | ||
761 | * the iommu type specific hardware information data | ||
762 | * @out_data_type: Output the iommu hardware info type as defined in the enum | ||
763 | * iommu_hw_info_type. | ||
764 | + * @out_capabilities: Output the generic iommu capability info type as defined | ||
765 | + * in the enum iommu_hw_capabilities. | ||
766 | * @__reserved: Must be 0 | ||
767 | * | ||
768 | * Query an iommu type specific hardware information data from an iommu behind | ||
769 | @@ -XXX,XX +XXX,XX @@ struct iommu_hw_info { | ||
770 | __aligned_u64 data_uptr; | ||
771 | __u32 out_data_type; | ||
772 | __u32 __reserved; | ||
773 | + __aligned_u64 out_capabilities; | ||
774 | }; | ||
775 | #define IOMMU_GET_HW_INFO _IO(IOMMUFD_TYPE, IOMMUFD_CMD_GET_HW_INFO) | ||
776 | + | ||
777 | +/* | ||
778 | + * enum iommufd_hwpt_set_dirty_tracking_flags - Flags for steering dirty | ||
779 | + * tracking | ||
780 | + * @IOMMU_HWPT_DIRTY_TRACKING_ENABLE: Enable dirty tracking | ||
781 | + */ | ||
782 | +enum iommufd_hwpt_set_dirty_tracking_flags { | ||
783 | + IOMMU_HWPT_DIRTY_TRACKING_ENABLE = 1, | ||
784 | +}; | ||
785 | + | ||
786 | +/** | ||
787 | + * struct iommu_hwpt_set_dirty_tracking - ioctl(IOMMU_HWPT_SET_DIRTY_TRACKING) | ||
788 | + * @size: sizeof(struct iommu_hwpt_set_dirty_tracking) | ||
789 | + * @flags: Combination of enum iommufd_hwpt_set_dirty_tracking_flags | ||
790 | + * @hwpt_id: HW pagetable ID that represents the IOMMU domain | ||
791 | + * @__reserved: Must be 0 | ||
792 | + * | ||
793 | + * Toggle dirty tracking on an HW pagetable. | ||
794 | + */ | ||
795 | +struct iommu_hwpt_set_dirty_tracking { | ||
796 | + __u32 size; | ||
797 | + __u32 flags; | ||
798 | + __u32 hwpt_id; | ||
799 | + __u32 __reserved; | ||
800 | +}; | ||
801 | +#define IOMMU_HWPT_SET_DIRTY_TRACKING _IO(IOMMUFD_TYPE, \ | ||
802 | + IOMMUFD_CMD_HWPT_SET_DIRTY_TRACKING) | ||
803 | + | ||
804 | +/** | ||
805 | + * enum iommufd_hwpt_get_dirty_bitmap_flags - Flags for getting dirty bits | ||
806 | + * @IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR: Just read the PTEs without clearing | ||
807 | + * any dirty bits metadata. This flag | ||
808 | + * can be passed in the expectation | ||
809 | + * where the next operation is an unmap | ||
810 | + * of the same IOVA range. | ||
811 | + * | ||
812 | + */ | ||
813 | +enum iommufd_hwpt_get_dirty_bitmap_flags { | ||
814 | + IOMMU_HWPT_GET_DIRTY_BITMAP_NO_CLEAR = 1, | ||
815 | +}; | ||
816 | + | ||
817 | +/** | ||
818 | + * struct iommu_hwpt_get_dirty_bitmap - ioctl(IOMMU_HWPT_GET_DIRTY_BITMAP) | ||
819 | + * @size: sizeof(struct iommu_hwpt_get_dirty_bitmap) | ||
820 | + * @hwpt_id: HW pagetable ID that represents the IOMMU domain | ||
821 | + * @flags: Combination of enum iommufd_hwpt_get_dirty_bitmap_flags | ||
822 | + * @__reserved: Must be 0 | ||
823 | + * @iova: base IOVA of the bitmap first bit | ||
824 | + * @length: IOVA range size | ||
825 | + * @page_size: page size granularity of each bit in the bitmap | ||
826 | + * @data: bitmap where to set the dirty bits. The bitmap bits each | ||
827 | + * represent a page_size which you deviate from an arbitrary iova. | ||
828 | + * | ||
829 | + * Checking a given IOVA is dirty: | ||
830 | + * | ||
831 | + * data[(iova / page_size) / 64] & (1ULL << ((iova / page_size) % 64)) | ||
832 | + * | ||
833 | + * Walk the IOMMU pagetables for a given IOVA range to return a bitmap | ||
834 | + * with the dirty IOVAs. In doing so it will also by default clear any | ||
835 | + * dirty bit metadata set in the IOPTE. | ||
836 | + */ | ||
837 | +struct iommu_hwpt_get_dirty_bitmap { | ||
838 | + __u32 size; | ||
839 | + __u32 hwpt_id; | ||
840 | + __u32 flags; | ||
841 | + __u32 __reserved; | ||
842 | + __aligned_u64 iova; | ||
843 | + __aligned_u64 length; | ||
844 | + __aligned_u64 page_size; | ||
845 | + __aligned_u64 data; | ||
846 | +}; | ||
847 | +#define IOMMU_HWPT_GET_DIRTY_BITMAP _IO(IOMMUFD_TYPE, \ | ||
848 | + IOMMUFD_CMD_HWPT_GET_DIRTY_BITMAP) | ||
849 | + | ||
850 | #endif | ||
851 | diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h | ||
852 | index XXXXXXX..XXXXXXX 100644 | ||
853 | --- a/linux-headers/linux/kvm.h | ||
854 | +++ b/linux-headers/linux/kvm.h | ||
855 | @@ -XXX,XX +XXX,XX @@ struct kvm_xen_exit { | ||
856 | #define KVM_EXIT_RISCV_SBI 35 | ||
857 | #define KVM_EXIT_RISCV_CSR 36 | ||
858 | #define KVM_EXIT_NOTIFY 37 | ||
859 | +#define KVM_EXIT_LOONGARCH_IOCSR 38 | ||
860 | |||
861 | /* For KVM_EXIT_INTERNAL_ERROR */ | ||
862 | /* Emulate instruction failed. */ | ||
863 | @@ -XXX,XX +XXX,XX @@ struct kvm_run { | ||
864 | __u32 len; | ||
865 | __u8 is_write; | ||
866 | } mmio; | ||
867 | + /* KVM_EXIT_LOONGARCH_IOCSR */ | ||
868 | + struct { | ||
869 | + __u64 phys_addr; | ||
870 | + __u8 data[8]; | ||
871 | + __u32 len; | ||
872 | + __u8 is_write; | ||
873 | + } iocsr_io; | ||
874 | /* KVM_EXIT_HYPERCALL */ | ||
875 | struct { | ||
876 | __u64 nr; | ||
877 | @@ -XXX,XX +XXX,XX @@ struct kvm_ppc_resize_hpt { | ||
878 | #define KVM_CAP_COUNTER_OFFSET 227 | ||
879 | #define KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE 228 | ||
880 | #define KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES 229 | ||
881 | +#define KVM_CAP_ARM_SUPPORTED_REG_MASK_RANGES 230 | ||
882 | |||
883 | #ifdef KVM_CAP_IRQ_ROUTING | ||
884 | |||
885 | @@ -XXX,XX +XXX,XX @@ struct kvm_dirty_tlb { | ||
886 | #define KVM_REG_ARM64 0x6000000000000000ULL | ||
887 | #define KVM_REG_MIPS 0x7000000000000000ULL | ||
888 | #define KVM_REG_RISCV 0x8000000000000000ULL | ||
889 | +#define KVM_REG_LOONGARCH 0x9000000000000000ULL | ||
890 | |||
891 | #define KVM_REG_SIZE_SHIFT 52 | ||
892 | #define KVM_REG_SIZE_MASK 0x00f0000000000000ULL | ||
893 | @@ -XXX,XX +XXX,XX @@ struct kvm_s390_ucas_mapping { | ||
894 | #define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags) | ||
895 | /* Available with KVM_CAP_COUNTER_OFFSET */ | ||
896 | #define KVM_ARM_SET_COUNTER_OFFSET _IOW(KVMIO, 0xb5, struct kvm_arm_counter_offset) | ||
897 | +#define KVM_ARM_GET_REG_WRITABLE_MASKS _IOR(KVMIO, 0xb6, struct reg_mask_range) | ||
898 | |||
899 | /* ioctl for vm fd */ | ||
900 | #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) | ||
901 | diff --git a/linux-headers/linux/psp-sev.h b/linux-headers/linux/psp-sev.h | ||
902 | index XXXXXXX..XXXXXXX 100644 | ||
903 | --- a/linux-headers/linux/psp-sev.h | ||
904 | +++ b/linux-headers/linux/psp-sev.h | ||
905 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
906 | SEV_RET_INVALID_PARAM, | ||
907 | SEV_RET_RESOURCE_LIMIT, | ||
908 | SEV_RET_SECURE_DATA_INVALID, | ||
909 | + SEV_RET_INVALID_KEY = 0x27, | ||
910 | SEV_RET_MAX, | ||
911 | } sev_ret_code; | ||
912 | |||
913 | diff --git a/linux-headers/linux/stddef.h b/linux-headers/linux/stddef.h | ||
914 | index XXXXXXX..XXXXXXX 100644 | ||
915 | --- a/linux-headers/linux/stddef.h | ||
916 | +++ b/linux-headers/linux/stddef.h | ||
917 | @@ -XXX,XX +XXX,XX @@ | ||
918 | union { \ | ||
919 | struct { MEMBERS } ATTRS; \ | ||
920 | struct TAG { MEMBERS } ATTRS NAME; \ | ||
921 | - } | ||
922 | + } ATTRS | ||
923 | |||
924 | +#ifdef __cplusplus | ||
925 | +/* sizeof(struct{}) is 1 in C++, not 0, can't use C version of the macro. */ | ||
926 | +#define __DECLARE_FLEX_ARRAY(T, member) \ | ||
927 | + T member[0] | ||
928 | +#else | ||
929 | /** | ||
930 | * __DECLARE_FLEX_ARRAY() - Declare a flexible array usable in a union | ||
931 | * | ||
932 | @@ -XXX,XX +XXX,XX @@ | ||
933 | #ifndef __counted_by | ||
934 | #define __counted_by(m) | ||
935 | #endif | ||
936 | + | ||
937 | +#endif /* _LINUX_STDDEF_H */ | ||
938 | diff --git a/linux-headers/linux/userfaultfd.h b/linux-headers/linux/userfaultfd.h | ||
939 | index XXXXXXX..XXXXXXX 100644 | ||
940 | --- a/linux-headers/linux/userfaultfd.h | ||
941 | +++ b/linux-headers/linux/userfaultfd.h | ||
942 | @@ -XXX,XX +XXX,XX @@ | ||
943 | UFFD_FEATURE_EXACT_ADDRESS | \ | ||
944 | UFFD_FEATURE_WP_HUGETLBFS_SHMEM | \ | ||
945 | UFFD_FEATURE_WP_UNPOPULATED | \ | ||
946 | - UFFD_FEATURE_POISON) | ||
947 | + UFFD_FEATURE_POISON | \ | ||
948 | + UFFD_FEATURE_WP_ASYNC) | ||
949 | #define UFFD_API_IOCTLS \ | ||
950 | ((__u64)1 << _UFFDIO_REGISTER | \ | ||
951 | (__u64)1 << _UFFDIO_UNREGISTER | \ | ||
952 | @@ -XXX,XX +XXX,XX @@ struct uffdio_api { | ||
953 | * (i.e. empty ptes). This will be the default behavior for shmem | ||
954 | * & hugetlbfs, so this flag only affects anonymous memory behavior | ||
955 | * when userfault write-protection mode is registered. | ||
956 | + * | ||
957 | + * UFFD_FEATURE_WP_ASYNC indicates that userfaultfd write-protection | ||
958 | + * asynchronous mode is supported in which the write fault is | ||
959 | + * automatically resolved and write-protection is un-set. | ||
960 | + * It implies UFFD_FEATURE_WP_UNPOPULATED. | ||
961 | */ | ||
962 | #define UFFD_FEATURE_PAGEFAULT_FLAG_WP (1<<0) | ||
963 | #define UFFD_FEATURE_EVENT_FORK (1<<1) | ||
964 | @@ -XXX,XX +XXX,XX @@ struct uffdio_api { | ||
965 | #define UFFD_FEATURE_WP_HUGETLBFS_SHMEM (1<<12) | ||
966 | #define UFFD_FEATURE_WP_UNPOPULATED (1<<13) | ||
967 | #define UFFD_FEATURE_POISON (1<<14) | ||
968 | +#define UFFD_FEATURE_WP_ASYNC (1<<15) | ||
969 | __u64 features; | ||
970 | |||
971 | __u64 ioctls; | ||
972 | diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h | ||
973 | index XXXXXXX..XXXXXXX 100644 | ||
974 | --- a/linux-headers/linux/vfio.h | ||
975 | +++ b/linux-headers/linux/vfio.h | ||
976 | @@ -XXX,XX +XXX,XX @@ struct vfio_region_info { | ||
977 | #define VFIO_REGION_INFO_FLAG_CAPS (1 << 3) /* Info supports caps */ | ||
978 | __u32 index; /* Region index */ | ||
979 | __u32 cap_offset; /* Offset within info struct of first cap */ | ||
980 | - __u64 size; /* Region size (bytes) */ | ||
981 | - __u64 offset; /* Region offset from start of device fd */ | ||
982 | + __aligned_u64 size; /* Region size (bytes) */ | ||
983 | + __aligned_u64 offset; /* Region offset from start of device fd */ | ||
984 | }; | ||
985 | #define VFIO_DEVICE_GET_REGION_INFO _IO(VFIO_TYPE, VFIO_BASE + 8) | ||
986 | |||
987 | @@ -XXX,XX +XXX,XX @@ struct vfio_region_info { | ||
988 | #define VFIO_REGION_INFO_CAP_SPARSE_MMAP 1 | ||
989 | |||
990 | struct vfio_region_sparse_mmap_area { | ||
991 | - __u64 offset; /* Offset of mmap'able area within region */ | ||
992 | - __u64 size; /* Size of mmap'able area */ | ||
993 | + __aligned_u64 offset; /* Offset of mmap'able area within region */ | ||
994 | + __aligned_u64 size; /* Size of mmap'able area */ | ||
995 | }; | ||
996 | |||
997 | struct vfio_region_info_cap_sparse_mmap { | ||
998 | @@ -XXX,XX +XXX,XX @@ struct vfio_device_migration_info { | ||
999 | VFIO_DEVICE_STATE_V1_RESUMING) | ||
1000 | |||
1001 | __u32 reserved; | ||
1002 | - __u64 pending_bytes; | ||
1003 | - __u64 data_offset; | ||
1004 | - __u64 data_size; | ||
1005 | + __aligned_u64 pending_bytes; | ||
1006 | + __aligned_u64 data_offset; | ||
1007 | + __aligned_u64 data_size; | ||
1008 | }; | ||
1009 | |||
1010 | /* | ||
1011 | @@ -XXX,XX +XXX,XX @@ struct vfio_device_migration_info { | ||
1012 | |||
1013 | struct vfio_region_info_cap_nvlink2_ssatgt { | ||
1014 | struct vfio_info_cap_header header; | ||
1015 | - __u64 tgt; | ||
1016 | + __aligned_u64 tgt; | ||
1017 | }; | ||
1018 | |||
1019 | /* | ||
1020 | @@ -XXX,XX +XXX,XX @@ struct vfio_device_gfx_plane_info { | ||
1021 | __u32 drm_plane_type; /* type of plane: DRM_PLANE_TYPE_* */ | ||
1022 | /* out */ | ||
1023 | __u32 drm_format; /* drm format of plane */ | ||
1024 | - __u64 drm_format_mod; /* tiled mode */ | ||
1025 | + __aligned_u64 drm_format_mod; /* tiled mode */ | ||
1026 | __u32 width; /* width of plane */ | ||
1027 | __u32 height; /* height of plane */ | ||
1028 | __u32 stride; /* stride of plane */ | ||
1029 | @@ -XXX,XX +XXX,XX @@ struct vfio_device_gfx_plane_info { | ||
1030 | __u32 region_index; /* region index */ | ||
1031 | __u32 dmabuf_id; /* dma-buf id */ | ||
1032 | }; | ||
1033 | + __u32 reserved; | ||
1034 | }; | ||
1035 | |||
1036 | #define VFIO_DEVICE_QUERY_GFX_PLANE _IO(VFIO_TYPE, VFIO_BASE + 14) | ||
1037 | @@ -XXX,XX +XXX,XX @@ struct vfio_device_ioeventfd { | ||
1038 | #define VFIO_DEVICE_IOEVENTFD_32 (1 << 2) /* 4-byte write */ | ||
1039 | #define VFIO_DEVICE_IOEVENTFD_64 (1 << 3) /* 8-byte write */ | ||
1040 | #define VFIO_DEVICE_IOEVENTFD_SIZE_MASK (0xf) | ||
1041 | - __u64 offset; /* device fd offset of write */ | ||
1042 | - __u64 data; /* data to be written */ | ||
1043 | + __aligned_u64 offset; /* device fd offset of write */ | ||
1044 | + __aligned_u64 data; /* data to be written */ | ||
1045 | __s32 fd; /* -1 for de-assignment */ | ||
1046 | + __u32 reserved; | ||
1047 | }; | ||
1048 | |||
1049 | #define VFIO_DEVICE_IOEVENTFD _IO(VFIO_TYPE, VFIO_BASE + 16) | ||
1050 | @@ -XXX,XX +XXX,XX @@ struct vfio_device_feature_mig_data_size { | ||
1051 | |||
1052 | #define VFIO_DEVICE_FEATURE_MIG_DATA_SIZE 9 | ||
1053 | |||
1054 | +/** | ||
1055 | + * Upon VFIO_DEVICE_FEATURE_SET, set or clear the BUS mastering for the device | ||
1056 | + * based on the operation specified in op flag. | ||
1057 | + * | ||
1058 | + * The functionality is incorporated for devices that needs bus master control, | ||
1059 | + * but the in-band device interface lacks the support. Consequently, it is not | ||
1060 | + * applicable to PCI devices, as bus master control for PCI devices is managed | ||
1061 | + * in-band through the configuration space. At present, this feature is supported | ||
1062 | + * only for CDX devices. | ||
1063 | + * When the device's BUS MASTER setting is configured as CLEAR, it will result in | ||
1064 | + * blocking all incoming DMA requests from the device. On the other hand, configuring | ||
1065 | + * the device's BUS MASTER setting as SET (enable) will grant the device the | ||
1066 | + * capability to perform DMA to the host memory. | ||
1067 | + */ | ||
1068 | +struct vfio_device_feature_bus_master { | ||
1069 | + __u32 op; | ||
1070 | +#define VFIO_DEVICE_FEATURE_CLEAR_MASTER 0 /* Clear Bus Master */ | ||
1071 | +#define VFIO_DEVICE_FEATURE_SET_MASTER 1 /* Set Bus Master */ | ||
1072 | +}; | ||
1073 | +#define VFIO_DEVICE_FEATURE_BUS_MASTER 10 | ||
1074 | + | ||
1075 | /* -------- API for Type1 VFIO IOMMU -------- */ | ||
1076 | |||
1077 | /** | ||
1078 | @@ -XXX,XX +XXX,XX @@ struct vfio_iommu_type1_info { | ||
1079 | __u32 flags; | ||
1080 | #define VFIO_IOMMU_INFO_PGSIZES (1 << 0) /* supported page sizes info */ | ||
1081 | #define VFIO_IOMMU_INFO_CAPS (1 << 1) /* Info supports caps */ | ||
1082 | - __u64 iova_pgsizes; /* Bitmap of supported page sizes */ | ||
1083 | + __aligned_u64 iova_pgsizes; /* Bitmap of supported page sizes */ | ||
1084 | __u32 cap_offset; /* Offset within info struct of first cap */ | ||
1085 | __u32 pad; | ||
1086 | }; | ||
1087 | diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h | ||
1088 | index XXXXXXX..XXXXXXX 100644 | ||
1089 | --- a/linux-headers/linux/vhost.h | ||
1090 | +++ b/linux-headers/linux/vhost.h | ||
1091 | @@ -XXX,XX +XXX,XX @@ | ||
1092 | */ | ||
1093 | #define VHOST_VDPA_RESUME _IO(VHOST_VIRTIO, 0x7E) | ||
1094 | |||
1095 | +/* Get the group for the descriptor table including driver & device areas | ||
1096 | + * of a virtqueue: read index, write group in num. | ||
1097 | + * The virtqueue index is stored in the index field of vhost_vring_state. | ||
1098 | + * The group ID of the descriptor table for this specific virtqueue | ||
1099 | + * is returned via num field of vhost_vring_state. | ||
1100 | + */ | ||
1101 | +#define VHOST_VDPA_GET_VRING_DESC_GROUP _IOWR(VHOST_VIRTIO, 0x7F, \ | ||
1102 | + struct vhost_vring_state) | ||
1103 | #endif | ||
1104 | -- | 200 | -- |
1105 | 2.43.0 | 201 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Sunil V L <sunilvl@ventanamicro.com> | 1 | From: Sunil V L <sunilvl@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Update the GPEX host bridge properties related to MMIO ranges with | 3 | Add a new machine option called 'iommu-sys' that enables a |
4 | values set for the virt machine. | 4 | riscv-iommu-sys platform device for the 'virt' machine. The option is |
5 | 5 | default 'off'. | |
6 | Suggested-by: Igor Mammedov <imammedo@redhat.com> | 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 | |||
7 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | 13 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> |
14 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | 16 | Message-ID: <20241106133407.604587-5-dbarboza@ventanamicro.com> |
10 | Message-ID: <20231218150247.466427-12-sunilvl@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 18 | --- |
13 | include/hw/riscv/virt.h | 1 + | 19 | include/hw/riscv/iommu.h | 2 + |
14 | hw/riscv/virt.c | 47 ++++++++++++++++++++++++++++------------- | 20 | include/hw/riscv/virt.h | 6 ++- |
15 | 2 files changed, 33 insertions(+), 15 deletions(-) | 21 | hw/riscv/virt.c | 104 ++++++++++++++++++++++++++++++++++++++- |
16 | 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 | ||
17 | diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h | 35 | diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h |
18 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/include/hw/riscv/virt.h | 37 | --- a/include/hw/riscv/virt.h |
20 | +++ b/include/hw/riscv/virt.h | 38 | +++ b/include/hw/riscv/virt.h |
21 | @@ -XXX,XX +XXX,XX @@ struct RISCVVirtState { | 39 | @@ -XXX,XX +XXX,XX @@ struct RISCVVirtState { |
22 | char *oem_table_id; | ||
23 | OnOffAuto acpi; | 40 | OnOffAuto acpi; |
24 | const MemMapEntry *memmap; | 41 | const MemMapEntry *memmap; |
25 | + struct GPEXHost *gpex_host; | 42 | struct GPEXHost *gpex_host; |
43 | + OnOffAuto iommu_sys; | ||
26 | }; | 44 | }; |
27 | 45 | ||
28 | enum { | 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 | |||
29 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 73 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
30 | index XXXXXXX..XXXXXXX 100644 | 74 | index XXXXXXX..XXXXXXX 100644 |
31 | --- a/hw/riscv/virt.c | 75 | --- a/hw/riscv/virt.c |
32 | +++ b/hw/riscv/virt.c | 76 | +++ b/hw/riscv/virt.c |
33 | @@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap) | 77 | @@ -XXX,XX +XXX,XX @@ |
34 | } | 78 | #include "target/riscv/pmu.h" |
35 | 79 | #include "hw/riscv/riscv_hart.h" | |
36 | static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, | 80 | #include "hw/riscv/iommu.h" |
37 | - hwaddr ecam_base, hwaddr ecam_size, | 81 | +#include "hw/riscv/riscv-iommu-bits.h" |
38 | - hwaddr mmio_base, hwaddr mmio_size, | 82 | #include "hw/riscv/virt.h" |
39 | - hwaddr high_mmio_base, | 83 | #include "hw/riscv/boot.h" |
40 | - hwaddr high_mmio_size, | 84 | #include "hw/riscv/numa.h" |
41 | - hwaddr pio_base, | 85 | @@ -XXX,XX +XXX,XX @@ static const MemMapEntry virt_memmap[] = { |
42 | - DeviceState *irqchip) | 86 | [VIRT_CLINT] = { 0x2000000, 0x10000 }, |
43 | + DeviceState *irqchip, | 87 | [VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 }, |
44 | + RISCVVirtState *s) | 88 | [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, |
45 | { | 89 | + [VIRT_IOMMU_SYS] = { 0x3010000, 0x1000 }, |
46 | DeviceState *dev; | 90 | [VIRT_PLATFORM_BUS] = { 0x4000000, 0x2000000 }, |
47 | MemoryRegion *ecam_alias, *ecam_reg; | 91 | [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) }, |
48 | MemoryRegion *mmio_alias, *high_mmio_alias, *mmio_reg; | 92 | [VIRT_APLIC_M] = { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) }, |
49 | + hwaddr ecam_base = s->memmap[VIRT_PCIE_ECAM].base; | 93 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap, |
50 | + hwaddr ecam_size = s->memmap[VIRT_PCIE_ECAM].size; | 94 | |
51 | + hwaddr mmio_base = s->memmap[VIRT_PCIE_MMIO].base; | 95 | static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, |
52 | + hwaddr mmio_size = s->memmap[VIRT_PCIE_MMIO].size; | 96 | uint32_t irq_pcie_phandle, |
53 | + hwaddr high_mmio_base = virt_high_pcie_memmap.base; | 97 | - uint32_t msi_pcie_phandle) |
54 | + hwaddr high_mmio_size = virt_high_pcie_memmap.size; | 98 | + uint32_t msi_pcie_phandle, |
55 | + hwaddr pio_base = s->memmap[VIRT_PCIE_PIO].base; | 99 | + uint32_t iommu_sys_phandle) |
56 | + hwaddr pio_size = s->memmap[VIRT_PCIE_PIO].size; | 100 | { |
57 | qemu_irq irq; | 101 | g_autofree char *name = NULL; |
58 | int i; | 102 | MachineState *ms = MACHINE(s); |
59 | 103 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, | |
60 | dev = qdev_new(TYPE_GPEX_HOST); | 104 | 2, virt_high_pcie_memmap.base, |
61 | 105 | 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size); | |
62 | + /* Set GPEX object properties for the virt machine */ | 106 | |
63 | + object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_BASE, | 107 | + if (virt_is_iommu_sys_enabled(s)) { |
64 | + ecam_base, NULL); | 108 | + qemu_fdt_setprop_cells(ms->fdt, name, "iommu-map", |
65 | + object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ECAM_SIZE, | 109 | + 0, iommu_sys_phandle, 0, 0, 0, |
66 | + ecam_size, NULL); | 110 | + iommu_sys_phandle, 0, 0xffff); |
67 | + object_property_set_uint(OBJECT(GPEX_HOST(dev)), | 111 | + } |
68 | + PCI_HOST_BELOW_4G_MMIO_BASE, | 112 | + |
69 | + mmio_base, NULL); | 113 | create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle); |
70 | + object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_BELOW_4G_MMIO_SIZE, | 114 | } |
71 | + mmio_size, NULL); | 115 | |
72 | + object_property_set_uint(OBJECT(GPEX_HOST(dev)), | 116 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_virtio_iommu(RISCVVirtState *s, uint16_t bdf) |
73 | + PCI_HOST_ABOVE_4G_MMIO_BASE, | 117 | bdf + 1, iommu_phandle, bdf + 1, 0xffff - bdf); |
74 | + high_mmio_base, NULL); | 118 | } |
75 | + object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_ABOVE_4G_MMIO_SIZE, | 119 | |
76 | + high_mmio_size, NULL); | 120 | +static void create_fdt_iommu_sys(RISCVVirtState *s, uint32_t irq_chip, |
77 | + object_property_set_uint(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_BASE, | 121 | + uint32_t *iommu_sys_phandle) |
78 | + pio_base, NULL); | 122 | +{ |
79 | + object_property_set_int(OBJECT(GPEX_HOST(dev)), PCI_HOST_PIO_SIZE, | 123 | + const char comp[] = "riscv,iommu"; |
80 | + pio_size, NULL); | 124 | + void *fdt = MACHINE(s)->fdt; |
81 | + | 125 | + uint32_t iommu_phandle; |
82 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 126 | + g_autofree char *iommu_node = NULL; |
83 | 127 | + hwaddr addr = s->memmap[VIRT_IOMMU_SYS].base; | |
84 | ecam_alias = g_new0(MemoryRegion, 1); | 128 | + hwaddr size = s->memmap[VIRT_IOMMU_SYS].size; |
85 | @@ -XXX,XX +XXX,XX @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, | 129 | + uint32_t iommu_irq_map[RISCV_IOMMU_INTR_COUNT] = { |
86 | gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i); | 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); | ||
87 | } | 184 | } |
88 | 185 | ||
89 | + GPEX_HOST(dev)->gpex_cfg.bus = PCI_HOST_BRIDGE(GPEX_HOST(dev))->bus; | 186 | + if (virt_is_iommu_sys_enabled(s)) { |
90 | return dev; | 187 | + DeviceState *iommu_sys = qdev_new(TYPE_RISCV_IOMMU_SYS); |
91 | } | 188 | + |
92 | 189 | + object_property_set_uint(OBJECT(iommu_sys), "addr", | |
93 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) | 190 | + s->memmap[VIRT_IOMMU_SYS].base, |
94 | qdev_get_gpio_in(virtio_irqchip, VIRTIO_IRQ + i)); | 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); | ||
95 | } | 253 | } |
96 | 254 | ||
97 | - gpex_pcie_init(system_memory, | 255 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, |
98 | - memmap[VIRT_PCIE_ECAM].base, | 256 | |
99 | - memmap[VIRT_PCIE_ECAM].size, | 257 | if (object_dynamic_cast(OBJECT(dev), TYPE_RISCV_IOMMU_PCI)) { |
100 | - memmap[VIRT_PCIE_MMIO].base, | 258 | create_fdt_iommu(s, pci_get_bdf(PCI_DEVICE(dev))); |
101 | - memmap[VIRT_PCIE_MMIO].size, | 259 | + s->iommu_sys = ON_OFF_AUTO_OFF; |
102 | - virt_high_pcie_memmap.base, | 260 | } |
103 | - virt_high_pcie_memmap.size, | 261 | } |
104 | - memmap[VIRT_PCIE_PIO].base, | 262 | |
105 | - pcie_irqchip); | 263 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data) |
106 | + gpex_pcie_init(system_memory, pcie_irqchip, s); | 264 | NULL, NULL); |
107 | 265 | object_class_property_set_description(oc, "acpi", | |
108 | create_platform_bus(s, mmio_irqchip); | 266 | "Enable ACPI"); |
109 | 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 = { | ||
110 | -- | 276 | -- |
111 | 2.43.0 | 277 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Our current logic in get/setters of MISA and multi-letter extensions | 3 | MSIx support is added in the RISC-V IOMMU platform device by including |
4 | works because we have only 2 CPU types, generic and vendor, and by using | 4 | the required MSIx facilities to alow software to properly setup the MSIx |
5 | "!generic" we're implying that we're talking about vendor CPUs. When adding | 5 | subsystem. |
6 | a third CPU type this logic will break so let's handle it beforehand. | 6 | |
7 | 7 | We took inspiration of what is being done in the riscv-iommu-pci device, | |
8 | In set_misa_ext_cfg() and set_multi_ext_cfg(), check for "vendor" cpu instead | 8 | mainly msix_init() and msix_notify(), while keeping in mind that |
9 | of "not generic". The "generic CPU" checks remaining are from | 9 | riscv-iommu-sys isn't a true PCI device and we don't need to copy/paste |
10 | riscv_cpu_add_misa_properties() and cpu_add_multi_ext_prop() before | 10 | all the contents of these MSIx functions. |
11 | applying default values for the extensions. | 11 | |
12 | 12 | Two extra MSI MemoryRegions were added: 'msix-table' and 'msix-pba'. | |
13 | This leaves us with: | 13 | They are used to manage r/w of the MSI table and Pending Bit Array (PBA) |
14 | 14 | respectively. Both are subregions of the main IOMMU memory region, | |
15 | - vendor CPUs will not allow extension enablement, all other CPUs will; | 15 | iommu->regs_mr, initialized during riscv_iommu_realize(), and each one |
16 | 16 | has their own handlers for MSIx reads and writes. | |
17 | - generic CPUs will inherit default values for extensions, all others | 17 | |
18 | won't. | 18 | This is the expected memory map when using this device in the 'virt' |
19 | 19 | machine: | |
20 | And now we can add a new, third CPU type, that will allow extensions to | 20 | |
21 | be enabled and will not inherit defaults, without changing the existing | 21 | 0000000003010000-0000000003010fff (prio 0, i/o): riscv-iommu-regs |
22 | logic. | 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. | ||
23 | 30 | ||
24 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 31 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
25 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 32 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
26 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 33 | Message-ID: <20241106133407.604587-6-dbarboza@ventanamicro.com> |
27 | Message-ID: <20231218125334.37184-3-dbarboza@ventanamicro.com> | ||
28 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 34 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
29 | --- | 35 | --- |
30 | target/riscv/tcg/tcg-cpu.c | 13 +++++++++---- | 36 | hw/riscv/riscv-iommu-sys.c | 116 +++++++++++++++++++++++++++++++++++-- |
31 | 1 file changed, 9 insertions(+), 4 deletions(-) | 37 | hw/riscv/virt.c | 6 +- |
32 | 38 | hw/riscv/trace-events | 2 + | |
33 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 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 | ||
34 | index XXXXXXX..XXXXXXX 100644 | 42 | index XXXXXXX..XXXXXXX 100644 |
35 | --- a/target/riscv/tcg/tcg-cpu.c | 43 | --- a/hw/riscv/riscv-iommu-sys.c |
36 | +++ b/target/riscv/tcg/tcg-cpu.c | 44 | +++ b/hw/riscv/riscv-iommu-sys.c |
37 | @@ -XXX,XX +XXX,XX @@ static bool riscv_cpu_is_generic(Object *cpu_obj) | 45 | @@ -XXX,XX +XXX,XX @@ |
38 | return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL; | 46 | #include "qemu/host-utils.h" |
39 | } | 47 | #include "qemu/module.h" |
40 | 48 | #include "qom/object.h" | |
41 | +static bool riscv_cpu_is_vendor(Object *cpu_obj) | 49 | +#include "exec/exec-all.h" |
42 | +{ | 50 | +#include "trace.h" |
43 | + return object_dynamic_cast(cpu_obj, TYPE_RISCV_VENDOR_CPU) != NULL; | 51 | |
44 | +} | 52 | #include "riscv-iommu.h" |
45 | + | 53 | |
46 | /* | 54 | #define RISCV_IOMMU_SYSDEV_ICVEC_VECTORS 0x3333 |
47 | * We'll get here via the following path: | 55 | |
48 | * | 56 | +#define RISCV_IOMMU_PCI_MSIX_VECTORS 5 |
49 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name, | 57 | + |
50 | target_ulong misa_bit = misa_ext_cfg->misa_bit; | 58 | /* RISC-V IOMMU System Platform Device Emulation */ |
51 | RISCVCPU *cpu = RISCV_CPU(obj); | 59 | |
52 | CPURISCVState *env = &cpu->env; | 60 | struct RISCVIOMMUStateSys { |
53 | - bool generic_cpu = riscv_cpu_is_generic(obj); | 61 | @@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUStateSys { |
54 | + bool vendor_cpu = riscv_cpu_is_vendor(obj); | 62 | uint32_t base_irq; |
55 | bool prev_val, value; | 63 | DeviceState *irqchip; |
56 | 64 | RISCVIOMMUState iommu; | |
57 | if (!visit_type_bool(v, name, &value, errp)) { | 65 | + |
58 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name, | 66 | + /* Wired int support */ |
59 | } | 67 | qemu_irq irqs[RISCV_IOMMU_INTR_COUNT]; |
60 | 68 | + | |
61 | if (value) { | 69 | + /* Memory Regions for MSIX table and pending bit entries. */ |
62 | - if (!generic_cpu) { | 70 | + MemoryRegion msix_table_mmio; |
63 | + if (vendor_cpu) { | 71 | + MemoryRegion msix_pba_mmio; |
64 | g_autofree char *cpuname = riscv_cpu_get_name(cpu); | 72 | + uint8_t *msix_table; |
65 | error_setg(errp, "'%s' CPU does not allow enabling extensions", | 73 | + uint8_t *msix_pba; |
66 | cpuname); | 74 | +}; |
67 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name, | 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) | ||
68 | { | 171 | { |
69 | const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque; | 172 | RISCVIOMMUStateSys *s = container_of(iommu, RISCVIOMMUStateSys, iommu); |
70 | RISCVCPU *cpu = RISCV_CPU(obj); | 173 | uint32_t fctl = riscv_iommu_reg_get32(iommu, RISCV_IOMMU_REG_FCTL); |
71 | - bool generic_cpu = riscv_cpu_is_generic(obj); | 174 | |
72 | + bool vendor_cpu = riscv_cpu_is_vendor(obj); | 175 | - /* We do not support MSIs yet */ |
73 | bool prev_val, value; | 176 | - if (!(fctl & RISCV_IOMMU_FCTL_WSI)) { |
74 | 177 | + if (fctl & RISCV_IOMMU_FCTL_WSI) { | |
75 | if (!visit_type_bool(v, name, &value, errp)) { | 178 | + qemu_irq_pulse(s->irqs[vector]); |
76 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name, | 179 | + trace_riscv_iommu_sys_irq_sent(vector); |
77 | return; | 180 | return; |
78 | } | 181 | } |
79 | 182 | ||
80 | - if (value && !generic_cpu) { | 183 | - qemu_irq_pulse(s->irqs[vector]); |
81 | + if (value && vendor_cpu) { | 184 | + riscv_iommu_sysdev_send_MSI(s, vector); |
82 | g_autofree char *cpuname = riscv_cpu_get_name(cpu); | 185 | } |
83 | error_setg(errp, "'%s' CPU does not allow enabling extensions", | 186 | |
84 | cpuname); | 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" | ||
85 | -- | 247 | -- |
86 | 2.43.0 | 248 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | zic64b is defined in the RVA22U64 profile [1] as a named feature for | 3 | Add a riscv_iommu_reset() helper in the base emulation code that |
4 | "Cache blocks must be 64 bytes in size, naturally aligned in the address | 4 | implements the expected reset behavior as defined by the riscv-iommu |
5 | space". It's a fantasy name for 64 bytes cache blocks. The RVA22U64 | 5 | spec. |
6 | profile mandates this feature, meaning that applications using this | 6 | |
7 | profile expects 64 bytes cache blocks. | 7 | Devices can then use this helper in their own reset callbacks. |
8 | |||
9 | To make the upcoming RVA22U64 implementation complete, we'll zic64b as | ||
10 | a 'named feature', not a regular extension. This means that: | ||
11 | |||
12 | - it won't be exposed to users; | ||
13 | - it won't be written in riscv,isa. | ||
14 | |||
15 | This will be extended to other named extensions in the future, so we're | ||
16 | creating some common boilerplate for them as well. | ||
17 | |||
18 | zic64b is default to 'true' since we're already using 64 bytes blocks. | ||
19 | If any cache block size (cbo{m,p,z}_blocksize) is changed to something | ||
20 | different than 64, zic64b is set to 'false'. | ||
21 | |||
22 | Our profile implementation will then be able to check the current state | ||
23 | of zic64b and take the appropriate action (e.g. throw a warning). | ||
24 | |||
25 | [1] https://github.com/riscv/riscv-profiles/releases/download/v1.0/profiles.pdf | ||
26 | 8 | ||
27 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 9 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
28 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 10 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
29 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Message-ID: <20241106133407.604587-7-dbarboza@ventanamicro.com> |
30 | Message-ID: <20231218125334.37184-7-dbarboza@ventanamicro.com> | ||
31 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
32 | --- | 13 | --- |
33 | target/riscv/cpu.h | 1 + | 14 | hw/riscv/riscv-iommu.h | 1 + |
34 | target/riscv/cpu_cfg.h | 1 + | 15 | include/hw/riscv/iommu.h | 6 ++++-- |
35 | target/riscv/cpu.c | 6 ++++++ | 16 | hw/riscv/riscv-iommu-pci.c | 20 ++++++++++++++++++++ |
36 | target/riscv/tcg/tcg-cpu.c | 26 ++++++++++++++++++++++++++ | 17 | hw/riscv/riscv-iommu-sys.c | 20 ++++++++++++++++++++ |
37 | 4 files changed, 34 insertions(+) | 18 | hw/riscv/riscv-iommu.c | 35 +++++++++++++++++++++++++++++++++++ |
38 | 19 | hw/riscv/trace-events | 2 ++ | |
39 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 20 | 6 files changed, 82 insertions(+), 2 deletions(-) |
40 | index XXXXXXX..XXXXXXX 100644 | 21 | |
41 | --- a/target/riscv/cpu.h | 22 | diff --git a/hw/riscv/riscv-iommu.h b/hw/riscv/riscv-iommu.h |
42 | +++ b/target/riscv/cpu.h | 23 | index XXXXXXX..XXXXXXX 100644 |
43 | @@ -XXX,XX +XXX,XX @@ typedef struct RISCVCPUMultiExtConfig { | 24 | --- a/hw/riscv/riscv-iommu.h |
44 | extern const RISCVCPUMultiExtConfig riscv_cpu_extensions[]; | 25 | +++ b/hw/riscv/riscv-iommu.h |
45 | extern const RISCVCPUMultiExtConfig riscv_cpu_vendor_exts[]; | 26 | @@ -XXX,XX +XXX,XX @@ struct RISCVIOMMUState { |
46 | extern const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[]; | 27 | void riscv_iommu_pci_setup_iommu(RISCVIOMMUState *iommu, PCIBus *bus, |
47 | +extern const RISCVCPUMultiExtConfig riscv_cpu_named_features[]; | 28 | Error **errp); |
48 | extern const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[]; | 29 | void riscv_iommu_set_cap_igs(RISCVIOMMUState *s, riscv_iommu_igs_mode mode); |
49 | extern Property riscv_cpu_options[]; | 30 | +void riscv_iommu_reset(RISCVIOMMUState *s); |
50 | 31 | ||
51 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | 32 | /* private helpers */ |
52 | index XXXXXXX..XXXXXXX 100644 | 33 | |
53 | --- a/target/riscv/cpu_cfg.h | 34 | diff --git a/include/hw/riscv/iommu.h b/include/hw/riscv/iommu.h |
54 | +++ b/target/riscv/cpu_cfg.h | 35 | index XXXXXXX..XXXXXXX 100644 |
55 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | 36 | --- a/include/hw/riscv/iommu.h |
56 | bool ext_smepmp; | 37 | +++ b/include/hw/riscv/iommu.h |
57 | bool rvv_ta_all_1s; | 38 | @@ -XXX,XX +XXX,XX @@ typedef struct RISCVIOMMUState RISCVIOMMUState; |
58 | bool rvv_ma_all_1s; | 39 | typedef struct RISCVIOMMUSpace RISCVIOMMUSpace; |
59 | + bool zic64b; | 40 | |
60 | 41 | #define TYPE_RISCV_IOMMU_PCI "riscv-iommu-pci" | |
61 | uint32_t mvendorid; | 42 | -OBJECT_DECLARE_SIMPLE_TYPE(RISCVIOMMUStatePci, RISCV_IOMMU_PCI) |
62 | uint64_t marchid; | 43 | +OBJECT_DECLARE_TYPE(RISCVIOMMUStatePci, RISCVIOMMUPciClass, RISCV_IOMMU_PCI) |
63 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 44 | typedef struct RISCVIOMMUStatePci RISCVIOMMUStatePci; |
64 | index XXXXXXX..XXXXXXX 100644 | 45 | +typedef struct RISCVIOMMUPciClass RISCVIOMMUPciClass; |
65 | --- a/target/riscv/cpu.c | 46 | |
66 | +++ b/target/riscv/cpu.c | 47 | #define TYPE_RISCV_IOMMU_SYS "riscv-iommu-device" |
67 | @@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { | 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[] = { | ||
68 | DEFINE_PROP_END_OF_LIST(), | 81 | DEFINE_PROP_END_OF_LIST(), |
69 | }; | 82 | }; |
70 | 83 | ||
71 | +const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = { | 84 | +static void riscv_iommu_pci_reset_hold(Object *obj, ResetType type) |
72 | + MULTI_EXT_CFG_BOOL("zic64b", zic64b, true), | 85 | +{ |
73 | + | 86 | + RISCVIOMMUStatePci *pci = RISCV_IOMMU_PCI(obj); |
74 | + DEFINE_PROP_END_OF_LIST(), | 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; | ||
75 | +}; | 116 | +}; |
76 | + | 117 | + |
77 | /* Deprecated entries marked for future removal */ | 118 | static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr, |
78 | const RISCVCPUMultiExtConfig riscv_cpu_deprecated_exts[] = { | 119 | unsigned size) |
79 | MULTI_EXT_CFG_BOOL("Zifencei", ext_zifencei, true), | 120 | { |
80 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 121 | @@ -XXX,XX +XXX,XX @@ static Property riscv_iommu_sys_properties[] = { |
81 | index XXXXXXX..XXXXXXX 100644 | 122 | DEFINE_PROP_END_OF_LIST(), |
82 | --- a/target/riscv/tcg/tcg-cpu.c | 123 | }; |
83 | +++ b/target/riscv/tcg/tcg-cpu.c | 124 | |
84 | @@ -XXX,XX +XXX,XX @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset) | 125 | +static void riscv_iommu_sys_reset_hold(Object *obj, ResetType type) |
85 | g_assert_not_reached(); | 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); | ||
86 | } | 151 | } |
87 | 152 | ||
88 | +static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset) | 153 | +void riscv_iommu_reset(RISCVIOMMUState *s) |
89 | +{ | 154 | +{ |
90 | + const RISCVCPUMultiExtConfig *feat; | 155 | + uint32_t reg_clr; |
91 | + | 156 | + int ddtp_mode; |
92 | + for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) { | 157 | + |
93 | + if (feat->offset == ext_offset) { | 158 | + /* |
94 | + return true; | 159 | + * Clear DDTP while setting DDTP_mode back to user |
95 | + } | 160 | + * initial setting. |
96 | + } | 161 | + */ |
97 | + | 162 | + ddtp_mode = s->enable_off ? |
98 | + return false; | 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); | ||
99 | +} | 186 | +} |
100 | + | 187 | + |
101 | static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env, | 188 | static const Property riscv_iommu_properties[] = { |
102 | uint32_t ext_offset) | 189 | DEFINE_PROP_UINT32("version", RISCVIOMMUState, version, |
103 | { | 190 | RISCV_IOMMU_SPEC_DOT_VER), |
104 | @@ -XXX,XX +XXX,XX @@ static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env, | 191 | diff --git a/hw/riscv/trace-events b/hw/riscv/trace-events |
105 | return; | 192 | index XXXXXXX..XXXXXXX 100644 |
106 | } | 193 | --- a/hw/riscv/trace-events |
107 | 194 | +++ b/hw/riscv/trace-events | |
108 | + if (cpu_cfg_offset_is_named_feat(ext_offset)) { | 195 | @@ -XXX,XX +XXX,XX @@ riscv_iommu_ats_inval(const char *id) "%s: dev-iotlb invalidate" |
109 | + return; | 196 | riscv_iommu_ats_prgr(const char *id) "%s: dev-iotlb page request group response" |
110 | + } | 197 | riscv_iommu_sys_irq_sent(uint32_t vector) "IRQ sent to vector %u" |
111 | + | 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" |
112 | ext_priv_ver = cpu_cfg_ext_get_min_version(ext_offset); | 199 | +riscv_iommu_sys_reset_hold(int reset_type) "reset type %d" |
113 | 200 | +riscv_iommu_pci_reset_hold(int reset_type) "reset type %d" | |
114 | if (env->priv_ver < ext_priv_ver) { | ||
115 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) | ||
116 | } | ||
117 | } | ||
118 | |||
119 | +static void riscv_cpu_update_named_features(RISCVCPU *cpu) | ||
120 | +{ | ||
121 | + cpu->cfg.zic64b = cpu->cfg.cbom_blocksize == 64 && | ||
122 | + cpu->cfg.cbop_blocksize == 64 && | ||
123 | + cpu->cfg.cboz_blocksize == 64; | ||
124 | +} | ||
125 | + | ||
126 | /* | ||
127 | * Check consistency between chosen extensions while setting | ||
128 | * cpu->cfg accordingly. | ||
129 | @@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp) | ||
130 | return; | ||
131 | } | ||
132 | |||
133 | + riscv_cpu_update_named_features(cpu); | ||
134 | + | ||
135 | if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) { | ||
136 | /* | ||
137 | * Enhanced PMP should only be available | ||
138 | -- | 201 | -- |
139 | 2.43.0 | 202 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | |||
3 | We already track user choice for multi-letter extensions because we | ||
4 | needed to honor user choice when enabling/disabling extensions during | ||
5 | realize(). We refrained from adding the same mechanism for MISA | ||
6 | extensions since we didn't need it. | ||
7 | |||
8 | Profile support requires tne need to check for user choice for MISA | ||
9 | extensions, so let's add the corresponding hash now. It works like the | ||
10 | existing multi-letter hash (multi_ext_user_opts) but tracking MISA bits | ||
11 | options in the cpu_set_misa_ext_cfg() callback. | ||
12 | |||
13 | Note that we can't re-use the same hash from multi-letter extensions | ||
14 | because that hash uses cpu->cfg offsets as keys, while for MISA | ||
15 | extensions we're using MISA bits as keys. | ||
16 | |||
17 | After adding the user hash in cpu_set_misa_ext_cfg(), setting default | ||
18 | values with object_property_set_bool() in add_misa_properties() will end | ||
19 | up marking the user choice hash with them. Set the default value | ||
20 | manually to avoid it. | ||
21 | 2 | ||
22 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 3 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
23 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
24 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 5 | Message-ID: <20241106133407.604587-8-dbarboza@ventanamicro.com> |
25 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
26 | Message-ID: <20231218125334.37184-12-dbarboza@ventanamicro.com> | ||
27 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
28 | --- | 7 | --- |
29 | target/riscv/tcg/tcg-cpu.c | 15 ++++++++++++++- | 8 | docs/specs/riscv-iommu.rst | 30 +++++++++++++++++++++++++++--- |
30 | 1 file changed, 14 insertions(+), 1 deletion(-) | 9 | docs/system/riscv/virt.rst | 10 ++++++++++ |
10 | 2 files changed, 37 insertions(+), 3 deletions(-) | ||
31 | 11 | ||
32 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 12 | diff --git a/docs/specs/riscv-iommu.rst b/docs/specs/riscv-iommu.rst |
33 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
34 | --- a/target/riscv/tcg/tcg-cpu.c | 14 | --- a/docs/specs/riscv-iommu.rst |
35 | +++ b/target/riscv/tcg/tcg-cpu.c | 15 | +++ b/docs/specs/riscv-iommu.rst |
36 | @@ -XXX,XX +XXX,XX @@ | 16 | @@ -XXX,XX +XXX,XX @@ RISC-V IOMMU support for RISC-V machines |
37 | 17 | QEMU implements a RISC-V IOMMU emulation based on the RISC-V IOMMU spec | |
38 | /* Hash that stores user set extensions */ | 18 | version 1.0 `iommu1.0`_. |
39 | static GHashTable *multi_ext_user_opts; | 19 | |
40 | +static GHashTable *misa_ext_user_opts; | 20 | -The emulation includes a PCI reference device, riscv-iommu-pci, that QEMU |
41 | 21 | -RISC-V boards can use. The 'virt' RISC-V machine is compatible with this | |
42 | static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset) | 22 | -device. |
43 | { | 23 | +The emulation includes a PCI reference device (riscv-iommu-pci) and a platform |
44 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name, | 24 | +bus device (riscv-iommu-sys) that QEMU RISC-V boards can use. The 'virt' |
45 | return; | 25 | +RISC-V machine is compatible with both devices. |
46 | } | 26 | |
47 | 27 | riscv-iommu-pci reference device | |
48 | + g_hash_table_insert(misa_ext_user_opts, | 28 | -------------------------------- |
49 | + GUINT_TO_POINTER(misa_bit), | 29 | @@ -XXX,XX +XXX,XX @@ Several options are available to control the capabilities of the device, namely: |
50 | + (gpointer)value); | 30 | - "s-stage": enable s-stage support |
31 | - "g-stage": enable g-stage support | ||
32 | |||
33 | +riscv-iommu-sys device | ||
34 | +---------------------- | ||
51 | + | 35 | + |
52 | prev_val = env->misa_ext & misa_bit; | 36 | +This device implements the RISC-V IOMMU emulation as a platform bus device that |
53 | 37 | +RISC-V boards can use. | |
54 | if (value == prev_val) { | 38 | + |
55 | @@ -XXX,XX +XXX,XX @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = { | 39 | +For the 'virt' board the device is disabled by default. To enable it use the |
56 | */ | 40 | +'iommu-sys' machine option: |
57 | static void riscv_cpu_add_misa_properties(Object *cpu_obj) | 41 | + |
58 | { | 42 | +.. code-block:: bash |
59 | + CPURISCVState *env = &RISCV_CPU(cpu_obj)->env; | 43 | + |
60 | bool use_def_vals = riscv_cpu_is_generic(cpu_obj); | 44 | + $ qemu-system-riscv64 -M virt,iommu-sys=on (...) |
61 | int i; | 45 | + |
62 | 46 | +There is no options to configure the capabilities of this device in the 'virt' | |
63 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj) | 47 | +board using the QEMU command line. The device is configured with the following |
64 | NULL, (void *)misa_cfg); | 48 | +riscv-iommu options: |
65 | object_property_set_description(cpu_obj, name, desc); | 49 | + |
66 | if (use_def_vals) { | 50 | +- "ioatc-limit": default value (2Mb) |
67 | - object_property_set_bool(cpu_obj, name, misa_cfg->enabled, NULL); | 51 | +- "intremap": enabled |
68 | + if (misa_cfg->enabled) { | 52 | +- "ats": enabled |
69 | + env->misa_ext |= bit; | 53 | +- "off": on (DMA disabled) |
70 | + env->misa_ext_mask |= bit; | 54 | +- "s-stage": enabled |
71 | + } else { | 55 | +- "g-stage": enabled |
72 | + env->misa_ext &= ~bit; | 56 | + |
73 | + env->misa_ext_mask &= ~bit; | 57 | .. _iommu1.0: https://github.com/riscv-non-isa/riscv-iommu/releases/download/v1.0/riscv-iommu.pdf |
74 | + } | 58 | |
75 | } | 59 | .. _linux-v8: https://lore.kernel.org/linux-riscv/cover.1718388908.git.tjeznach@rivosinc.com/ |
76 | } | 60 | diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst |
77 | } | 61 | index XXXXXXX..XXXXXXX 100644 |
78 | @@ -XXX,XX +XXX,XX @@ static void tcg_cpu_instance_init(CPUState *cs) | 62 | --- a/docs/system/riscv/virt.rst |
79 | RISCVCPU *cpu = RISCV_CPU(cs); | 63 | +++ b/docs/system/riscv/virt.rst |
80 | Object *obj = OBJECT(cpu); | 64 | @@ -XXX,XX +XXX,XX @@ command line: |
81 | 65 | ||
82 | + misa_ext_user_opts = g_hash_table_new(NULL, g_direct_equal); | 66 | $ qemu-system-riscv64 -M virt -device riscv-iommu-pci (...) |
83 | multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal); | 67 | |
84 | riscv_cpu_add_user_properties(obj); | 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 | -------------------- | ||
85 | 87 | ||
86 | -- | 88 | -- |
87 | 2.43.0 | 89 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Anton Blanchard <antonb@tenstorrent.com> |
---|---|---|---|
2 | 2 | ||
3 | We want to add a new CPU type for bare CPUs that will inherit specific | 3 | Add a CPU entry for the Tenstorrent Ascalon CPU, a series of 2 wide to |
4 | traits of the 2 existing types: | 4 | 8 wide RV64 cores. More details can be found at |
5 | https://tenstorrent.com/ip/tt-ascalon | ||
5 | 6 | ||
6 | - it will allow for extensions to be enabled/disabled, like generic | 7 | Signed-off-by: Anton Blanchard <antonb@tenstorrent.com> |
7 | CPUs; | 8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
8 | 9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | |
9 | - it will NOT inherit defaults, like vendor CPUs. | 10 | Message-ID: <20241113110459.1607299-1-antonb@tenstorrent.com> |
10 | |||
11 | We can make this conditions met by adding an explicit type for the | ||
12 | existing vendor CPUs and change the existing logic to not imply that | ||
13 | "not generic" means vendor CPUs. | ||
14 | |||
15 | Let's add the "vendor" CPU type first. | ||
16 | |||
17 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
18 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
19 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
20 | Message-ID: <20231218125334.37184-2-dbarboza@ventanamicro.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
22 | --- | 12 | --- |
23 | target/riscv/cpu-qom.h | 1 + | 13 | target/riscv/cpu-qom.h | 1 + |
24 | target/riscv/cpu.c | 30 +++++++++++++++++++++--------- | 14 | target/riscv/cpu.c | 67 ++++++++++++++++++++++++++++++++++++++++++ |
25 | 2 files changed, 22 insertions(+), 9 deletions(-) | 15 | 2 files changed, 68 insertions(+) |
26 | 16 | ||
27 | diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h | 17 | diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h |
28 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/target/riscv/cpu-qom.h | 19 | --- a/target/riscv/cpu-qom.h |
30 | +++ b/target/riscv/cpu-qom.h | 20 | +++ b/target/riscv/cpu-qom.h |
31 | @@ -XXX,XX +XXX,XX @@ | 21 | @@ -XXX,XX +XXX,XX @@ |
32 | 22 | #define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54") | |
33 | #define TYPE_RISCV_CPU "riscv-cpu" | 23 | #define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906") |
34 | #define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu" | 24 | #define TYPE_RISCV_CPU_VEYRON_V1 RISCV_CPU_TYPE_NAME("veyron-v1") |
35 | +#define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu" | 25 | +#define TYPE_RISCV_CPU_TT_ASCALON RISCV_CPU_TYPE_NAME("tt-ascalon") |
36 | 26 | #define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host") | |
37 | #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU | 27 | |
38 | #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX) | 28 | OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU) |
39 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 29 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
40 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
41 | --- a/target/riscv/cpu.c | 31 | --- a/target/riscv/cpu.c |
42 | +++ b/target/riscv/cpu.c | 32 | +++ b/target/riscv/cpu.c |
43 | @@ -XXX,XX +XXX,XX @@ char *riscv_isa_string(RISCVCPU *cpu) | 33 | @@ -XXX,XX +XXX,XX @@ static void rv64_veyron_v1_cpu_init(Object *obj) |
44 | .instance_init = initfn \ | 34 | #endif |
45 | } | 35 | } |
46 | 36 | ||
47 | +#define DEFINE_VENDOR_CPU(type_name, initfn) \ | 37 | +/* Tenstorrent Ascalon */ |
48 | + { \ | 38 | +static void rv64_tt_ascalon_cpu_init(Object *obj) |
49 | + .name = type_name, \ | 39 | +{ |
50 | + .parent = TYPE_RISCV_VENDOR_CPU, \ | 40 | + CPURISCVState *env = &RISCV_CPU(obj)->env; |
51 | + .instance_init = initfn \ | 41 | + RISCVCPU *cpu = RISCV_CPU(obj); |
52 | + } | ||
53 | + | 42 | + |
54 | static const TypeInfo riscv_cpu_type_infos[] = { | 43 | + riscv_cpu_set_misa_ext(env, RVG | RVC | RVS | RVU | RVH | RVV); |
55 | { | 44 | + env->priv_ver = PRIV_VERSION_1_13_0; |
56 | .name = TYPE_RISCV_CPU, | 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 | { | ||
57 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { | 106 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { |
58 | .parent = TYPE_RISCV_CPU, | 107 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, MXL_RV64, rv64_sifive_u_cpu_init), |
59 | .abstract = true, | 108 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C, MXL_RV64, rv64_sifive_u_cpu_init), |
60 | }, | 109 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64, rv64_thead_c906_cpu_init), |
61 | + { | 110 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64, rv64_tt_ascalon_cpu_init), |
62 | + .name = TYPE_RISCV_VENDOR_CPU, | 111 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, MXL_RV64, rv64_veyron_v1_cpu_init), |
63 | + .parent = TYPE_RISCV_CPU, | 112 | #ifdef CONFIG_TCG |
64 | + .abstract = true, | 113 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, MXL_RV128, rv128_base_cpu_init), |
65 | + }, | ||
66 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init), | ||
67 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, riscv_max_cpu_init), | ||
68 | #if defined(TARGET_RISCV32) | ||
69 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init), | ||
70 | - DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init), | ||
71 | - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init), | ||
72 | - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init), | ||
73 | - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init), | ||
74 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init), | ||
75 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init), | ||
76 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init), | ||
77 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init), | ||
78 | #elif defined(TARGET_RISCV64) | ||
79 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init), | ||
80 | - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init), | ||
81 | - DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init), | ||
82 | - DEFINE_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init), | ||
83 | - DEFINE_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init), | ||
84 | - DEFINE_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init), | ||
85 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init), | ||
86 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init), | ||
87 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_SHAKTI_C, rv64_sifive_u_cpu_init), | ||
88 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init), | ||
89 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init), | ||
90 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init), | ||
91 | #endif | ||
92 | }; | ||
93 | -- | 114 | -- |
94 | 2.43.0 | 115 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Add support for RVV and Vector CSR KVM regs vstart, vl and vtype. | 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. | ||
4 | 6 | ||
5 | Support for vregs[] requires KVM side changes and an extra reg (vlenb) | 7 | Rename it to be a bit clear what the helper is doing since we'll add |
6 | and will be added later. | 8 | more AIA helpers in the next patches. |
9 | |||
10 | Make the helper public because the 'virt' machine will use it as well. | ||
7 | 11 | ||
8 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 12 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-ID: <20231218204321.75757-5-dbarboza@ventanamicro.com> | 14 | Message-ID: <20241119191706.718860-2-dbarboza@ventanamicro.com> |
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 16 | --- |
13 | target/riscv/kvm/kvm-cpu.c | 74 ++++++++++++++++++++++++++++++++++++++ | 17 | include/hw/intc/riscv_aplic.h | 1 + |
14 | 1 file changed, 74 insertions(+) | 18 | hw/intc/riscv_aplic.c | 8 ++++---- |
19 | 2 files changed, 5 insertions(+), 4 deletions(-) | ||
15 | 20 | ||
16 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | 21 | diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h |
17 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/riscv/kvm/kvm-cpu.c | 23 | --- a/include/hw/intc/riscv_aplic.h |
19 | +++ b/target/riscv/kvm/kvm-cpu.c | 24 | +++ b/include/hw/intc/riscv_aplic.h |
20 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t idx) | 25 | @@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState { |
21 | |||
22 | #define RISCV_FP_D_REG(idx) kvm_riscv_reg_id_u64(KVM_REG_RISCV_FP_D, idx) | ||
23 | |||
24 | +#define RISCV_VECTOR_CSR_REG(env, name) \ | ||
25 | + kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_VECTOR, \ | ||
26 | + KVM_REG_RISCV_VECTOR_CSR_REG(name)) | ||
27 | + | ||
28 | #define KVM_RISCV_GET_CSR(cs, env, csr, reg) \ | ||
29 | do { \ | ||
30 | int _ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, csr), ®); \ | ||
31 | @@ -XXX,XX +XXX,XX @@ static KVMCPUConfig kvm_misa_ext_cfgs[] = { | ||
32 | KVM_MISA_CFG(RVH, KVM_RISCV_ISA_EXT_H), | ||
33 | KVM_MISA_CFG(RVI, KVM_RISCV_ISA_EXT_I), | ||
34 | KVM_MISA_CFG(RVM, KVM_RISCV_ISA_EXT_M), | ||
35 | + KVM_MISA_CFG(RVV, KVM_RISCV_ISA_EXT_V), | ||
36 | }; | 26 | }; |
37 | 27 | ||
38 | static void kvm_cpu_get_misa_ext_cfg(Object *obj, Visitor *v, | 28 | void riscv_aplic_add_child(DeviceState *parent, DeviceState *child); |
39 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs) | 29 | +bool riscv_is_kvm_aia_aplic_imsic(bool msimode); |
40 | env->kvm_timer_dirty = false; | 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; | ||
41 | } | 45 | } |
42 | 46 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) | |
43 | +static int kvm_riscv_get_regs_vector(CPUState *cs) | 47 | uint32_t i; |
44 | +{ | 48 | RISCVAPLICState *aplic = RISCV_APLIC(dev); |
45 | + CPURISCVState *env = &RISCV_CPU(cs)->env; | 49 | |
46 | + target_ulong reg; | 50 | - if (!is_kvm_aia(aplic->msimode)) { |
47 | + int ret = 0; | 51 | + if (!riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) { |
48 | + | 52 | aplic->bitfield_words = (aplic->num_irqs + 31) >> 5; |
49 | + if (!riscv_has_ext(env, RVV)) { | 53 | aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs); |
50 | + return 0; | 54 | aplic->state = g_new0(uint32_t, aplic->num_irqs); |
51 | + } | 55 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) |
52 | + | 56 | * have IRQ lines delegated by their parent APLIC. |
53 | + ret = kvm_get_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vstart), ®); | 57 | */ |
54 | + if (ret) { | 58 | if (!aplic->parent) { |
55 | + return ret; | 59 | - if (kvm_enabled() && is_kvm_aia(aplic->msimode)) { |
56 | + } | 60 | + if (kvm_enabled() && riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) { |
57 | + env->vstart = reg; | 61 | qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs); |
58 | + | 62 | } else { |
59 | + ret = kvm_get_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vl), ®); | 63 | qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs); |
60 | + if (ret) { | 64 | @@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size, |
61 | + return ret; | 65 | |
62 | + } | 66 | sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); |
63 | + env->vl = reg; | 67 | |
64 | + | 68 | - if (!is_kvm_aia(msimode)) { |
65 | + ret = kvm_get_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vtype), ®); | 69 | + if (!riscv_is_kvm_aia_aplic_imsic(msimode)) { |
66 | + if (ret) { | 70 | sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); |
67 | + return ret; | ||
68 | + } | ||
69 | + env->vtype = reg; | ||
70 | + | ||
71 | + return 0; | ||
72 | +} | ||
73 | + | ||
74 | +static int kvm_riscv_put_regs_vector(CPUState *cs) | ||
75 | +{ | ||
76 | + CPURISCVState *env = &RISCV_CPU(cs)->env; | ||
77 | + target_ulong reg; | ||
78 | + int ret = 0; | ||
79 | + | ||
80 | + if (!riscv_has_ext(env, RVV)) { | ||
81 | + return 0; | ||
82 | + } | ||
83 | + | ||
84 | + reg = env->vstart; | ||
85 | + ret = kvm_set_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vstart), ®); | ||
86 | + if (ret) { | ||
87 | + return ret; | ||
88 | + } | ||
89 | + | ||
90 | + reg = env->vl; | ||
91 | + ret = kvm_set_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vl), ®); | ||
92 | + if (ret) { | ||
93 | + return ret; | ||
94 | + } | ||
95 | + | ||
96 | + reg = env->vtype; | ||
97 | + ret = kvm_set_one_reg(cs, RISCV_VECTOR_CSR_REG(env, vtype), ®); | ||
98 | + | ||
99 | + return ret; | ||
100 | +} | ||
101 | + | ||
102 | typedef struct KVMScratchCPU { | ||
103 | int kvmfd; | ||
104 | int vmfd; | ||
105 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_get_registers(CPUState *cs) | ||
106 | return ret; | ||
107 | } | 71 | } |
108 | 72 | ||
109 | + ret = kvm_riscv_get_regs_vector(cs); | ||
110 | + if (ret) { | ||
111 | + return ret; | ||
112 | + } | ||
113 | + | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_put_registers(CPUState *cs, int level) | ||
118 | return ret; | ||
119 | } | ||
120 | |||
121 | + ret = kvm_riscv_put_regs_vector(cs); | ||
122 | + if (ret) { | ||
123 | + return ret; | ||
124 | + } | ||
125 | + | ||
126 | if (KVM_PUT_RESET_STATE == level) { | ||
127 | RISCVCPU *cpu = RISCV_CPU(cs); | ||
128 | if (cs->cpu_index == 0) { | ||
129 | -- | 73 | -- |
130 | 2.43.0 | 74 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | QEMU already implements zicbom (Cache Block Management Operations) and | 3 | In create_fdt_sockets() we have the following pattern: |
4 | zicboz (Cache Block Zero Operations). Commit 59cb29d6a5 ("target/riscv: | ||
5 | add Zicbop cbo.prefetch{i, r, m} placeholder") added placeholders for | ||
6 | what would be the instructions for zicbop (Cache Block Prefetch | ||
7 | Operations), which are now no-ops. | ||
8 | 4 | ||
9 | The RVA22U64 profile mandates zicbop, which means that applications that | 5 | if (kvm_enabled() && virt_use_kvm_aia(s)) { |
10 | run with this profile might expect zicbop to be present in the riscv,isa | 6 | (... do stuff ...) |
11 | DT and might behave badly if it's absent. | 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 | } | ||
12 | 15 | ||
13 | Adding zicbop as an extension will make our future RVA22U64 | 16 | Do everything in a single if/else clause to reduce the usage of |
14 | implementation more in line with what userspace expects and, if/when | 17 | virt_use_kvm_aia() helper and to make the code a bit less repetitive. |
15 | cache block prefetch operations became relevant to QEMU, we already have | ||
16 | the extension flag to turn then on/off as needed. | ||
17 | 18 | ||
18 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 19 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
19 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
20 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 20 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
21 | Message-ID: <20231218125334.37184-6-dbarboza@ventanamicro.com> | 21 | Message-ID: <20241119191706.718860-3-dbarboza@ventanamicro.com> |
22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
23 | --- | 23 | --- |
24 | target/riscv/cpu_cfg.h | 2 ++ | 24 | hw/riscv/virt.c | 10 ++++------ |
25 | hw/riscv/virt.c | 5 +++++ | 25 | 1 file changed, 4 insertions(+), 6 deletions(-) |
26 | target/riscv/cpu.c | 3 +++ | ||
27 | 3 files changed, 10 insertions(+) | ||
28 | 26 | ||
29 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/target/riscv/cpu_cfg.h | ||
32 | +++ b/target/riscv/cpu_cfg.h | ||
33 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
34 | bool ext_zicntr; | ||
35 | bool ext_zicsr; | ||
36 | bool ext_zicbom; | ||
37 | + bool ext_zicbop; | ||
38 | bool ext_zicboz; | ||
39 | bool ext_zicond; | ||
40 | bool ext_zihintntl; | ||
41 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | ||
42 | uint16_t vlen; | ||
43 | uint16_t elen; | ||
44 | uint16_t cbom_blocksize; | ||
45 | + uint16_t cbop_blocksize; | ||
46 | uint16_t cboz_blocksize; | ||
47 | bool mmu; | ||
48 | bool pmp; | ||
49 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 27 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
50 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
51 | --- a/hw/riscv/virt.c | 29 | --- a/hw/riscv/virt.c |
52 | +++ b/hw/riscv/virt.c | 30 | +++ b/hw/riscv/virt.c |
53 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, | 31 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, |
54 | cpu_ptr->cfg.cboz_blocksize); | 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 | } | ||
55 | } | 45 | } |
56 | 46 | - } | |
57 | + if (cpu_ptr->cfg.ext_zicbop) { | 47 | |
58 | + qemu_fdt_setprop_cell(ms->fdt, cpu_name, "riscv,cbop-block-size", | 48 | - if (kvm_enabled() && virt_use_kvm_aia(s)) { |
59 | + cpu_ptr->cfg.cbop_blocksize); | 49 | - *irq_mmio_phandle = xplic_phandles[0]; |
60 | + } | 50 | - *irq_virtio_phandle = xplic_phandles[0]; |
61 | + | 51 | - *irq_pcie_phandle = xplic_phandles[0]; |
62 | qemu_fdt_setprop_string(ms->fdt, cpu_name, "compatible", "riscv"); | 52 | - } else { |
63 | qemu_fdt_setprop_string(ms->fdt, cpu_name, "status", "okay"); | 53 | for (socket = 0; socket < socket_count; socket++) { |
64 | qemu_fdt_setprop_cell(ms->fdt, cpu_name, "reg", | 54 | if (socket == 0) { |
65 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 55 | *irq_mmio_phandle = xplic_phandles[socket]; |
66 | index XXXXXXX..XXXXXXX 100644 | ||
67 | --- a/target/riscv/cpu.c | ||
68 | +++ b/target/riscv/cpu.c | ||
69 | @@ -XXX,XX +XXX,XX @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, | ||
70 | */ | ||
71 | const RISCVIsaExtData isa_edata_arr[] = { | ||
72 | ISA_EXT_DATA_ENTRY(zicbom, PRIV_VERSION_1_12_0, ext_zicbom), | ||
73 | + ISA_EXT_DATA_ENTRY(zicbop, PRIV_VERSION_1_12_0, ext_zicbop), | ||
74 | ISA_EXT_DATA_ENTRY(zicboz, PRIV_VERSION_1_12_0, ext_zicboz), | ||
75 | ISA_EXT_DATA_ENTRY(zicond, PRIV_VERSION_1_12_0, ext_zicond), | ||
76 | ISA_EXT_DATA_ENTRY(zicntr, PRIV_VERSION_1_12_0, ext_zicntr), | ||
77 | @@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { | ||
78 | MULTI_EXT_CFG_BOOL("zhinxmin", ext_zhinxmin, false), | ||
79 | |||
80 | MULTI_EXT_CFG_BOOL("zicbom", ext_zicbom, true), | ||
81 | + MULTI_EXT_CFG_BOOL("zicbop", ext_zicbop, true), | ||
82 | MULTI_EXT_CFG_BOOL("zicboz", ext_zicboz, true), | ||
83 | |||
84 | MULTI_EXT_CFG_BOOL("zmmul", ext_zmmul, false), | ||
85 | @@ -XXX,XX +XXX,XX @@ Property riscv_cpu_options[] = { | ||
86 | DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), | ||
87 | |||
88 | DEFINE_PROP_UINT16("cbom_blocksize", RISCVCPU, cfg.cbom_blocksize, 64), | ||
89 | + DEFINE_PROP_UINT16("cbop_blocksize", RISCVCPU, cfg.cbop_blocksize, 64), | ||
90 | DEFINE_PROP_UINT16("cboz_blocksize", RISCVCPU, cfg.cboz_blocksize, 64), | ||
91 | |||
92 | DEFINE_PROP_END_OF_LIST(), | ||
93 | -- | 56 | -- |
94 | 2.43.0 | 57 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Previous patches added several g_hash_table_insert() patterns. Add two | 3 | Similar to the riscv_is_kvm_aia_aplic_imsic() helper from riscv_aplic.c, |
4 | helpers, one for each user hash, to make the code cleaner. | 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. | ||
5 | 10 | ||
6 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 11 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
7 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Message-ID: <20231218125334.37184-15-dbarboza@ventanamicro.com> | 13 | Message-ID: <20241119191706.718860-4-dbarboza@ventanamicro.com> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 15 | --- |
12 | target/riscv/tcg/tcg-cpu.c | 28 ++++++++++++++++------------ | 16 | hw/riscv/virt.c | 12 +++++++----- |
13 | 1 file changed, 16 insertions(+), 12 deletions(-) | 17 | 1 file changed, 7 insertions(+), 5 deletions(-) |
14 | 18 | ||
15 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 19 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
16 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/tcg/tcg-cpu.c | 21 | --- a/hw/riscv/virt.c |
18 | +++ b/target/riscv/tcg/tcg-cpu.c | 22 | +++ b/hw/riscv/virt.c |
19 | @@ -XXX,XX +XXX,XX @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset) | 23 | @@ -XXX,XX +XXX,XX @@ |
20 | GUINT_TO_POINTER(ext_offset)); | 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); | ||
21 | } | 34 | } |
22 | 35 | ||
23 | +static void cpu_cfg_ext_add_user_opt(uint32_t ext_offset, bool value) | 36 | static bool virt_aclint_allowed(void) |
24 | +{ | 37 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, |
25 | + g_hash_table_insert(multi_ext_user_opts, GUINT_TO_POINTER(ext_offset), | 38 | *msi_pcie_phandle = msi_s_phandle; |
26 | + (gpointer)value); | ||
27 | +} | ||
28 | + | ||
29 | +static void cpu_misa_ext_add_user_opt(uint32_t bit, bool value) | ||
30 | +{ | ||
31 | + g_hash_table_insert(misa_ext_user_opts, GUINT_TO_POINTER(bit), | ||
32 | + (gpointer)value); | ||
33 | +} | ||
34 | + | ||
35 | static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit, | ||
36 | bool enabled) | ||
37 | { | ||
38 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name, | ||
39 | return; | ||
40 | } | 39 | } |
41 | 40 | ||
42 | - g_hash_table_insert(misa_ext_user_opts, | 41 | - /* KVM AIA only has one APLIC instance */ |
43 | - GUINT_TO_POINTER(misa_bit), | 42 | - if (kvm_enabled() && virt_use_kvm_aia(s)) { |
44 | - (gpointer)value); | 43 | + /* KVM AIA aplic-imsic only has one APLIC instance */ |
45 | + cpu_misa_ext_add_user_opt(misa_bit, value); | 44 | + if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) { |
46 | 45 | create_fdt_socket_aplic(s, memmap, 0, | |
47 | prev_val = env->misa_ext & misa_bit; | 46 | msi_m_phandle, msi_s_phandle, phandle, |
48 | 47 | &intc_phandles[0], xplic_phandles, | |
49 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name, | 48 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) |
50 | continue; | ||
51 | } | 49 | } |
52 | |||
53 | - g_hash_table_insert(misa_ext_user_opts, | ||
54 | - GUINT_TO_POINTER(bit), | ||
55 | - (gpointer)value); | ||
56 | + cpu_misa_ext_add_user_opt(bit, profile->enabled); | ||
57 | riscv_cpu_write_misa_bit(cpu, bit, profile->enabled); | ||
58 | } | 50 | } |
59 | 51 | ||
60 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name, | 52 | - if (kvm_enabled() && virt_use_kvm_aia(s)) { |
61 | cpu_bump_multi_ext_priv_ver(&cpu->env, ext_offset); | 53 | + if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) { |
62 | } | 54 | kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT, |
63 | 55 | VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS, | |
64 | - g_hash_table_insert(multi_ext_user_opts, | 56 | memmap[VIRT_APLIC_S].base, |
65 | - GUINT_TO_POINTER(ext_offset), | ||
66 | - (gpointer)profile->enabled); | ||
67 | + cpu_cfg_ext_add_user_opt(ext_offset, profile->enabled); | ||
68 | isa_ext_update_enabled(cpu, ext_offset, profile->enabled); | ||
69 | } | ||
70 | } | ||
71 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name, | ||
72 | multi_ext_cfg->name, lower); | ||
73 | } | ||
74 | |||
75 | - g_hash_table_insert(multi_ext_user_opts, | ||
76 | - GUINT_TO_POINTER(multi_ext_cfg->offset), | ||
77 | - (gpointer)value); | ||
78 | + cpu_cfg_ext_add_user_opt(multi_ext_cfg->offset, value); | ||
79 | |||
80 | prev_val = isa_ext_is_enabled(cpu, multi_ext_cfg->offset); | ||
81 | |||
82 | -- | 57 | -- |
83 | 2.43.0 | 58 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | The emulated AIA within the Linux kernel restores the HART index | 3 | Before adding support to kernel-irqchip=split when using KVM AIA we need |
4 | of the IMSICs according to the configured AIA settings. During | 4 | to change how we create the in-kernel AIA device. |
5 | this process, the group setting is used only when the machine | ||
6 | partitions harts into groups. It's unnecessary to set the group | ||
7 | configuration if the machine has only one socket, as its address | ||
8 | space might not contain the group shift. | ||
9 | 5 | ||
10 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> | 6 | In the use case we have so far, i.e. in-kernel irqchip without split |
11 | Reviewed-by: Jim Shu <jim.shu@sifive.com> | 7 | mode, both the s-mode APLIC and IMSIC controllers are provided by the |
12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 8 | irqchip. In irqchip_split() mode we'll emulate the s-mode APLIC |
13 | Message-ID: <20231218090543.22353-2-yongxuan.wang@sifive.com> | 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> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 25 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
15 | --- | 26 | --- |
16 | target/riscv/kvm/kvm-cpu.c | 31 +++++++++++++++++-------------- | 27 | target/riscv/kvm/kvm-cpu.c | 38 +++++++++++++++++++++++--------------- |
17 | 1 file changed, 17 insertions(+), 14 deletions(-) | 28 | 1 file changed, 23 insertions(+), 15 deletions(-) |
18 | 29 | ||
19 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | 30 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c |
20 | index XXXXXXX..XXXXXXX 100644 | 31 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/riscv/kvm/kvm-cpu.c | 32 | --- a/target/riscv/kvm/kvm-cpu.c |
22 | +++ b/target/riscv/kvm/kvm-cpu.c | 33 | +++ b/target/riscv/kvm/kvm-cpu.c |
23 | @@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, | 34 | @@ -XXX,XX +XXX,XX @@ void kvm_riscv_aia_create(MachineState *machine, uint64_t group_shift, |
24 | exit(1); | 35 | } |
25 | } | 36 | } |
26 | 37 | ||
27 | - socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1; | ||
28 | - ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | 38 | - ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, |
29 | - KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS, | 39 | - KVM_DEV_RISCV_AIA_CONFIG_SRCS, |
30 | - &socket_bits, true, NULL); | 40 | - &aia_irq_num, true, NULL); |
31 | - if (ret < 0) { | 41 | - if (ret < 0) { |
32 | - error_report("KVM AIA: failed to set group_bits"); | 42 | - error_report("KVM AIA: failed to set number of input irq lines"); |
33 | - exit(1); | 43 | - exit(1); |
34 | - } | 44 | - } |
35 | 45 | + /* | |
36 | - ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | 46 | + * Skip APLIC creation in KVM if we're running split mode. |
37 | - KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT, | 47 | + * This is done by leaving KVM_DEV_RISCV_AIA_CONFIG_SRCS |
38 | - &group_shift, true, NULL); | 48 | + * unset. We can also skip KVM_DEV_RISCV_AIA_ADDR_APLIC |
39 | - if (ret < 0) { | 49 | + * since KVM won't be using it. |
40 | - error_report("KVM AIA: failed to set group_shift"); | 50 | + */ |
41 | - exit(1); | 51 | + if (!kvm_kernel_irqchip_split()) { |
42 | + if (socket_count > 1) { | ||
43 | + socket_bits = find_last_bit(&socket_count, BITS_PER_LONG) + 1; | ||
44 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | 52 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, |
45 | + KVM_DEV_RISCV_AIA_CONFIG_GROUP_BITS, | 53 | + KVM_DEV_RISCV_AIA_CONFIG_SRCS, |
46 | + &socket_bits, true, NULL); | 54 | + &aia_irq_num, true, NULL); |
47 | + if (ret < 0) { | 55 | + if (ret < 0) { |
48 | + error_report("KVM AIA: failed to set group_bits"); | 56 | + error_report("KVM AIA: failed to set number of input irq lines"); |
49 | + exit(1); | 57 | + exit(1); |
50 | + } | 58 | + } |
51 | + | 59 | + |
52 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, | 60 | + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_ADDR, |
53 | + KVM_DEV_RISCV_AIA_CONFIG_GROUP_SHIFT, | 61 | + KVM_DEV_RISCV_AIA_ADDR_APLIC, |
54 | + &group_shift, true, NULL); | 62 | + &aplic_base, true, NULL); |
55 | + if (ret < 0) { | 63 | + if (ret < 0) { |
56 | + error_report("KVM AIA: failed to set group_shift"); | 64 | + error_report("KVM AIA: failed to set the base address of APLIC"); |
57 | + exit(1); | 65 | + exit(1); |
58 | + } | 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); | ||
59 | } | 73 | } |
60 | 74 | ||
61 | guest_bits = guest_num == 0 ? 0 : | 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); | ||
62 | -- | 86 | -- |
63 | 2.43.0 | 87 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | Enabling a profile and then disabling some of its mandatory extensions | 3 | The current logic to determine if we don't need an emulated APLIC |
4 | is a valid use. It can be useful for debugging and testing. But the | 4 | controller, i.e. KVM will provide for us, is to determine if we're |
5 | common expected use of enabling a profile is to enable all its mandatory | 5 | running KVM, with in-kernel irqchip support, and running |
6 | extensions. | 6 | aia=aplic-imsic. This is modelled by riscv_is_kvm_aia_aplic_imsic() and |
7 | virt_use_kvm_aia_aplic_imsic(). | ||
7 | 8 | ||
8 | Add an user warning when mandatory extensions from an enabled profile | 9 | This won't suffice to support irqchip_split() mode: it will match |
9 | are disabled in the command line. We're also going to disable the | 10 | exactly the same conditions as the one above, but setting the irqchip to |
10 | profile flag in this case since the profile must include all the | 11 | 'split' mode will now require us to emulate an APLIC s-mode controller, |
11 | mandatory extensions. This flag can be exposed by QMP to indicate the | 12 | like we're doing with 'aia=aplic'. |
12 | actual profile state after the CPU is realized. | ||
13 | 13 | ||
14 | After this patch, this will throw warnings: | 14 | Create a new riscv_use_emulated_aplic() helper that will encapsulate |
15 | 15 | this logic. Replace the uses of "riscv_is_kvm_aia_aplic_imsic()" with | |
16 | -cpu rv64,rva22u64=true,zihintpause=false,zicbom=false,zicboz=false | 16 | this helper every time we're taking a decision on emulate an APLIC |
17 | 17 | controller or not. Do the same in virt.c with virt_use_emulated_aplic(). | |
18 | qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension zihintpause | ||
19 | qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension zicbom | ||
20 | qemu-system-riscv64: warning: Profile rva22u64 mandates disabled extension zicboz | ||
21 | |||
22 | Note that the following will NOT throw warnings because the profile is | ||
23 | being enabled last, hence all its mandatory extensions will be enabled: | ||
24 | |||
25 | -cpu rv64,zihintpause=false,zicbom=false,zicboz=false,rva22u64=true | ||
26 | 18 | ||
27 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 19 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
28 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
29 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 20 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
30 | Message-ID: <20231218125334.37184-17-dbarboza@ventanamicro.com> | 21 | Message-ID: <20241119191706.718860-6-dbarboza@ventanamicro.com> |
31 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
32 | --- | 23 | --- |
33 | target/riscv/tcg/tcg-cpu.c | 69 ++++++++++++++++++++++++++++++++++++++ | 24 | include/hw/intc/riscv_aplic.h | 1 + |
34 | 1 file changed, 69 insertions(+) | 25 | hw/intc/riscv_aplic.c | 24 +++++++++++++++++++++--- |
26 | hw/riscv/virt.c | 14 ++++++++++++-- | ||
27 | 3 files changed, 34 insertions(+), 5 deletions(-) | ||
35 | 28 | ||
36 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 29 | diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h |
37 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
38 | --- a/target/riscv/tcg/tcg-cpu.c | 31 | --- a/include/hw/intc/riscv_aplic.h |
39 | +++ b/target/riscv/tcg/tcg-cpu.c | 32 | +++ b/include/hw/intc/riscv_aplic.h |
40 | @@ -XXX,XX +XXX,XX @@ static int cpu_cfg_ext_get_min_version(uint32_t ext_offset) | 33 | @@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState { |
41 | g_assert_not_reached(); | 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; | ||
42 | } | 55 | } |
43 | 56 | ||
44 | +static const char *cpu_cfg_ext_get_name(uint32_t ext_offset) | 57 | +bool riscv_use_emulated_aplic(bool msimode) |
45 | +{ | 58 | +{ |
46 | + const RISCVCPUMultiExtConfig *feat; | 59 | +#ifdef CONFIG_KVM |
47 | + const RISCVIsaExtData *edata; | 60 | + if (tcg_enabled()) { |
48 | + | 61 | + return true; |
49 | + for (edata = isa_edata_arr; edata->name != NULL; edata++) { | ||
50 | + if (edata->ext_enable_offset == ext_offset) { | ||
51 | + return edata->name; | ||
52 | + } | ||
53 | + } | 62 | + } |
54 | + | 63 | + |
55 | + for (feat = riscv_cpu_named_features; feat->name != NULL; feat++) { | 64 | + if (!riscv_is_kvm_aia_aplic_imsic(msimode)) { |
56 | + if (feat->offset == ext_offset) { | 65 | + return true; |
57 | + return feat->name; | ||
58 | + } | ||
59 | + } | 66 | + } |
60 | + | 67 | + |
61 | + g_assert_not_reached(); | 68 | + return kvm_kernel_irqchip_split(); |
69 | +#else | ||
70 | + return true; | ||
71 | +#endif | ||
62 | +} | 72 | +} |
63 | + | 73 | + |
64 | static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset) | 74 | static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic, |
75 | uint32_t irq) | ||
65 | { | 76 | { |
66 | const RISCVCPUMultiExtConfig *feat; | 77 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) |
67 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | 78 | uint32_t i; |
68 | riscv_cpu_disable_priv_spec_isa_exts(cpu); | 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); | ||
69 | } | 110 | } |
70 | 111 | ||
71 | +static void riscv_cpu_validate_profile(RISCVCPU *cpu, | 112 | +static bool virt_use_emulated_aplic(RISCVVirtAIAType aia_type) |
72 | + RISCVCPUProfile *profile) | ||
73 | +{ | 113 | +{ |
74 | + const char *warn_msg = "Profile %s mandates disabled extension %s"; | 114 | + bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC; |
75 | + bool send_warn = profile->user_set && profile->enabled; | ||
76 | + bool profile_impl = true; | ||
77 | + int i; | ||
78 | + | 115 | + |
79 | + for (i = 0; misa_bits[i] != 0; i++) { | 116 | + return riscv_use_emulated_aplic(msimode); |
80 | + uint32_t bit = misa_bits[i]; | ||
81 | + | ||
82 | + if (!(profile->misa_ext & bit)) { | ||
83 | + continue; | ||
84 | + } | ||
85 | + | ||
86 | + if (!riscv_has_ext(&cpu->env, bit)) { | ||
87 | + profile_impl = false; | ||
88 | + | ||
89 | + if (send_warn) { | ||
90 | + warn_report(warn_msg, profile->name, | ||
91 | + riscv_get_misa_ext_name(bit)); | ||
92 | + } | ||
93 | + } | ||
94 | + } | ||
95 | + | ||
96 | + for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) { | ||
97 | + int ext_offset = profile->ext_offsets[i]; | ||
98 | + | ||
99 | + if (!isa_ext_is_enabled(cpu, ext_offset)) { | ||
100 | + profile_impl = false; | ||
101 | + | ||
102 | + if (send_warn) { | ||
103 | + warn_report(warn_msg, profile->name, | ||
104 | + cpu_cfg_ext_get_name(ext_offset)); | ||
105 | + } | ||
106 | + } | ||
107 | + } | ||
108 | + | ||
109 | + profile->enabled = profile_impl; | ||
110 | +} | 117 | +} |
111 | + | 118 | + |
112 | +static void riscv_cpu_validate_profiles(RISCVCPU *cpu) | 119 | static bool virt_aclint_allowed(void) |
113 | +{ | ||
114 | + for (int i = 0; riscv_profiles[i] != NULL; i++) { | ||
115 | + riscv_cpu_validate_profile(cpu, riscv_profiles[i]); | ||
116 | + } | ||
117 | +} | ||
118 | + | ||
119 | void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp) | ||
120 | { | 120 | { |
121 | CPURISCVState *env = &cpu->env; | 121 | return tcg_enabled() || qtest_enabled(); |
122 | @@ -XXX,XX +XXX,XX @@ void riscv_tcg_cpu_finalize_features(RISCVCPU *cpu, Error **errp) | 122 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, |
123 | *msi_pcie_phandle = msi_s_phandle; | ||
123 | } | 124 | } |
124 | 125 | ||
125 | riscv_cpu_update_named_features(cpu); | 126 | - /* KVM AIA aplic-imsic only has one APLIC instance */ |
126 | + riscv_cpu_validate_profiles(cpu); | 127 | - if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) { |
127 | 128 | + /* | |
128 | if (cpu->cfg.ext_smepmp && !cpu->cfg.pmp) { | 129 | + * With KVM AIA aplic-imsic, using an irqchip without split |
129 | /* | 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, | ||
130 | -- | 136 | -- |
131 | 2.43.0 | 137 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | This CPU was suggested by Alistair [1] and others during the profile | 3 | The last step to enable KVM AIA aplic-imsic with irqchip in split mode |
4 | design discussions. It consists of the bare 'rv64i' CPU with rva22u64 | 4 | is to deal with how MSIs are going to be sent. In our current design we |
5 | enabled by default, like an alias of '-cpu rv64i,rva22u64=true'. | 5 | don't allow an APLIC controller to send MSIs unless it's on m-mode. And |
6 | we also do not allow Supervisor MSI address configuration via the | ||
7 | 'smsiaddrcfg' and 'smsiaddrcfgh' registers unless it's also a m-mode | ||
8 | APLIC controller. | ||
6 | 9 | ||
7 | Users now have an even easier way of consuming this user-mode profile by | 10 | Add a new RISCVACPLICState attribute called 'kvm_msicfgaddr'. This |
8 | doing '-cpu rva22u64'. Extensions can be enabled/disabled at will on top | 11 | attribute represents the base configuration address for MSIs, in our |
9 | of it. | 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. | ||
10 | 14 | ||
11 | We can boot Linux with this "user-mode" CPU by doing: | 15 | During riscv_aplic_msi_send() we'll check if the attribute was set to |
12 | 16 | skip the check for a m-mode APLIC controller and to change the resulting | |
13 | -cpu rva22u64,sv39=true,s=true,zifencei=true | 17 | MSI addr by adding kvm_msicfgaddr right before address_space_stl_le(). |
14 | |||
15 | [1] https://lore.kernel.org/qemu-riscv/CAKmqyKP7xzZ9Sx=-Lbx2Ob0qCfB7Z+JO944FQ2TQ+49mqo0q_Q@mail.gmail.com/ | ||
16 | 18 | ||
17 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 19 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
18 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 20 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
19 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 21 | Message-ID: <20241119191706.718860-7-dbarboza@ventanamicro.com> |
20 | Message-ID: <20231218125334.37184-19-dbarboza@ventanamicro.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
22 | --- | 23 | --- |
23 | target/riscv/cpu-qom.h | 1 + | 24 | include/hw/intc/riscv_aplic.h | 6 +++++ |
24 | target/riscv/cpu.c | 17 +++++++++++++++++ | 25 | hw/intc/riscv_aplic.c | 42 +++++++++++++++++++++++++++-------- |
25 | target/riscv/tcg/tcg-cpu.c | 9 +++++++++ | 26 | hw/riscv/virt.c | 6 ++++- |
26 | 3 files changed, 27 insertions(+) | 27 | 3 files changed, 44 insertions(+), 10 deletions(-) |
27 | 28 | ||
28 | diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h | 29 | diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h |
29 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
30 | --- a/target/riscv/cpu-qom.h | 31 | --- a/include/hw/intc/riscv_aplic.h |
31 | +++ b/target/riscv/cpu-qom.h | 32 | +++ b/include/hw/intc/riscv_aplic.h |
32 | @@ -XXX,XX +XXX,XX @@ | 33 | @@ -XXX,XX +XXX,XX @@ struct RISCVAPLICState { |
33 | #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64") | 34 | uint32_t num_irqs; |
34 | #define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128") | 35 | bool msimode; |
35 | #define TYPE_RISCV_CPU_RV64I RISCV_CPU_TYPE_NAME("rv64i") | 36 | bool mmode; |
36 | +#define TYPE_RISCV_CPU_RVA22U64 RISCV_CPU_TYPE_NAME("rva22u64") | 37 | + |
37 | #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex") | 38 | + /* To support KVM aia=aplic-imsic with irqchip split mode */ |
38 | #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c") | 39 | + bool kvm_splitmode; |
39 | #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31") | 40 | + uint32_t kvm_msicfgaddr; |
40 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 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 | ||
41 | index XXXXXXX..XXXXXXX 100644 | 52 | index XXXXXXX..XXXXXXX 100644 |
42 | --- a/target/riscv/cpu.c | 53 | --- a/hw/intc/riscv_aplic.c |
43 | +++ b/target/riscv/cpu.c | 54 | +++ b/hw/intc/riscv_aplic.c |
44 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | 55 | @@ -XXX,XX +XXX,XX @@ bool riscv_use_emulated_aplic(bool msimode) |
45 | DEFINE_PROP_END_OF_LIST(), | 56 | #endif |
46 | }; | 57 | } |
47 | 58 | ||
48 | +#if defined(TARGET_RISCV64) | 59 | +void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr) |
49 | +static void rva22u64_profile_cpu_init(Object *obj) | ||
50 | +{ | 60 | +{ |
51 | + rv64i_bare_cpu_init(obj); | 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 | +} | ||
52 | + | 68 | + |
53 | + RVA22U64.enabled = true; | 69 | static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic, |
54 | +} | 70 | uint32_t irq) |
55 | +#endif | 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; | ||
56 | + | 83 | + |
57 | static const gchar *riscv_gdb_arch_name(CPUState *cs) | 84 | + if (!aplic->kvm_splitmode) { |
58 | { | 85 | + while (aplic_m && !aplic_m->mmode) { |
59 | RISCVCPU *cpu = RISCV_CPU(cs); | 86 | + aplic_m = aplic_m->parent; |
60 | @@ -XXX,XX +XXX,XX @@ char *riscv_isa_string(RISCVCPU *cpu) | 87 | + } |
61 | .instance_init = initfn \ | 88 | + if (!aplic_m) { |
89 | + qemu_log_mask(LOG_GUEST_ERROR, "%s: m-level APLIC not found\n", | ||
90 | + __func__); | ||
91 | + return; | ||
92 | + } | ||
62 | } | 93 | } |
63 | 94 | ||
64 | +#define DEFINE_PROFILE_CPU(type_name, initfn) \ | 95 | if (aplic->mmode) { |
65 | + { \ | 96 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic, |
66 | + .name = type_name, \ | 97 | addr |= (uint64_t)(guest_idx & APLIC_xMSICFGADDR_PPN_HART(lhxs)); |
67 | + .parent = TYPE_RISCV_BARE_CPU, \ | 98 | addr <<= APLIC_xMSICFGADDR_PPN_SHIFT; |
68 | + .instance_init = initfn \ | 99 | |
100 | + if (aplic->kvm_splitmode) { | ||
101 | + addr |= aplic->kvm_msicfgaddr; | ||
102 | + addr |= ((uint64_t)aplic->kvm_msicfgaddrH << 32); | ||
69 | + } | 103 | + } |
70 | + | 104 | + |
71 | static const TypeInfo riscv_cpu_type_infos[] = { | 105 | address_space_stl_le(&address_space_memory, addr, |
72 | { | 106 | eiid, MEMTXATTRS_UNSPECIFIED, &result); |
73 | .name = TYPE_RISCV_CPU, | 107 | if (result != MEMTX_OK) { |
74 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { | 108 | @@ -XXX,XX +XXX,XX @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) |
75 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init), | 109 | memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, |
76 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init), | 110 | aplic, TYPE_RISCV_APLIC, aplic->aperture_size); |
77 | DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init), | 111 | sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio); |
78 | + DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_profile_cpu_init), | ||
79 | #endif | ||
80 | }; | ||
81 | |||
82 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
83 | index XXXXXXX..XXXXXXX 100644 | ||
84 | --- a/target/riscv/tcg/tcg-cpu.c | ||
85 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
86 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_profiles(Object *cpu_obj) | ||
87 | object_property_add(cpu_obj, profile->name, "bool", | ||
88 | cpu_get_profile, cpu_set_profile, | ||
89 | NULL, (void *)profile); | ||
90 | + | 112 | + |
91 | + /* | 113 | + if (kvm_enabled()) { |
92 | + * CPUs might enable a profile right from the start. | 114 | + aplic->kvm_splitmode = true; |
93 | + * Enable its mandatory extensions right away in this | ||
94 | + * case. | ||
95 | + */ | ||
96 | + if (profile->enabled) { | ||
97 | + object_property_set_bool(cpu_obj, profile->name, true, NULL); | ||
98 | + } | 115 | + } |
99 | } | 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; | ||
100 | } | 161 | } |
101 | 162 | ||
102 | -- | 163 | -- |
103 | 2.43.0 | 164 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | KVM does not have the means to support enabling the rva22u64 profile. | 3 | Remove the 'irqchip_split()' restriction in kvm_arch_init() now that |
4 | The main reasons are: | 4 | we have support for "-accel kvm,kernel-irqchip=split". |
5 | |||
6 | - we're missing support for some mandatory rva22u64 extensions in the | ||
7 | KVM module; | ||
8 | |||
9 | - we can't make promises about enabling a profile since it all depends | ||
10 | on host support in the end. | ||
11 | |||
12 | We'll revisit this decision in the future if needed. For now mark the | ||
13 | 'rva22u64' profile as unavailable when running a KVM CPU: | ||
14 | |||
15 | $ qemu-system-riscv64 -machine virt,accel=kvm -cpu rv64,rva22u64=true | ||
16 | qemu-system-riscv64: can't apply global rv64-riscv-cpu.rva22u64=true: | ||
17 | 'rva22u64' is not available with KVM | ||
18 | 5 | ||
19 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 6 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
20 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
21 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 8 | Message-ID: <20241119191706.718860-8-dbarboza@ventanamicro.com> |
22 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
23 | Message-ID: <20231218125334.37184-10-dbarboza@ventanamicro.com> | ||
24 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
25 | --- | 10 | --- |
26 | target/riscv/kvm/kvm-cpu.c | 7 ++++++- | 11 | target/riscv/kvm/kvm-cpu.c | 5 ----- |
27 | 1 file changed, 6 insertions(+), 1 deletion(-) | 12 | 1 file changed, 5 deletions(-) |
28 | 13 | ||
29 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | 14 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c |
30 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
31 | --- a/target/riscv/kvm/kvm-cpu.c | 16 | --- a/target/riscv/kvm/kvm-cpu.c |
32 | +++ b/target/riscv/kvm/kvm-cpu.c | 17 | +++ b/target/riscv/kvm/kvm-cpu.c |
33 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_cfg_unavailable(Object *obj, Visitor *v, | 18 | @@ -XXX,XX +XXX,XX @@ int kvm_arch_init(MachineState *ms, KVMState *s) |
34 | } | 19 | |
35 | 20 | int kvm_arch_irqchip_create(KVMState *s) | |
36 | if (value) { | 21 | { |
37 | - error_setg(errp, "extension %s is not available with KVM", | 22 | - if (kvm_kernel_irqchip_split()) { |
38 | + error_setg(errp, "'%s' is not available with KVM", | 23 | - error_report("-machine kernel_irqchip=split is not supported on RISC-V."); |
39 | propname); | 24 | - exit(1); |
40 | } | 25 | - } |
41 | } | 26 | - |
42 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj) | 27 | /* |
43 | riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_extensions); | 28 | * We can create the VAIA using the newer device control API. |
44 | riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_vendor_exts); | 29 | */ |
45 | riscv_cpu_add_kvm_unavail_prop_array(cpu_obj, riscv_cpu_experimental_exts); | ||
46 | + | ||
47 | + /* We don't have the needed KVM support for profiles */ | ||
48 | + for (i = 0; riscv_profiles[i] != NULL; i++) { | ||
49 | + riscv_cpu_add_kvm_unavail_prop(cpu_obj, riscv_profiles[i]->name); | ||
50 | + } | ||
51 | } | ||
52 | |||
53 | static int kvm_riscv_get_regs_core(CPUState *cs) | ||
54 | -- | 30 | -- |
55 | 2.43.0 | 31 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | KVM vector support for RISC-V requires the linux-header ptrace.h. | 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. | ||
4 | 6 | ||
5 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 7 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
6 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
7 | Message-ID: <20231218204321.75757-3-dbarboza@ventanamicro.com> | 9 | Message-ID: <20241119191706.718860-9-dbarboza@ventanamicro.com> |
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
9 | --- | 11 | --- |
10 | linux-headers/asm-riscv/ptrace.h | 132 +++++++++++++++++++++++++++++++ | 12 | docs/specs/index.rst | 1 + |
11 | scripts/update-linux-headers.sh | 3 + | 13 | docs/specs/riscv-aia.rst | 83 ++++++++++++++++++++++++++++++++++++++ |
12 | 2 files changed, 135 insertions(+) | 14 | docs/system/riscv/virt.rst | 7 ++++ |
13 | create mode 100644 linux-headers/asm-riscv/ptrace.h | 15 | 3 files changed, 91 insertions(+) |
16 | create mode 100644 docs/specs/riscv-aia.rst | ||
14 | 17 | ||
15 | diff --git a/linux-headers/asm-riscv/ptrace.h b/linux-headers/asm-riscv/ptrace.h | 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 | ||
16 | new file mode 100644 | 28 | new file mode 100644 |
17 | index XXXXXXX..XXXXXXX | 29 | index XXXXXXX..XXXXXXX |
18 | --- /dev/null | 30 | --- /dev/null |
19 | +++ b/linux-headers/asm-riscv/ptrace.h | 31 | +++ b/docs/specs/riscv-aia.rst |
20 | @@ -XXX,XX +XXX,XX @@ | 32 | @@ -XXX,XX +XXX,XX @@ |
21 | +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ | 33 | +.. _riscv-aia: |
22 | +/* | ||
23 | + * Copyright (C) 2012 Regents of the University of California | ||
24 | + */ | ||
25 | + | 34 | + |
26 | +#ifndef _ASM_RISCV_PTRACE_H | 35 | +RISC-V AIA support for RISC-V machines |
27 | +#define _ASM_RISCV_PTRACE_H | 36 | +====================================== |
28 | + | 37 | + |
29 | +#ifndef __ASSEMBLY__ | 38 | +AIA (Advanced Interrupt Architecture) support is implemented in the ``virt`` |
39 | +RISC-V machine for TCG and KVM accelerators. | ||
30 | + | 40 | + |
31 | +#include <linux/types.h> | 41 | +The support consists of two main modes: |
32 | + | 42 | + |
33 | +#define PTRACE_GETFDPIC 33 | 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 | ||
34 | + | 47 | + |
35 | +#define PTRACE_GETFDPIC_EXEC 0 | 48 | +From an user standpoint, these modes will behave the same regardless of the accelerator |
36 | +#define PTRACE_GETFDPIC_INTERP 1 | 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. | ||
37 | + | 51 | + |
38 | +/* | 52 | +When running TCG, all controllers are emulated in userspace, including machine mode |
39 | + * User-mode register state for core dumps, ptrace, sigcontext | 53 | +(m-mode) APLIC and IMSIC (when applicable). |
40 | + * | ||
41 | + * This decouples struct pt_regs from the userspace ABI. | ||
42 | + * struct user_regs_struct must form a prefix of struct pt_regs. | ||
43 | + */ | ||
44 | +struct user_regs_struct { | ||
45 | + unsigned long pc; | ||
46 | + unsigned long ra; | ||
47 | + unsigned long sp; | ||
48 | + unsigned long gp; | ||
49 | + unsigned long tp; | ||
50 | + unsigned long t0; | ||
51 | + unsigned long t1; | ||
52 | + unsigned long t2; | ||
53 | + unsigned long s0; | ||
54 | + unsigned long s1; | ||
55 | + unsigned long a0; | ||
56 | + unsigned long a1; | ||
57 | + unsigned long a2; | ||
58 | + unsigned long a3; | ||
59 | + unsigned long a4; | ||
60 | + unsigned long a5; | ||
61 | + unsigned long a6; | ||
62 | + unsigned long a7; | ||
63 | + unsigned long s2; | ||
64 | + unsigned long s3; | ||
65 | + unsigned long s4; | ||
66 | + unsigned long s5; | ||
67 | + unsigned long s6; | ||
68 | + unsigned long s7; | ||
69 | + unsigned long s8; | ||
70 | + unsigned long s9; | ||
71 | + unsigned long s10; | ||
72 | + unsigned long s11; | ||
73 | + unsigned long t3; | ||
74 | + unsigned long t4; | ||
75 | + unsigned long t5; | ||
76 | + unsigned long t6; | ||
77 | +}; | ||
78 | + | 54 | + |
79 | +struct __riscv_f_ext_state { | 55 | +When running KVM: |
80 | + __u32 f[32]; | ||
81 | + __u32 fcsr; | ||
82 | +}; | ||
83 | + | 56 | + |
84 | +struct __riscv_d_ext_state { | 57 | +- no m-mode is provided, so there is no m-mode APLIC or IMSIC emulation regardless of |
85 | + __u64 f[32]; | 58 | + the AIA mode chosen |
86 | + __u32 fcsr; | 59 | +- with "aia=aplic", s-mode APLIC will be emulated by userspace |
87 | +}; | 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 | ||
88 | + | 65 | + |
89 | +struct __riscv_q_ext_state { | 66 | +The following table summarizes how the AIA and accelerator options defines what |
90 | + __u64 f[64] __attribute__((aligned(16))); | 67 | +we will emulate in userspace: |
91 | + __u32 fcsr; | ||
92 | + /* | ||
93 | + * Reserved for expansion of sigcontext structure. Currently zeroed | ||
94 | + * upon signal, and must be zero upon sigreturn. | ||
95 | + */ | ||
96 | + __u32 reserved[3]; | ||
97 | +}; | ||
98 | + | 68 | + |
99 | +struct __riscv_ctx_hdr { | ||
100 | + __u32 magic; | ||
101 | + __u32 size; | ||
102 | +}; | ||
103 | + | 69 | + |
104 | +struct __riscv_extra_ext_header { | 70 | +.. list-table:: How AIA and accel options changes controller emulation |
105 | + __u32 __padding[129] __attribute__((aligned(16))); | 71 | + :widths: 25 25 25 25 25 25 25 |
106 | + /* | 72 | + :header-rows: 1 |
107 | + * Reserved for expansion of sigcontext structure. Currently zeroed | ||
108 | + * upon signal, and must be zero upon sigreturn. | ||
109 | + */ | ||
110 | + __u32 reserved; | ||
111 | + struct __riscv_ctx_hdr hdr; | ||
112 | +}; | ||
113 | + | 73 | + |
114 | +union __riscv_fp_state { | 74 | + * - Accel |
115 | + struct __riscv_f_ext_state f; | 75 | + - Accel props |
116 | + struct __riscv_d_ext_state d; | 76 | + - AIA type |
117 | + struct __riscv_q_ext_state q; | 77 | + - APLIC m-mode |
118 | +}; | 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. | ||
119 | + | 130 | + |
120 | +struct __riscv_v_ext_state { | 131 | - aia-guests=nnn |
121 | + unsigned long vstart; | 132 | |
122 | + unsigned long vl; | 133 | The number of per-HART VS-level AIA IMSIC pages to be emulated for a guest |
123 | + unsigned long vtype; | ||
124 | + unsigned long vcsr; | ||
125 | + unsigned long vlenb; | ||
126 | + void *datap; | ||
127 | + /* | ||
128 | + * In signal handler, datap will be set a correct user stack offset | ||
129 | + * and vector registers will be copied to the address of datap | ||
130 | + * pointer. | ||
131 | + */ | ||
132 | +}; | ||
133 | + | ||
134 | +struct __riscv_v_regset_state { | ||
135 | + unsigned long vstart; | ||
136 | + unsigned long vl; | ||
137 | + unsigned long vtype; | ||
138 | + unsigned long vcsr; | ||
139 | + unsigned long vlenb; | ||
140 | + char vreg[]; | ||
141 | +}; | ||
142 | + | ||
143 | +/* | ||
144 | + * According to spec: The number of bits in a single vector register, | ||
145 | + * VLEN >= ELEN, which must be a power of 2, and must be no greater than | ||
146 | + * 2^16 = 65536bits = 8192bytes | ||
147 | + */ | ||
148 | +#define RISCV_MAX_VLENB (8192) | ||
149 | + | ||
150 | +#endif /* __ASSEMBLY__ */ | ||
151 | + | ||
152 | +#endif /* _ASM_RISCV_PTRACE_H */ | ||
153 | diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh | ||
154 | index XXXXXXX..XXXXXXX 100755 | ||
155 | --- a/scripts/update-linux-headers.sh | ||
156 | +++ b/scripts/update-linux-headers.sh | ||
157 | @@ -XXX,XX +XXX,XX @@ for arch in $ARCHLIST; do | ||
158 | cp_portable "$tmpdir/bootparam.h" \ | ||
159 | "$output/include/standard-headers/asm-$arch" | ||
160 | fi | ||
161 | + if [ $arch = riscv ]; then | ||
162 | + cp "$tmpdir/include/asm/ptrace.h" "$output/linux-headers/asm-riscv/" | ||
163 | + fi | ||
164 | done | ||
165 | |||
166 | rm -rf "$output/linux-headers/linux" | ||
167 | -- | 134 | -- |
168 | 2.43.0 | 135 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Sunil V L <sunilvl@ventanamicro.com> | 1 | From: Sai Pavan Boddu <sai.pavan.boddu@amd.com> |
---|---|---|---|
2 | 2 | ||
3 | RISC-V also needs to create the virtio in DSDT in the same way as ARM. | 3 | Add a basic board with interrupt controller (intc), timer, serial |
4 | So, instead of duplicating the code, move this function to the device | 4 | (uartlite), small memory called LMB@0 (128kB) and DDR@0x80000000 |
5 | specific file which is common across architectures. | 5 | (configured via command line eg. -m 2g). |
6 | 6 | This is basic configuration which matches HW generated out of AMD Vivado | |
7 | Suggested-by: Igor Mammedov <imammedo@redhat.com> | 7 | (design tools). But initial configuration is going beyond what it is |
8 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | 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> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 30 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 31 | Message-ID: <20241125134739.18189-1-sai.pavan.boddu@amd.com> |
11 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
12 | Message-ID: <20231218150247.466427-3-sunilvl@ventanamicro.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 32 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 33 | --- |
15 | include/hw/virtio/virtio-acpi.h | 16 ++++++++++++++++ | 34 | MAINTAINERS | 6 + |
16 | hw/arm/virt-acpi-build.c | 32 ++++---------------------------- | 35 | docs/system/riscv/microblaze-v-generic.rst | 42 +++++ |
17 | hw/virtio/virtio-acpi.c | 33 +++++++++++++++++++++++++++++++++ | 36 | docs/system/target-riscv.rst | 1 + |
18 | hw/virtio/meson.build | 1 + | 37 | hw/riscv/microblaze-v-generic.c | 184 +++++++++++++++++++++ |
19 | 4 files changed, 54 insertions(+), 28 deletions(-) | 38 | hw/riscv/Kconfig | 8 + |
20 | create mode 100644 include/hw/virtio/virtio-acpi.h | 39 | hw/riscv/meson.build | 1 + |
21 | create mode 100644 hw/virtio/virtio-acpi.c | 40 | 6 files changed, 242 insertions(+) |
22 | 41 | create mode 100644 docs/system/riscv/microblaze-v-generic.rst | |
23 | diff --git a/include/hw/virtio/virtio-acpi.h b/include/hw/virtio/virtio-acpi.h | 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 | ||
24 | new file mode 100644 | 62 | new file mode 100644 |
25 | index XXXXXXX..XXXXXXX | 63 | index XXXXXXX..XXXXXXX |
26 | --- /dev/null | 64 | --- /dev/null |
27 | +++ b/include/hw/virtio/virtio-acpi.h | 65 | +++ b/docs/system/riscv/microblaze-v-generic.rst |
28 | @@ -XXX,XX +XXX,XX @@ | 66 | @@ -XXX,XX +XXX,XX @@ |
29 | +/* SPDX-License-Identifier: GPL-2.0+ */ | 67 | +Microblaze-V generic board (``amd-microblaze-v-generic``) |
30 | +/* | 68 | +========================================================= |
31 | + * ACPI support for virtio | 69 | +The AMD MicroBlaze™ V processor is a soft-core RISC-V processor IP for AMD |
32 | + */ | 70 | +adaptive SoCs and FPGAs. The MicroBlaze™ V processor is based on the 32-bit (or |
33 | + | 71 | +64-bit) RISC-V instruction set architecture (ISA) and contains interfaces |
34 | +#ifndef VIRTIO_ACPI_H | 72 | +compatible with the classic MicroBlaze™ V processor (i.e it is a drop in |
35 | +#define VIRTIO_ACPI_H | 73 | +replacement for the classic MicroBlaze™ processor in existing RTL designs). |
36 | + | 74 | +More information can be found in below document. |
37 | +#include "qemu/osdep.h" | 75 | + |
38 | +#include "exec/hwaddr.h" | 76 | +https://docs.amd.com/r/en-US/ug1629-microblaze-v-user-guide/MicroBlaze-V-Architecture |
39 | + | 77 | + |
40 | +void virtio_acpi_dsdt_add(Aml *scope, const hwaddr virtio_mmio_base, | 78 | +The MicroBlaze™ V generic board in QEMU has following supported devices: |
41 | + const hwaddr virtio_mmio_size, uint32_t mmio_irq, | 79 | + |
42 | + long int start_index, int num); | 80 | + - timer |
43 | + | 81 | + - uartlite |
44 | +#endif | 82 | + - uart16550 |
45 | diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c | 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 | ||
46 | index XXXXXXX..XXXXXXX 100644 | 110 | index XXXXXXX..XXXXXXX 100644 |
47 | --- a/hw/arm/virt-acpi-build.c | 111 | --- a/docs/system/target-riscv.rst |
48 | +++ b/hw/arm/virt-acpi-build.c | 112 | +++ b/docs/system/target-riscv.rst |
49 | @@ -XXX,XX +XXX,XX @@ | 113 | @@ -XXX,XX +XXX,XX @@ undocumented; you can get a complete list by running |
50 | #include "migration/vmstate.h" | 114 | .. toctree:: |
51 | #include "hw/acpi/ghes.h" | 115 | :maxdepth: 1 |
52 | #include "hw/acpi/viot.h" | 116 | |
53 | +#include "hw/virtio/virtio-acpi.h" | 117 | + riscv/microblaze-v-generic |
54 | 118 | riscv/microchip-icicle-kit | |
55 | #define ARM_SPI_BASE 32 | 119 | riscv/shakti-c |
56 | 120 | riscv/sifive_u | |
57 | @@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap) | 121 | diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c |
58 | aml_append(scope, dev); | ||
59 | } | ||
60 | |||
61 | -static void acpi_dsdt_add_virtio(Aml *scope, | ||
62 | - const MemMapEntry *virtio_mmio_memmap, | ||
63 | - uint32_t mmio_irq, int num) | ||
64 | -{ | ||
65 | - hwaddr base = virtio_mmio_memmap->base; | ||
66 | - hwaddr size = virtio_mmio_memmap->size; | ||
67 | - int i; | ||
68 | - | ||
69 | - for (i = 0; i < num; i++) { | ||
70 | - uint32_t irq = mmio_irq + i; | ||
71 | - Aml *dev = aml_device("VR%02u", i); | ||
72 | - aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005"))); | ||
73 | - aml_append(dev, aml_name_decl("_UID", aml_int(i))); | ||
74 | - aml_append(dev, aml_name_decl("_CCA", aml_int(1))); | ||
75 | - | ||
76 | - Aml *crs = aml_resource_template(); | ||
77 | - aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE)); | ||
78 | - aml_append(crs, | ||
79 | - aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, | ||
80 | - AML_EXCLUSIVE, &irq, 1)); | ||
81 | - aml_append(dev, aml_name_decl("_CRS", crs)); | ||
82 | - aml_append(scope, dev); | ||
83 | - base += size; | ||
84 | - } | ||
85 | -} | ||
86 | - | ||
87 | static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, | ||
88 | uint32_t irq, VirtMachineState *vms) | ||
89 | { | ||
90 | @@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) | ||
91 | acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]); | ||
92 | } | ||
93 | fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]); | ||
94 | - acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO], | ||
95 | - (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS); | ||
96 | + virtio_acpi_dsdt_add(scope, memmap[VIRT_MMIO].base, memmap[VIRT_MMIO].size, | ||
97 | + (irqmap[VIRT_MMIO] + ARM_SPI_BASE), | ||
98 | + 0, NUM_VIRTIO_TRANSPORTS); | ||
99 | acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms); | ||
100 | if (vms->acpi_dev) { | ||
101 | build_ged_aml(scope, "\\_SB."GED_DEVICE, | ||
102 | diff --git a/hw/virtio/virtio-acpi.c b/hw/virtio/virtio-acpi.c | ||
103 | new file mode 100644 | 122 | new file mode 100644 |
104 | index XXXXXXX..XXXXXXX | 123 | index XXXXXXX..XXXXXXX |
105 | --- /dev/null | 124 | --- /dev/null |
106 | +++ b/hw/virtio/virtio-acpi.c | 125 | +++ b/hw/riscv/microblaze-v-generic.c |
107 | @@ -XXX,XX +XXX,XX @@ | 126 | @@ -XXX,XX +XXX,XX @@ |
108 | +// SPDX-License-Identifier: GPL-2.0+ | ||
109 | +/* | 127 | +/* |
110 | + * virtio ACPI Support | 128 | + * QEMU model of Microblaze V generic board. |
111 | + * | 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>. | ||
112 | + */ | 140 | + */ |
113 | + | 141 | + |
114 | +#include "hw/virtio/virtio-acpi.h" | 142 | +#include "qemu/osdep.h" |
115 | +#include "hw/acpi/aml-build.h" | 143 | +#include "qemu/units.h" |
116 | + | 144 | +#include "qapi/error.h" |
117 | +void virtio_acpi_dsdt_add(Aml *scope, const hwaddr base, const hwaddr size, | 145 | +#include "cpu.h" |
118 | + uint32_t mmio_irq, long int start_index, int num) | 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) | ||
119 | +{ | 181 | +{ |
120 | + hwaddr virtio_base = base; | 182 | + ram_addr_t ram_size = machine->ram_size; |
121 | + uint32_t irq = mmio_irq; | 183 | + DeviceState *dev, *dma, *eth0; |
122 | + long int i; | 184 | + Object *ds, *cs; |
123 | + | 185 | + int i; |
124 | + for (i = start_index; i < start_index + num; i++) { | 186 | + RISCVCPU *cpu; |
125 | + Aml *dev = aml_device("VR%02u", (unsigned)i); | 187 | + hwaddr ddr_base = MEMORY_BASEADDR; |
126 | + aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005"))); | 188 | + MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1); |
127 | + aml_append(dev, aml_name_decl("_UID", aml_int(i))); | 189 | + MemoryRegion *phys_ram = g_new(MemoryRegion, 1); |
128 | + aml_append(dev, aml_name_decl("_CCA", aml_int(1))); | 190 | + qemu_irq irq[32]; |
129 | + | 191 | + MemoryRegion *sysmem = get_system_memory(); |
130 | + Aml *crs = aml_resource_template(); | 192 | + |
131 | + aml_append(crs, aml_memory32_fixed(virtio_base, size, AML_READ_WRITE)); | 193 | + cpu = RISCV_CPU(object_new(machine->cpu_type)); |
132 | + aml_append(crs, | 194 | + object_property_set_bool(OBJECT(cpu), "h", false, NULL); |
133 | + aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, | 195 | + object_property_set_bool(OBJECT(cpu), "d", false, NULL); |
134 | + AML_EXCLUSIVE, &irq, 1)); | 196 | + qdev_realize(DEVICE(cpu), NULL, &error_abort); |
135 | + aml_append(dev, aml_name_decl("_CRS", crs)); | 197 | + /* Attach emulated BRAM through the LMB. */ |
136 | + aml_append(scope, dev); | 198 | + memory_region_init_ram(phys_lmb_bram, NULL, |
137 | + virtio_base += size; | 199 | + "mb_v.lmb_bram", LMB_BRAM_SIZE, |
138 | + irq++; | 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); | ||
139 | + } | 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); | ||
140 | +} | 298 | +} |
141 | diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build | 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 | ||
142 | index XXXXXXX..XXXXXXX 100644 | 312 | index XXXXXXX..XXXXXXX 100644 |
143 | --- a/hw/virtio/meson.build | 313 | --- a/hw/riscv/Kconfig |
144 | +++ b/hw/virtio/meson.build | 314 | +++ b/hw/riscv/Kconfig |
145 | @@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_VIRTIO', if_false: files('virtio-stub.c')) | 315 | @@ -XXX,XX +XXX,XX @@ config MICROCHIP_PFSOC |
146 | system_ss.add(files('virtio-hmp-cmds.c')) | 316 | select SIFIVE_PLIC |
147 | 317 | select UNIMP | |
148 | specific_ss.add_all(when: 'CONFIG_VIRTIO', if_true: specific_virtio_ss) | 318 | |
149 | +system_ss.add(when: 'CONFIG_ACPI', if_true: files('virtio-acpi.c')) | 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} | ||
150 | -- | 341 | -- |
151 | 2.43.0 | 342 | 2.47.1 |
343 | |||
344 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair23@gmail.com> | 1 | From: Sia Jee Heng <jeeheng.sia@starfivetech.com> |
---|---|---|---|
2 | 2 | ||
3 | Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor is | 3 | Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com> |
4 | enabled. We currently only set them on accesses to mideleg, but they | 4 | Reviewed-by: Sunil V L <sunilvl@ventanamicro.com> |
5 | aren't correctly set on reset. Let's ensure they are always the correct | 5 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
6 | value. | 6 | Message-ID: <20241028015744.624943-2-jeeheng.sia@starfivetech.com> |
7 | |||
8 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1617 | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
11 | Message-ID: <20240108001328.280222-4-alistair.francis@wdc.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 8 | --- |
14 | target/riscv/cpu.c | 8 ++++++++ | 9 | tests/qtest/bios-tables-test-allowed-diff.h | 1 + |
15 | 1 file changed, 8 insertions(+) | 10 | 1 file changed, 1 insertion(+) |
16 | 11 | ||
17 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 12 | diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h |
18 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/cpu.c | 14 | --- a/tests/qtest/bios-tables-test-allowed-diff.h |
20 | +++ b/target/riscv/cpu.c | 15 | +++ b/tests/qtest/bios-tables-test-allowed-diff.h |
21 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset_hold(Object *obj) | 16 | @@ -1 +1,2 @@ |
22 | /* mmte is supposed to have pm.current hardwired to 1 */ | 17 | /* List of comma-separated changed AML files to ignore */ |
23 | env->mmte |= (EXT_STATUS_INITIAL | MMTE_M_PM_CURRENT); | 18 | +"tests/data/acpi/riscv64/virt/SPCR", |
24 | |||
25 | + /* | ||
26 | + * Bits 10, 6, 2 and 12 of mideleg are read only 1 when the Hypervisor | ||
27 | + * extension is enabled. | ||
28 | + */ | ||
29 | + if (riscv_has_ext(env, RVH)) { | ||
30 | + env->mideleg |= HS_MODE_INTERRUPTS; | ||
31 | + } | ||
32 | + | ||
33 | /* | ||
34 | * Clear mseccfg and unlock all the PMP entries upon reset. | ||
35 | * This is allowed as per the priv and smepmp specifications | ||
36 | -- | 19 | -- |
37 | 2.43.0 | 20 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Sunil V L <sunilvl@ventanamicro.com> | 1 | From: Sia Jee Heng <jeeheng.sia@starfivetech.com> |
---|---|---|---|
2 | 2 | ||
3 | RISC-V also needs to use the same code to create fw_cfg in DSDT. So, | 3 | Update the SPCR table to accommodate the SPCR Table revision 4 [1]. |
4 | avoid code duplication by moving the code in arm and riscv to a device | 4 | The SPCR table has been modified to adhere to the revision 4 format [2]. |
5 | specific file. | ||
6 | 5 | ||
7 | Suggested-by: Igor Mammedov <imammedo@redhat.com> | 6 | [1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table |
8 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | 7 | [2]: https://github.com/acpica/acpica/pull/931 |
9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 8 | |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Sia Jee Heng <jeeheng.sia@starfivetech.com> |
11 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 10 | Reviewed-by: Sunil V L <sunilvl@ventanamicro.com> |
12 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | 11 | Reviewed-by: Michael S. Tsirkin <mst@redhat.com> |
13 | Message-ID: <20231218150247.466427-2-sunilvl@ventanamicro.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> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
15 | --- | 16 | --- |
16 | include/hw/nvram/fw_cfg_acpi.h | 15 +++++++++++++++ | 17 | include/hw/acpi/acpi-defs.h | 7 +++++-- |
17 | hw/arm/virt-acpi-build.c | 19 ++----------------- | 18 | include/hw/acpi/aml-build.h | 2 +- |
18 | hw/nvram/fw_cfg-acpi.c | 23 +++++++++++++++++++++++ | 19 | hw/acpi/aml-build.c | 20 ++++++++++++++++---- |
19 | hw/riscv/virt-acpi-build.c | 19 ++----------------- | 20 | hw/arm/virt-acpi-build.c | 8 ++++++-- |
20 | hw/nvram/meson.build | 1 + | 21 | hw/loongarch/acpi-build.c | 6 +++++- |
21 | 5 files changed, 43 insertions(+), 34 deletions(-) | 22 | hw/riscv/virt-acpi-build.c | 12 +++++++++--- |
22 | create mode 100644 include/hw/nvram/fw_cfg_acpi.h | 23 | 6 files changed, 42 insertions(+), 13 deletions(-) |
23 | create mode 100644 hw/nvram/fw_cfg-acpi.c | ||
24 | 24 | ||
25 | diff --git a/include/hw/nvram/fw_cfg_acpi.h b/include/hw/nvram/fw_cfg_acpi.h | 25 | diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h |
26 | new file mode 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
27 | index XXXXXXX..XXXXXXX | 27 | --- a/include/hw/acpi/acpi-defs.h |
28 | --- /dev/null | 28 | +++ b/include/hw/acpi/acpi-defs.h |
29 | +++ b/include/hw/nvram/fw_cfg_acpi.h | 29 | @@ -XXX,XX +XXX,XX @@ typedef struct AcpiSpcrData { |
30 | @@ -XXX,XX +XXX,XX @@ | 30 | uint8_t flow_control; |
31 | +/* SPDX-License-Identifier: GPL-2.0+ */ | 31 | uint8_t terminal_type; |
32 | +/* | 32 | uint8_t language; |
33 | + * ACPI support for fw_cfg | 33 | - uint8_t reserved1; |
34 | + * | 34 | uint16_t pci_device_id; /* Must be 0xffff if not PCI device */ |
35 | + */ | 35 | uint16_t pci_vendor_id; /* Must be 0xffff if not PCI device */ |
36 | + | 36 | uint8_t pci_bus; |
37 | +#ifndef FW_CFG_ACPI_H | 37 | @@ -XXX,XX +XXX,XX @@ typedef struct AcpiSpcrData { |
38 | +#define FW_CFG_ACPI_H | 38 | uint8_t pci_function; |
39 | + | 39 | uint32_t pci_flags; |
40 | +#include "qemu/osdep.h" | 40 | uint8_t pci_segment; |
41 | +#include "exec/hwaddr.h" | 41 | - uint32_t reserved2; |
42 | + | 42 | + uint32_t uart_clk_freq; |
43 | +void fw_cfg_acpi_dsdt_add(Aml *scope, const MemMapEntry *fw_cfg_memmap); | 43 | + uint32_t precise_baudrate; |
44 | + | 44 | + uint32_t namespace_string_length; |
45 | +#endif | 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 | /* | ||
46 | diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c | 99 | diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c |
47 | index XXXXXXX..XXXXXXX 100644 | 100 | index XXXXXXX..XXXXXXX 100644 |
48 | --- a/hw/arm/virt-acpi-build.c | 101 | --- a/hw/arm/virt-acpi-build.c |
49 | +++ b/hw/arm/virt-acpi-build.c | 102 | +++ b/hw/arm/virt-acpi-build.c |
50 | @@ -XXX,XX +XXX,XX @@ | 103 | @@ -XXX,XX +XXX,XX @@ spcr_setup(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) |
51 | #include "target/arm/cpu.h" | 104 | .pci_flags = 0, |
52 | #include "hw/acpi/acpi-defs.h" | 105 | .pci_segment = 0, |
53 | #include "hw/acpi/acpi.h" | 106 | }; |
54 | -#include "hw/nvram/fw_cfg.h" | 107 | - |
55 | +#include "hw/nvram/fw_cfg_acpi.h" | 108 | - build_spcr(table_data, linker, &serial, 2, vms->oem_id, vms->oem_table_id); |
56 | #include "hw/acpi/bios-linker-loader.h" | 109 | + /* |
57 | #include "hw/acpi/aml-build.h" | 110 | + * Passing NULL as the SPCR Table for Revision 2 doesn't support |
58 | #include "hw/acpi/utils.h" | 111 | + * NameSpaceString. |
59 | @@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, | 112 | + */ |
60 | aml_append(scope, dev); | 113 | + build_spcr(table_data, linker, &serial, 2, vms->oem_id, vms->oem_table_id, |
114 | + NULL); | ||
61 | } | 115 | } |
62 | 116 | ||
63 | -static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap) | 117 | /* |
64 | -{ | 118 | diff --git a/hw/loongarch/acpi-build.c b/hw/loongarch/acpi-build.c |
65 | - Aml *dev = aml_device("FWCF"); | 119 | index XXXXXXX..XXXXXXX 100644 |
66 | - aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002"))); | 120 | --- a/hw/loongarch/acpi-build.c |
67 | - /* device present, functioning, decoding, not shown in UI */ | 121 | +++ b/hw/loongarch/acpi-build.c |
68 | - aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); | 122 | @@ -XXX,XX +XXX,XX @@ spcr_setup(GArray *table_data, BIOSLinker *linker, MachineState *machine) |
69 | - aml_append(dev, aml_name_decl("_CCA", aml_int(1))); | 123 | }; |
70 | - | 124 | |
71 | - Aml *crs = aml_resource_template(); | 125 | lvms = LOONGARCH_VIRT_MACHINE(machine); |
72 | - aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base, | 126 | + /* |
73 | - fw_cfg_memmap->size, AML_READ_WRITE)); | 127 | + * Passing NULL as the SPCR Table for Revision 2 doesn't support |
74 | - aml_append(dev, aml_name_decl("_CRS", crs)); | 128 | + * NameSpaceString. |
75 | - aml_append(scope, dev); | 129 | + */ |
76 | -} | 130 | build_spcr(table_data, linker, &serial, 2, lvms->oem_id, |
77 | - | 131 | - lvms->oem_table_id); |
78 | static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap) | 132 | + lvms->oem_table_id, NULL); |
79 | { | 133 | } |
80 | Aml *dev, *crs; | 134 | |
81 | @@ -XXX,XX +XXX,XX @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) | 135 | typedef |
82 | if (vmc->acpi_expose_flash) { | ||
83 | acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]); | ||
84 | } | ||
85 | - acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]); | ||
86 | + fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]); | ||
87 | acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO], | ||
88 | (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS); | ||
89 | acpi_dsdt_add_pci(scope, memmap, irqmap[VIRT_PCIE] + ARM_SPI_BASE, vms); | ||
90 | diff --git a/hw/nvram/fw_cfg-acpi.c b/hw/nvram/fw_cfg-acpi.c | ||
91 | new file mode 100644 | ||
92 | index XXXXXXX..XXXXXXX | ||
93 | --- /dev/null | ||
94 | +++ b/hw/nvram/fw_cfg-acpi.c | ||
95 | @@ -XXX,XX +XXX,XX @@ | ||
96 | +// SPDX-License-Identifier: GPL-2.0+ | ||
97 | +/* | ||
98 | + * Add fw_cfg device in DSDT | ||
99 | + * | ||
100 | + */ | ||
101 | + | ||
102 | +#include "hw/nvram/fw_cfg_acpi.h" | ||
103 | +#include "hw/acpi/aml-build.h" | ||
104 | + | ||
105 | +void fw_cfg_acpi_dsdt_add(Aml *scope, const MemMapEntry *fw_cfg_memmap) | ||
106 | +{ | ||
107 | + Aml *dev = aml_device("FWCF"); | ||
108 | + aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002"))); | ||
109 | + /* device present, functioning, decoding, not shown in UI */ | ||
110 | + aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); | ||
111 | + aml_append(dev, aml_name_decl("_CCA", aml_int(1))); | ||
112 | + | ||
113 | + Aml *crs = aml_resource_template(); | ||
114 | + aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base, | ||
115 | + fw_cfg_memmap->size, AML_READ_WRITE)); | ||
116 | + aml_append(dev, aml_name_decl("_CRS", crs)); | ||
117 | + aml_append(scope, dev); | ||
118 | +} | ||
119 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | 136 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c |
120 | index XXXXXXX..XXXXXXX 100644 | 137 | index XXXXXXX..XXXXXXX 100644 |
121 | --- a/hw/riscv/virt-acpi-build.c | 138 | --- a/hw/riscv/virt-acpi-build.c |
122 | +++ b/hw/riscv/virt-acpi-build.c | 139 | +++ b/hw/riscv/virt-acpi-build.c |
123 | @@ -XXX,XX +XXX,XX @@ | 140 | @@ -XXX,XX +XXX,XX @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, |
124 | #include "hw/acpi/acpi.h" | 141 | |
125 | #include "hw/acpi/aml-build.h" | 142 | /* |
126 | #include "hw/acpi/utils.h" | 143 | * Serial Port Console Redirection Table (SPCR) |
127 | +#include "hw/nvram/fw_cfg_acpi.h" | 144 | - * Rev: 1.07 |
128 | #include "qapi/error.h" | 145 | + * Rev: 1.10 |
129 | #include "qemu/error-report.h" | 146 | */ |
130 | #include "sysemu/reset.h" | 147 | |
131 | @@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s) | 148 | static void |
132 | } | 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); | ||
133 | } | 171 | } |
134 | 172 | ||
135 | -static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap) | ||
136 | -{ | ||
137 | - Aml *dev = aml_device("FWCF"); | ||
138 | - aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002"))); | ||
139 | - | ||
140 | - /* device present, functioning, decoding, not shown in UI */ | ||
141 | - aml_append(dev, aml_name_decl("_STA", aml_int(0xB))); | ||
142 | - aml_append(dev, aml_name_decl("_CCA", aml_int(1))); | ||
143 | - | ||
144 | - Aml *crs = aml_resource_template(); | ||
145 | - aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base, | ||
146 | - fw_cfg_memmap->size, AML_READ_WRITE)); | ||
147 | - aml_append(dev, aml_name_decl("_CRS", crs)); | ||
148 | - aml_append(scope, dev); | ||
149 | -} | ||
150 | - | ||
151 | /* RHCT Node[N] starts at offset 56 */ | 173 | /* RHCT Node[N] starts at offset 56 */ |
152 | #define RHCT_NODE_ARRAY_OFFSET 56 | ||
153 | |||
154 | @@ -XXX,XX +XXX,XX @@ static void build_dsdt(GArray *table_data, | ||
155 | scope = aml_scope("\\_SB"); | ||
156 | acpi_dsdt_add_cpus(scope, s); | ||
157 | |||
158 | - acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]); | ||
159 | + fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]); | ||
160 | |||
161 | aml_append(dsdt, scope); | ||
162 | |||
163 | diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build | ||
164 | index XXXXXXX..XXXXXXX 100644 | ||
165 | --- a/hw/nvram/meson.build | ||
166 | +++ b/hw/nvram/meson.build | ||
167 | @@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_XLNX_EFUSE_ZYNQMP', if_true: files( | ||
168 | system_ss.add(when: 'CONFIG_XLNX_BBRAM', if_true: files('xlnx-bbram.c')) | ||
169 | |||
170 | specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c')) | ||
171 | +specific_ss.add(when: 'CONFIG_ACPI', if_true: files('fw_cfg-acpi.c')) | ||
172 | -- | 174 | -- |
173 | 2.43.0 | 175 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair23@gmail.com> | 1 | From: Sia Jee Heng <jeeheng.sia@starfivetech.com> |
---|---|---|---|
2 | 2 | ||
3 | We have been incorrectly adjusting both the interrupt and exception | 3 | Update the virt SPCR golden reference file for RISC-V to accommodate the |
4 | cause when using the hypervisor extension and trapping to VS-mode. This | 4 | SPCR Table revision 4 [1], utilizing the iasl binary compiled from the |
5 | patch changes the conditional to ensure we only adjust the cause for | 5 | latest ACPICA repository. The SPCR table has been modified to |
6 | interrupts and not exceptions. | 6 | adhere to the revision 4 format [2]. |
7 | 7 | ||
8 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/1708 | 8 | [1]: https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table |
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | [2]: https://github.com/acpica/acpica/pull/931 |
10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 10 | |
11 | Message-ID: <20240108001328.280222-3-alistair.francis@wdc.com> | 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> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 87 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 88 | --- |
14 | target/riscv/cpu_helper.c | 4 ++-- | 89 | tests/qtest/bios-tables-test-allowed-diff.h | 1 - |
15 | 1 file changed, 2 insertions(+), 2 deletions(-) | 90 | tests/data/acpi/riscv64/virt/SPCR | Bin 80 -> 90 bytes |
91 | 2 files changed, 1 deletion(-) | ||
16 | 92 | ||
17 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | 93 | diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h |
18 | index XXXXXXX..XXXXXXX 100644 | 94 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/cpu_helper.c | 95 | --- a/tests/qtest/bios-tables-test-allowed-diff.h |
20 | +++ b/target/riscv/cpu_helper.c | 96 | +++ b/tests/qtest/bios-tables-test-allowed-diff.h |
21 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_interrupt(CPUState *cs) | 97 | @@ -1,2 +1 @@ |
22 | * See if we need to adjust cause. Yes if its VS mode interrupt | 98 | /* List of comma-separated changed AML files to ignore */ |
23 | * no if hypervisor has delegated one of hs mode's interrupt | 99 | -"tests/data/acpi/riscv64/virt/SPCR", |
24 | */ | 100 | diff --git a/tests/data/acpi/riscv64/virt/SPCR b/tests/data/acpi/riscv64/virt/SPCR |
25 | - if (cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT || | 101 | index XXXXXXX..XXXXXXX 100644 |
26 | - cause == IRQ_VS_EXT) { | 102 | Binary files a/tests/data/acpi/riscv64/virt/SPCR and b/tests/data/acpi/riscv64/virt/SPCR differ |
27 | + if (async && (cause == IRQ_VS_TIMER || cause == IRQ_VS_SOFT || | ||
28 | + cause == IRQ_VS_EXT)) { | ||
29 | cause = cause - 1; | ||
30 | } | ||
31 | write_gva = false; | ||
32 | -- | 103 | -- |
33 | 2.43.0 | 104 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | Next patch will need to retrieve if a given RISCVCPU is 32 or 64 bit. | 3 | The HTIF interface is RISC-V specific, add |
4 | The existing helper riscv_is_32bit() (hw/riscv/boot.c) will always check | 4 | it within the MAINTAINERS section covering |
5 | the first CPU of a given hart array, not any given CPU. | 5 | hw/riscv/. |
6 | 6 | ||
7 | Create a helper to retrieve the info for any given CPU, not the first | 7 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
8 | CPU of the hart array. The helper is using the same 32 bit check that | ||
9 | riscv_cpu_satp_mode_finalize() was doing. | ||
10 | |||
11 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
12 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
13 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | ||
14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
15 | Message-ID: <20231218125334.37184-23-dbarboza@ventanamicro.com> | 9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
10 | Message-ID: <20241129154304.34946-2-philmd@linaro.org> | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
17 | --- | 12 | --- |
18 | target/riscv/cpu.h | 1 + | 13 | MAINTAINERS | 2 ++ |
19 | target/riscv/cpu.c | 7 ++++++- | 14 | 1 file changed, 2 insertions(+) |
20 | 2 files changed, 7 insertions(+), 1 deletion(-) | ||
21 | 15 | ||
22 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 16 | diff --git a/MAINTAINERS b/MAINTAINERS |
23 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/target/riscv/cpu.h | 18 | --- a/MAINTAINERS |
25 | +++ b/target/riscv/cpu.h | 19 | +++ b/MAINTAINERS |
26 | @@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPURISCVState *env, vaddr *pc, | 20 | @@ -XXX,XX +XXX,XX @@ S: Supported |
27 | uint64_t *cs_base, uint32_t *pflags); | 21 | F: configs/targets/riscv* |
28 | 22 | F: docs/system/target-riscv.rst | |
29 | void riscv_cpu_update_mask(CPURISCVState *env); | 23 | F: target/riscv/ |
30 | +bool riscv_cpu_is_32bit(RISCVCPU *cpu); | 24 | +F: hw/char/riscv_htif.c |
31 | 25 | F: hw/riscv/ | |
32 | RISCVException riscv_csrrw(CPURISCVState *env, int csrno, | 26 | F: hw/intc/riscv* |
33 | target_ulong *ret_value, | 27 | +F: include/hw/char/riscv_htif.h |
34 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 28 | F: include/hw/riscv/ |
35 | index XXXXXXX..XXXXXXX 100644 | 29 | F: linux-user/host/riscv32/ |
36 | --- a/target/riscv/cpu.c | 30 | F: linux-user/host/riscv64/ |
37 | +++ b/target/riscv/cpu.c | ||
38 | @@ -XXX,XX +XXX,XX @@ const uint32_t misa_bits[] = {RVI, RVE, RVM, RVA, RVF, RVD, RVV, | ||
39 | #define BYTE(x) (x) | ||
40 | #endif | ||
41 | |||
42 | +bool riscv_cpu_is_32bit(RISCVCPU *cpu) | ||
43 | +{ | ||
44 | + return riscv_cpu_mxl(&cpu->env) == MXL_RV32; | ||
45 | +} | ||
46 | + | ||
47 | #define ISA_EXT_DATA_ENTRY(_name, _min_ver, _prop) \ | ||
48 | {#_name, _min_ver, CPU_CFG_OFFSET(_prop)} | ||
49 | |||
50 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) | ||
51 | #ifndef CONFIG_USER_ONLY | ||
52 | static void riscv_cpu_satp_mode_finalize(RISCVCPU *cpu, Error **errp) | ||
53 | { | ||
54 | - bool rv32 = riscv_cpu_mxl(&cpu->env) == MXL_RV32; | ||
55 | + bool rv32 = riscv_cpu_is_32bit(cpu); | ||
56 | uint8_t satp_mode_map_max, satp_mode_supported_max; | ||
57 | |||
58 | /* The CPU wants the OS to decide which satp mode to use */ | ||
59 | -- | 31 | -- |
60 | 2.43.0 | 32 | 2.47.1 |
61 | 33 | ||
62 | 34 | diff view generated by jsdifflib |
1 | From: Rob Bradford <rbradford@rivosinc.com> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Rob Bradford <rbradford@rivosinc.com> | 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> | ||
4 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
5 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 14 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
6 | Message-ID: <20231207153842.32401-3-rbradford@rivosinc.com> | 15 | Message-ID: <20241129154304.34946-3-philmd@linaro.org> |
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
8 | --- | 17 | --- |
9 | disas/riscv.c | 9 +++++++++ | 18 | hw/char/riscv_htif.c | 11 ++++++----- |
10 | 1 file changed, 9 insertions(+) | 19 | 1 file changed, 6 insertions(+), 5 deletions(-) |
11 | 20 | ||
12 | diff --git a/disas/riscv.c b/disas/riscv.c | 21 | diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c |
13 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/disas/riscv.c | 23 | --- a/hw/char/riscv_htif.c |
15 | +++ b/disas/riscv.c | 24 | +++ b/hw/char/riscv_htif.c |
16 | @@ -XXX,XX +XXX,XX @@ typedef enum { | 25 | @@ -XXX,XX +XXX,XX @@ |
17 | rv_op_vwsll_vv = 872, | 26 | #include "qemu/timer.h" |
18 | rv_op_vwsll_vx = 873, | 27 | #include "qemu/error-report.h" |
19 | rv_op_vwsll_vi = 874, | 28 | #include "exec/address-spaces.h" |
20 | + rv_op_amocas_w = 875, | 29 | -#include "exec/tswap.h" |
21 | + rv_op_amocas_d = 876, | 30 | +#include "qemu/bswap.h" |
22 | + rv_op_amocas_q = 877, | 31 | #include "sysemu/dma.h" |
23 | } rv_op; | 32 | #include "sysemu/runstate.h" |
24 | 33 | ||
25 | /* register names */ | 34 | @@ -XXX,XX +XXX,XX @@ static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written) |
26 | @@ -XXX,XX +XXX,XX @@ const rv_opcode_data rvi_opcode_data[] = { | 35 | } else { |
27 | { "vwsll.vv", rv_codec_v_r, rv_fmt_vd_vs2_vs1_vm, NULL, 0, 0, 0 }, | 36 | uint64_t syscall[8]; |
28 | { "vwsll.vx", rv_codec_v_r, rv_fmt_vd_vs2_rs1_vm, NULL, 0, 0, 0 }, | 37 | cpu_physical_memory_read(payload, syscall, sizeof(syscall)); |
29 | { "vwsll.vi", rv_codec_v_i, rv_fmt_vd_vs2_uimm_vm, NULL, 0, 0, 0 }, | 38 | - if (tswap64(syscall[0]) == PK_SYS_WRITE && |
30 | + { "amocas.w", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 }, | 39 | - tswap64(syscall[1]) == HTIF_DEV_CONSOLE && |
31 | + { "amocas.d", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 }, | 40 | - tswap64(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) { |
32 | + { "amocas.q", rv_codec_r_a, rv_fmt_aqrl_rd_rs2_rs1, NULL, 0, 0, 0 }, | 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, | ||
33 | }; | 55 | }; |
34 | 56 | ||
35 | /* CSR names */ | 57 | HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr, |
36 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
37 | case 34: op = rv_op_amoxor_w; break; | ||
38 | case 35: op = rv_op_amoxor_d; break; | ||
39 | case 36: op = rv_op_amoxor_q; break; | ||
40 | + case 42: op = rv_op_amocas_w; break; | ||
41 | + case 43: op = rv_op_amocas_d; break; | ||
42 | + case 44: op = rv_op_amocas_q; break; | ||
43 | case 66: op = rv_op_amoor_w; break; | ||
44 | case 67: op = rv_op_amoor_d; break; | ||
45 | case 68: op = rv_op_amoor_q; break; | ||
46 | -- | 58 | -- |
47 | 2.43.0 | 59 | 2.47.1 |
60 | |||
61 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | Add a new profile CPU 'rva22s64' to work as an alias of | 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. | ||
4 | 7 | ||
5 | -cpu rv64i,rva22s64 | 8 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
6 | 9 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | |
7 | Like the existing rva22u64 CPU already does with the RVA22U64 profile. | 10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
8 | 11 | Message-ID: <20241129154304.34946-4-philmd@linaro.org> | |
9 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
10 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-ID: <20231218125334.37184-27-dbarboza@ventanamicro.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 13 | --- |
15 | target/riscv/cpu-qom.h | 1 + | 14 | hw/char/riscv_htif.c | 4 ++++ |
16 | target/riscv/cpu.c | 8 ++++++++ | 15 | 1 file changed, 4 insertions(+) |
17 | 2 files changed, 9 insertions(+) | ||
18 | 16 | ||
19 | diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h | 17 | diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c |
20 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/riscv/cpu-qom.h | 19 | --- a/hw/char/riscv_htif.c |
22 | +++ b/target/riscv/cpu-qom.h | 20 | +++ b/hw/char/riscv_htif.c |
23 | @@ -XXX,XX +XXX,XX @@ | 21 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps htif_mm_ops = { |
24 | #define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128") | 22 | .read = htif_mm_read, |
25 | #define TYPE_RISCV_CPU_RV64I RISCV_CPU_TYPE_NAME("rv64i") | 23 | .write = htif_mm_write, |
26 | #define TYPE_RISCV_CPU_RVA22U64 RISCV_CPU_TYPE_NAME("rva22u64") | 24 | .endianness = DEVICE_LITTLE_ENDIAN, |
27 | +#define TYPE_RISCV_CPU_RVA22S64 RISCV_CPU_TYPE_NAME("rva22s64") | 25 | + .impl = { |
28 | #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex") | 26 | + .min_access_size = 4, |
29 | #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c") | 27 | + .max_access_size = 4, |
30 | #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31") | 28 | + }, |
31 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/cpu.c | ||
34 | +++ b/target/riscv/cpu.c | ||
35 | @@ -XXX,XX +XXX,XX @@ static void rva22u64_profile_cpu_init(Object *obj) | ||
36 | |||
37 | RVA22U64.enabled = true; | ||
38 | } | ||
39 | + | ||
40 | +static void rva22s64_profile_cpu_init(Object *obj) | ||
41 | +{ | ||
42 | + rv64i_bare_cpu_init(obj); | ||
43 | + | ||
44 | + RVA22S64.enabled = true; | ||
45 | +} | ||
46 | #endif | ||
47 | |||
48 | static const gchar *riscv_gdb_arch_name(CPUState *cs) | ||
49 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { | ||
50 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init), | ||
51 | DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init), | ||
52 | DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22U64, rva22u64_profile_cpu_init), | ||
53 | + DEFINE_PROFILE_CPU(TYPE_RISCV_CPU_RVA22S64, rva22s64_profile_cpu_init), | ||
54 | #endif | ||
55 | }; | 29 | }; |
56 | 30 | ||
31 | HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr, | ||
57 | -- | 32 | -- |
58 | 2.43.0 | 33 | 2.47.1 |
34 | |||
35 | diff view generated by jsdifflib |
1 | From: Sunil V L <sunilvl@ventanamicro.com> | 1 | From: Jim Shu <jim.shu@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Some macros and static function related to IMSIC are defined in virt.c. | 3 | Larger initrd image will overlap the DTB at 3GB address. Since 64-bit |
4 | They are required in virt-acpi-build.c. So, make them public. | 4 | system doesn't have 32-bit addressable issue, we just load DTB to the end |
5 | of dram in 64-bit system. | ||
5 | 6 | ||
6 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | 7 | Signed-off-by: Jim Shu <jim.shu@sifive.com> |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Message-ID: <20241120153935.24706-2-jim.shu@sifive.com> |
9 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 11 | [ Changes by AF |
10 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | 12 | - Store fdt_load_addr_hi32 in the reset vector |
11 | Message-ID: <20231218150247.466427-5-sunilvl@ventanamicro.com> | 13 | ] |
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 15 | --- |
14 | include/hw/riscv/virt.h | 25 +++++++++++++++++++++++++ | 16 | include/hw/riscv/boot.h | 2 +- |
15 | hw/riscv/virt.c | 25 +------------------------ | 17 | hw/riscv/boot.c | 14 +++++++++----- |
16 | 2 files changed, 26 insertions(+), 24 deletions(-) | 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(-) | ||
17 | 23 | ||
18 | diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h | 24 | diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h |
19 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/include/hw/riscv/virt.h | 26 | --- a/include/hw/riscv/boot.h |
21 | +++ b/include/hw/riscv/virt.h | 27 | +++ b/include/hw/riscv/boot.h |
22 | @@ -XXX,XX +XXX,XX @@ | 28 | @@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(MachineState *machine, |
23 | #include "hw/riscv/riscv_hart.h" | 29 | bool load_initrd, |
24 | #include "hw/sysbus.h" | 30 | symbol_fn_t sym_cb); |
25 | #include "hw/block/flash.h" | 31 | uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size, |
26 | +#include "hw/intc/riscv_imsic.h" | 32 | - MachineState *ms); |
27 | 33 | + MachineState *ms, RISCVHartArrayState *harts); | |
28 | #define VIRT_CPUS_MAX_BITS 9 | 34 | void riscv_load_fdt(hwaddr fdt_addr, void *fdt); |
29 | #define VIRT_CPUS_MAX (1 << VIRT_CPUS_MAX_BITS) | 35 | void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, |
30 | @@ -XXX,XX +XXX,XX @@ enum { | 36 | hwaddr saddr, |
31 | 37 | diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c | |
32 | bool virt_is_acpi_enabled(RISCVVirtState *s); | 38 | index XXXXXXX..XXXXXXX 100644 |
33 | void virt_acpi_setup(RISCVVirtState *vms); | 39 | --- a/hw/riscv/boot.c |
34 | +uint32_t imsic_num_bits(uint32_t count); | 40 | +++ b/hw/riscv/boot.c |
35 | + | 41 | @@ -XXX,XX +XXX,XX @@ out: |
36 | +/* | 42 | * The FDT is fdt_packed() during the calculation. |
37 | + * The virt machine physical address space used by some of the devices | 43 | */ |
38 | + * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets, | 44 | uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size, |
39 | + * number of CPUs, and number of IMSIC guest files. | 45 | - MachineState *ms) |
40 | + * | 46 | + MachineState *ms, RISCVHartArrayState *harts) |
41 | + * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS, | 47 | { |
42 | + * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization | 48 | int ret = fdt_pack(ms->fdt); |
43 | + * of virt machine physical address space. | 49 | hwaddr dram_end, temp; |
44 | + */ | 50 | @@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size, |
45 | + | 51 | |
46 | +#define VIRT_IMSIC_GROUP_MAX_SIZE (1U << IMSIC_MMIO_GROUP_MIN_SHIFT) | 52 | /* |
47 | +#if VIRT_IMSIC_GROUP_MAX_SIZE < \ | 53 | * We should put fdt as far as possible to avoid kernel/initrd overwriting |
48 | + IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS) | 54 | - * its content. But it should be addressable by 32 bit system as well. |
49 | +#error "Can't accomodate single IMSIC group in address space" | 55 | - * Thus, put it at an 2MB aligned address that less than fdt size from the |
50 | +#endif | 56 | - * end of dram or 3GB whichever is lesser. |
51 | + | 57 | + * its content. But it should be addressable by 32 bit system as well in RV32. |
52 | +#define VIRT_IMSIC_MAX_SIZE (VIRT_SOCKETS_MAX * \ | 58 | + * Thus, put it near to the end of dram in RV64, and put it near to the end |
53 | + VIRT_IMSIC_GROUP_MAX_SIZE) | 59 | + * of dram or 3GB whichever is lesser in RV32. |
54 | +#if 0x4000000 < VIRT_IMSIC_MAX_SIZE | 60 | */ |
55 | +#error "Can't accomodate all IMSIC groups in address space" | 61 | - temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; |
56 | +#endif | 62 | + if (!riscv_is_32bit(harts)) { |
57 | + | 63 | + temp = dram_end; |
58 | #endif | 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 */ | ||
59 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 152 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
60 | index XXXXXXX..XXXXXXX 100644 | 153 | index XXXXXXX..XXXXXXX 100644 |
61 | --- a/hw/riscv/virt.c | 154 | --- a/hw/riscv/virt.c |
62 | +++ b/hw/riscv/virt.c | 155 | +++ b/hw/riscv/virt.c |
63 | @@ -XXX,XX +XXX,XX @@ | 156 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_done(Notifier *notifier, void *data) |
64 | #include "kvm/kvm_riscv.h" | 157 | |
65 | #include "hw/intc/riscv_aclint.h" | 158 | fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base, |
66 | #include "hw/intc/riscv_aplic.h" | 159 | memmap[VIRT_DRAM].size, |
67 | -#include "hw/intc/riscv_imsic.h" | 160 | - machine); |
68 | #include "hw/intc/sifive_plic.h" | 161 | + machine, &s->soc[0]); |
69 | #include "hw/misc/sifive_test.h" | 162 | riscv_load_fdt(fdt_load_addr, machine->fdt); |
70 | #include "hw/platform-bus.h" | 163 | |
71 | @@ -XXX,XX +XXX,XX @@ | 164 | /* load the reset vector */ |
72 | #include "hw/acpi/aml-build.h" | ||
73 | #include "qapi/qapi-visit-common.h" | ||
74 | |||
75 | -/* | ||
76 | - * The virt machine physical address space used by some of the devices | ||
77 | - * namely ACLINT, PLIC, APLIC, and IMSIC depend on number of Sockets, | ||
78 | - * number of CPUs, and number of IMSIC guest files. | ||
79 | - * | ||
80 | - * Various limits defined by VIRT_SOCKETS_MAX_BITS, VIRT_CPUS_MAX_BITS, | ||
81 | - * and VIRT_IRQCHIP_MAX_GUESTS_BITS are tuned for maximum utilization | ||
82 | - * of virt machine physical address space. | ||
83 | - */ | ||
84 | - | ||
85 | -#define VIRT_IMSIC_GROUP_MAX_SIZE (1U << IMSIC_MMIO_GROUP_MIN_SHIFT) | ||
86 | -#if VIRT_IMSIC_GROUP_MAX_SIZE < \ | ||
87 | - IMSIC_GROUP_SIZE(VIRT_CPUS_MAX_BITS, VIRT_IRQCHIP_MAX_GUESTS_BITS) | ||
88 | -#error "Can't accommodate single IMSIC group in address space" | ||
89 | -#endif | ||
90 | - | ||
91 | -#define VIRT_IMSIC_MAX_SIZE (VIRT_SOCKETS_MAX * \ | ||
92 | - VIRT_IMSIC_GROUP_MAX_SIZE) | ||
93 | -#if 0x4000000 < VIRT_IMSIC_MAX_SIZE | ||
94 | -#error "Can't accommodate all IMSIC groups in address space" | ||
95 | -#endif | ||
96 | - | ||
97 | /* KVM AIA only supports APLIC MSI. APLIC Wired is always emulated by QEMU. */ | ||
98 | static bool virt_use_kvm_aia(RISCVVirtState *s) | ||
99 | { | ||
100 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s, | ||
101 | g_free(plic_cells); | ||
102 | } | ||
103 | |||
104 | -static uint32_t imsic_num_bits(uint32_t count) | ||
105 | +uint32_t imsic_num_bits(uint32_t count) | ||
106 | { | ||
107 | uint32_t ret = 0; | ||
108 | |||
109 | -- | 165 | -- |
110 | 2.43.0 | 166 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Jim Shu <jim.shu@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Named features (zic64b the sole example at this moment) aren't expose to | 3 | Add a new struct RISCVBootInfo to sync boot information between multiple |
4 | users, thus we need another way to expose them. | 4 | boot functions. |
5 | 5 | ||
6 | Go through each named feature, get its boolean value, do the needed | 6 | Signed-off-by: Jim Shu <jim.shu@sifive.com> |
7 | conversions (bool to qbool, qbool to QObject) and add it to output dict. | ||
8 | |||
9 | Another adjustment is needed: named features are evaluated during | ||
10 | finalize(), so riscv_cpu_finalize_features() needs to be mandatory | ||
11 | regardless of whether we have an input dict or not. Otherwise zic64b | ||
12 | will always return 'false', which is incorrect: the default values of | ||
13 | cache blocksizes ([cbom/cbop/cboz]_blocksize) are set to 64, satisfying | ||
14 | the conditions for zic64b. | ||
15 | |||
16 | Here's an API usage example after this patch: | ||
17 | |||
18 | $ ./build/qemu-system-riscv64 -S -M virt -display none | ||
19 | -qmp tcp:localhost:1234,server,wait=off | ||
20 | |||
21 | $ ./scripts/qmp/qmp-shell localhost:1234 | ||
22 | Welcome to the QMP low-level shell! | ||
23 | Connected to QEMU 8.1.50 | ||
24 | |||
25 | (QEMU) query-cpu-model-expansion type=full model={"name":"rv64"} | ||
26 | {"return": {"model": | ||
27 | {"name": "rv64", "props": {... "zic64b": true, ...}}}} | ||
28 | |||
29 | zic64b is set to 'true', as expected, since all cache sizes are 64 | ||
30 | bytes by default. | ||
31 | |||
32 | If we change one of the cache blocksizes, zic64b is returned as 'false': | ||
33 | |||
34 | (QEMU) query-cpu-model-expansion type=full model={"name":"rv64","props":{"cbom_blocksize":128}} | ||
35 | {"return": {"model": | ||
36 | {"name": "rv64", "props": {... "zic64b": false, ...}}}} | ||
37 | |||
38 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
39 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
40 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
41 | Message-ID: <20231218125334.37184-8-dbarboza@ventanamicro.com> | 8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
9 | Message-ID: <20241120153935.24706-3-jim.shu@sifive.com> | ||
42 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
43 | --- | 11 | --- |
44 | target/riscv/riscv-qmp-cmds.c | 30 +++++++++++++++++++++++++----- | 12 | include/hw/riscv/boot.h | 25 ++++++++++----- |
45 | 1 file changed, 25 insertions(+), 5 deletions(-) | 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(-) | ||
46 | 21 | ||
47 | diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c | 22 | diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h |
48 | index XXXXXXX..XXXXXXX 100644 | 23 | index XXXXXXX..XXXXXXX 100644 |
49 | --- a/target/riscv/riscv-qmp-cmds.c | 24 | --- a/include/hw/riscv/boot.h |
50 | +++ b/target/riscv/riscv-qmp-cmds.c | 25 | +++ b/include/hw/riscv/boot.h |
51 | @@ -XXX,XX +XXX,XX @@ | 26 | @@ -XXX,XX +XXX,XX @@ |
52 | 27 | #define RISCV32_BIOS_BIN "opensbi-riscv32-generic-fw_dynamic.bin" | |
53 | #include "qapi/error.h" | 28 | #define RISCV64_BIOS_BIN "opensbi-riscv64-generic-fw_dynamic.bin" |
54 | #include "qapi/qapi-commands-machine-target.h" | 29 | |
55 | +#include "qapi/qmp/qbool.h" | 30 | +typedef struct RISCVBootInfo { |
56 | #include "qapi/qmp/qdict.h" | 31 | + ssize_t kernel_size; |
57 | #include "qapi/qmp/qerror.h" | 32 | + hwaddr image_low_addr; |
58 | #include "qapi/qobject-input-visitor.h" | 33 | + hwaddr image_high_addr; |
59 | @@ -XXX,XX +XXX,XX @@ static void riscv_obj_add_multiext_props(Object *obj, QDict *qdict_out, | 34 | + |
60 | } | 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); | ||
61 | } | 75 | } |
62 | 76 | ||
63 | +static void riscv_obj_add_named_feats_qdict(Object *obj, QDict *qdict_out) | 77 | -target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState *harts, |
78 | +void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts) | ||
64 | +{ | 79 | +{ |
65 | + const RISCVCPUMultiExtConfig *named_cfg; | 80 | + info->kernel_size = 0; |
66 | + RISCVCPU *cpu = RISCV_CPU(obj); | 81 | + info->is_32bit = riscv_is_32bit(harts); |
67 | + QObject *value; | ||
68 | + bool flag_val; | ||
69 | + | ||
70 | + for (int i = 0; riscv_cpu_named_features[i].name != NULL; i++) { | ||
71 | + named_cfg = &riscv_cpu_named_features[i]; | ||
72 | + flag_val = isa_ext_is_enabled(cpu, named_cfg->offset); | ||
73 | + value = QOBJECT(qbool_from_bool(flag_val)); | ||
74 | + | ||
75 | + qdict_put_obj(qdict_out, named_cfg->name, value); | ||
76 | + } | ||
77 | +} | 82 | +} |
78 | + | 83 | + |
79 | static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props, | 84 | +target_ulong riscv_calc_kernel_start_addr(RISCVBootInfo *info, |
80 | const QDict *qdict_in, | 85 | target_ulong firmware_end_addr) { |
81 | Error **errp) | 86 | - if (riscv_is_32bit(harts)) { |
82 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props, | 87 | + if (info->is_32bit) { |
83 | goto err; | 88 | return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB); |
84 | } | 89 | } else { |
85 | 90 | return QEMU_ALIGN_UP(firmware_end_addr, 2 * MiB); | |
86 | - riscv_cpu_finalize_features(RISCV_CPU(obj), &local_err); | 91 | @@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_firmware(const char *firmware_filename, |
87 | - if (local_err) { | 92 | exit(1); |
88 | - goto err; | 93 | } |
89 | - } | 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 | } | ||
90 | - | 191 | - |
91 | visit_end_struct(visitor, NULL); | 192 | - return kernel_entry; |
92 | 193 | } | |
93 | err: | 194 | |
94 | @@ -XXX,XX +XXX,XX @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, | 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) | ||
95 | } | 388 | } |
96 | } | 389 | } |
97 | 390 | ||
98 | + riscv_cpu_finalize_features(RISCV_CPU(obj), &local_err); | 391 | + riscv_boot_info_init(&boot_info, &s->soc[0]); |
99 | + if (local_err) { | ||
100 | + error_propagate(errp, local_err); | ||
101 | + object_unref(obj); | ||
102 | + return NULL; | ||
103 | + } | ||
104 | + | 392 | + |
105 | expansion_info = g_new0(CpuModelExpansionInfo, 1); | 393 | if (machine->kernel_filename && !kernel_entry) { |
106 | expansion_info->model = g_malloc0(sizeof(*expansion_info->model)); | 394 | - kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0], |
107 | expansion_info->model->name = g_strdup(model->name); | 395 | + kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info, |
108 | @@ -XXX,XX +XXX,XX @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, | 396 | firmware_end_addr); |
109 | riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_extensions); | 397 | - |
110 | riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_experimental_exts); | 398 | - kernel_entry = riscv_load_kernel(machine, &s->soc[0], |
111 | riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_vendor_exts); | 399 | - kernel_start_addr, true, NULL); |
112 | + riscv_obj_add_named_feats_qdict(obj, qdict_out); | 400 | + riscv_load_kernel(machine, &boot_info, kernel_start_addr, |
113 | 401 | + true, NULL); | |
114 | /* Add our CPU boolean options too */ | 402 | + kernel_entry = boot_info.image_low_addr; |
115 | riscv_obj_add_qdict_prop(obj, qdict_out, "mmu"); | 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 */ | ||
116 | -- | 412 | -- |
117 | 2.43.0 | 413 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Sunil V L <sunilvl@ventanamicro.com> | 1 | From: Jim Shu <jim.shu@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Add IMSIC structure in MADT when IMSIC is configured. | 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. | ||
4 | 5 | ||
5 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | 6 | Signed-off-by: Jim Shu <jim.shu@sifive.com> |
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
7 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 9 | Message-ID: <20241120153935.24706-4-jim.shu@sifive.com> |
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
10 | Message-ID: <20231218150247.466427-7-sunilvl@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 11 | --- |
13 | hw/riscv/virt-acpi-build.c | 35 +++++++++++++++++++++++++++++++++++ | 12 | include/hw/riscv/boot.h | 3 +++ |
14 | 1 file changed, 35 insertions(+) | 13 | hw/riscv/boot.c | 25 ++++++++++++++++++++++++- |
14 | 2 files changed, 27 insertions(+), 1 deletion(-) | ||
15 | 15 | ||
16 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | 16 | diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h |
17 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/hw/riscv/virt-acpi-build.c | 18 | --- a/include/hw/riscv/boot.h |
19 | +++ b/hw/riscv/virt-acpi-build.c | 19 | +++ b/include/hw/riscv/boot.h |
20 | @@ -XXX,XX +XXX,XX @@ static void build_madt(GArray *table_data, | 20 | @@ -XXX,XX +XXX,XX @@ typedef struct RISCVBootInfo { |
21 | MachineClass *mc = MACHINE_GET_CLASS(s); | 21 | hwaddr image_low_addr; |
22 | MachineState *ms = MACHINE(s); | 22 | hwaddr image_high_addr; |
23 | const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms); | 23 | |
24 | + uint8_t group_index_bits = imsic_num_bits(riscv_socket_count(ms)); | 24 | + hwaddr initrd_start; |
25 | + uint8_t guest_index_bits = imsic_num_bits(s->aia_guests + 1); | 25 | + ssize_t initrd_size; |
26 | + uint16_t imsic_max_hart_per_socket = 0; | ||
27 | + uint8_t hart_index_bits; | ||
28 | + uint8_t socket; | ||
29 | + | 26 | + |
30 | + for (socket = 0; socket < riscv_socket_count(ms); socket++) { | 27 | bool is_32bit; |
31 | + if (imsic_max_hart_per_socket < s->soc[socket].num_harts) { | 28 | } RISCVBootInfo; |
32 | + imsic_max_hart_per_socket = s->soc[socket].num_harts; | 29 | |
33 | + } | 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; | ||
34 | + } | 73 | + } |
35 | + | 74 | + |
36 | + hart_index_bits = imsic_num_bits(imsic_max_hart_per_socket); | 75 | /* |
37 | 76 | * A dram_size == 0, usually from a MemMapEntry[].size element, | |
38 | AcpiTable table = { .sig = "APIC", .rev = 6, .oem_id = s->oem_id, | 77 | * means that the DRAM block goes all the way to ms->ram_size. |
39 | .oem_table_id = s->oem_table_id }; | 78 | @@ -XXX,XX +XXX,XX @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size, |
40 | @@ -XXX,XX +XXX,XX @@ static void build_madt(GArray *table_data, | 79 | temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; |
41 | riscv_acpi_madt_add_rintc(i, arch_ids, table_data, s); | ||
42 | } | 80 | } |
43 | 81 | ||
44 | + /* IMSIC */ | 82 | - return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); |
45 | + if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { | 83 | + dtb_start = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); |
46 | + /* IMSIC */ | 84 | + |
47 | + build_append_int_noprefix(table_data, 0x19, 1); /* Type */ | 85 | + if (dtb_start_limit && (dtb_start < dtb_start_limit)) { |
48 | + build_append_int_noprefix(table_data, 16, 1); /* Length */ | 86 | + error_report("No enough memory to place DTB after kernel/initrd"); |
49 | + build_append_int_noprefix(table_data, 1, 1); /* Version */ | 87 | + exit(1); |
50 | + build_append_int_noprefix(table_data, 0, 1); /* Reserved */ | ||
51 | + build_append_int_noprefix(table_data, 0, 4); /* Flags */ | ||
52 | + /* Number of supervisor mode Interrupt Identities */ | ||
53 | + build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_MSIS, 2); | ||
54 | + /* Number of guest mode Interrupt Identities */ | ||
55 | + build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_MSIS, 2); | ||
56 | + /* Guest Index Bits */ | ||
57 | + build_append_int_noprefix(table_data, guest_index_bits, 1); | ||
58 | + /* Hart Index Bits */ | ||
59 | + build_append_int_noprefix(table_data, hart_index_bits, 1); | ||
60 | + /* Group Index Bits */ | ||
61 | + build_append_int_noprefix(table_data, group_index_bits, 1); | ||
62 | + /* Group Index Shift */ | ||
63 | + build_append_int_noprefix(table_data, IMSIC_MMIO_GROUP_MIN_SHIFT, 1); | ||
64 | + } | 88 | + } |
65 | + | 89 | + |
66 | acpi_table_end(linker, &table); | 90 | + return dtb_start; |
67 | } | 91 | } |
68 | 92 | ||
93 | /* | ||
69 | -- | 94 | -- |
70 | 2.43.0 | 95 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: "Fea.Wang" <fea.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Add support for amocas.w/d/q instructions which are part of the ratified | 3 | Refer to the draft of svukte extension from: |
4 | Zacas extension: https://github.com/riscv/riscv-zacas | 4 | https://github.com/riscv/riscv-isa-manual/pull/1564 |
5 | 5 | ||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 6 | Svukte provides a means to make user-mode accesses to supervisor memory |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 7 | raise page faults in constant time, mitigating attacks that attempt to |
8 | Signed-off-by: Rob Bradford <rbradford@rivosinc.com> | 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> | ||
9 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 13 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
10 | Message-ID: <20231207153842.32401-2-rbradford@rivosinc.com> | 14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
15 | Message-ID: <20241203034932.25185-2-fea.wang@sifive.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 17 | --- |
13 | target/riscv/cpu_cfg.h | 1 + | 18 | target/riscv/cpu_cfg.h | 1 + |
14 | target/riscv/insn32.decode | 6 + | 19 | 1 file changed, 1 insertion(+) |
15 | target/riscv/cpu.c | 2 + | ||
16 | target/riscv/tcg/tcg-cpu.c | 5 + | ||
17 | target/riscv/translate.c | 1 + | ||
18 | target/riscv/insn_trans/trans_rvzacas.c.inc | 150 ++++++++++++++++++++ | ||
19 | 6 files changed, 165 insertions(+) | ||
20 | create mode 100644 target/riscv/insn_trans/trans_rvzacas.c.inc | ||
21 | 20 | ||
22 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | 21 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h |
23 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/target/riscv/cpu_cfg.h | 23 | --- a/target/riscv/cpu_cfg.h |
25 | +++ b/target/riscv/cpu_cfg.h | 24 | +++ b/target/riscv/cpu_cfg.h |
26 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | 25 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { |
27 | bool ext_svnapot; | 26 | bool ext_svnapot; |
28 | bool ext_svpbmt; | 27 | bool ext_svpbmt; |
28 | bool ext_svvptc; | ||
29 | + bool ext_svukte; | ||
29 | bool ext_zdinx; | 30 | bool ext_zdinx; |
30 | + bool ext_zacas; | 31 | bool ext_zaamo; |
31 | bool ext_zawrs; | 32 | bool ext_zacas; |
32 | bool ext_zfa; | ||
33 | bool ext_zfbfmin; | ||
34 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
35 | index XXXXXXX..XXXXXXX 100644 | ||
36 | --- a/target/riscv/insn32.decode | ||
37 | +++ b/target/riscv/insn32.decode | ||
38 | @@ -XXX,XX +XXX,XX @@ vgmul_vv 101000 1 ..... 10001 010 ..... 1110111 @r2_vm_1 | ||
39 | vsm4k_vi 100001 1 ..... ..... 010 ..... 1110111 @r_vm_1 | ||
40 | vsm4r_vv 101000 1 ..... 10000 010 ..... 1110111 @r2_vm_1 | ||
41 | vsm4r_vs 101001 1 ..... 10000 010 ..... 1110111 @r2_vm_1 | ||
42 | + | ||
43 | +# *** RV32 Zacas Standard Extension *** | ||
44 | +amocas_w 00101 . . ..... ..... 010 ..... 0101111 @atom_st | ||
45 | +amocas_d 00101 . . ..... ..... 011 ..... 0101111 @atom_st | ||
46 | +# *** RV64 Zacas Standard Extension *** | ||
47 | +amocas_q 00101 . . ..... ..... 100 ..... 0101111 @atom_st | ||
48 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
49 | index XXXXXXX..XXXXXXX 100644 | ||
50 | --- a/target/riscv/cpu.c | ||
51 | +++ b/target/riscv/cpu.c | ||
52 | @@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = { | ||
53 | ISA_EXT_DATA_ENTRY(zihintpause, PRIV_VERSION_1_10_0, ext_zihintpause), | ||
54 | ISA_EXT_DATA_ENTRY(zihpm, PRIV_VERSION_1_12_0, ext_zihpm), | ||
55 | ISA_EXT_DATA_ENTRY(zmmul, PRIV_VERSION_1_12_0, ext_zmmul), | ||
56 | + ISA_EXT_DATA_ENTRY(zacas, PRIV_VERSION_1_12_0, ext_zacas), | ||
57 | ISA_EXT_DATA_ENTRY(zawrs, PRIV_VERSION_1_12_0, ext_zawrs), | ||
58 | ISA_EXT_DATA_ENTRY(zfa, PRIV_VERSION_1_12_0, ext_zfa), | ||
59 | ISA_EXT_DATA_ENTRY(zfbfmin, PRIV_VERSION_1_12_0, ext_zfbfmin), | ||
60 | @@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = { | ||
61 | MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true), | ||
62 | MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true), | ||
63 | MULTI_EXT_CFG_BOOL("zihintpause", ext_zihintpause, true), | ||
64 | + MULTI_EXT_CFG_BOOL("zacas", ext_zacas, false), | ||
65 | MULTI_EXT_CFG_BOOL("zawrs", ext_zawrs, true), | ||
66 | MULTI_EXT_CFG_BOOL("zfa", ext_zfa, true), | ||
67 | MULTI_EXT_CFG_BOOL("zfh", ext_zfh, false), | ||
68 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
69 | index XXXXXXX..XXXXXXX 100644 | ||
70 | --- a/target/riscv/tcg/tcg-cpu.c | ||
71 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
72 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | + if ((cpu->cfg.ext_zacas) && !riscv_has_ext(env, RVA)) { | ||
77 | + error_setg(errp, "Zacas extension requires A extension"); | ||
78 | + return; | ||
79 | + } | ||
80 | + | ||
81 | if ((cpu->cfg.ext_zawrs) && !riscv_has_ext(env, RVA)) { | ||
82 | error_setg(errp, "Zawrs extension requires A extension"); | ||
83 | return; | ||
84 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
85 | index XXXXXXX..XXXXXXX 100644 | ||
86 | --- a/target/riscv/translate.c | ||
87 | +++ b/target/riscv/translate.c | ||
88 | @@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) | ||
89 | #include "insn_trans/trans_rvv.c.inc" | ||
90 | #include "insn_trans/trans_rvb.c.inc" | ||
91 | #include "insn_trans/trans_rvzicond.c.inc" | ||
92 | +#include "insn_trans/trans_rvzacas.c.inc" | ||
93 | #include "insn_trans/trans_rvzawrs.c.inc" | ||
94 | #include "insn_trans/trans_rvzicbo.c.inc" | ||
95 | #include "insn_trans/trans_rvzfa.c.inc" | ||
96 | diff --git a/target/riscv/insn_trans/trans_rvzacas.c.inc b/target/riscv/insn_trans/trans_rvzacas.c.inc | ||
97 | new file mode 100644 | ||
98 | index XXXXXXX..XXXXXXX | ||
99 | --- /dev/null | ||
100 | +++ b/target/riscv/insn_trans/trans_rvzacas.c.inc | ||
101 | @@ -XXX,XX +XXX,XX @@ | ||
102 | +/* | ||
103 | + * RISC-V translation routines for the RV64 Zacas Standard Extension. | ||
104 | + * | ||
105 | + * Copyright (c) 2020-2023 PLCT Lab | ||
106 | + * | ||
107 | + * This program is free software; you can redistribute it and/or modify it | ||
108 | + * under the terms and conditions of the GNU General Public License, | ||
109 | + * version 2 or later, as published by the Free Software Foundation. | ||
110 | + * | ||
111 | + * This program is distributed in the hope it will be useful, but WITHOUT | ||
112 | + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
113 | + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
114 | + * more details. | ||
115 | + * | ||
116 | + * You should have received a copy of the GNU General Public License along with | ||
117 | + * this program. If not, see <http://www.gnu.org/licenses/>. | ||
118 | + */ | ||
119 | + | ||
120 | +#define REQUIRE_ZACAS(ctx) do { \ | ||
121 | + if (!ctx->cfg_ptr->ext_zacas) { \ | ||
122 | + return false; \ | ||
123 | + } \ | ||
124 | +} while (0) | ||
125 | + | ||
126 | +static bool gen_cmpxchg(DisasContext *ctx, arg_atomic *a, MemOp mop) | ||
127 | +{ | ||
128 | + TCGv dest = get_gpr(ctx, a->rd, EXT_NONE); | ||
129 | + TCGv src1 = get_address(ctx, a->rs1, 0); | ||
130 | + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); | ||
131 | + | ||
132 | + decode_save_opc(ctx); | ||
133 | + tcg_gen_atomic_cmpxchg_tl(dest, src1, dest, src2, ctx->mem_idx, mop); | ||
134 | + | ||
135 | + gen_set_gpr(ctx, a->rd, dest); | ||
136 | + return true; | ||
137 | +} | ||
138 | + | ||
139 | +static bool trans_amocas_w(DisasContext *ctx, arg_amocas_w *a) | ||
140 | +{ | ||
141 | + REQUIRE_ZACAS(ctx); | ||
142 | + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TESL); | ||
143 | +} | ||
144 | + | ||
145 | +static TCGv_i64 get_gpr_pair(DisasContext *ctx, int reg_num) | ||
146 | +{ | ||
147 | + TCGv_i64 t; | ||
148 | + | ||
149 | + assert(get_ol(ctx) == MXL_RV32); | ||
150 | + | ||
151 | + if (reg_num == 0) { | ||
152 | + return tcg_constant_i64(0); | ||
153 | + } | ||
154 | + | ||
155 | + t = tcg_temp_new_i64(); | ||
156 | + tcg_gen_concat_tl_i64(t, cpu_gpr[reg_num], cpu_gpr[reg_num + 1]); | ||
157 | + return t; | ||
158 | +} | ||
159 | + | ||
160 | +static void gen_set_gpr_pair(DisasContext *ctx, int reg_num, TCGv_i64 t) | ||
161 | +{ | ||
162 | + assert(get_ol(ctx) == MXL_RV32); | ||
163 | + | ||
164 | + if (reg_num != 0) { | ||
165 | +#ifdef TARGET_RISCV32 | ||
166 | + tcg_gen_extr_i64_i32(cpu_gpr[reg_num], cpu_gpr[reg_num + 1], t); | ||
167 | +#else | ||
168 | + tcg_gen_ext32s_i64(cpu_gpr[reg_num], t); | ||
169 | + tcg_gen_sari_i64(cpu_gpr[reg_num + 1], t, 32); | ||
170 | +#endif | ||
171 | + | ||
172 | + if (get_xl_max(ctx) == MXL_RV128) { | ||
173 | + tcg_gen_sari_tl(cpu_gprh[reg_num], cpu_gpr[reg_num], 63); | ||
174 | + tcg_gen_sari_tl(cpu_gprh[reg_num + 1], cpu_gpr[reg_num + 1], 63); | ||
175 | + } | ||
176 | + } | ||
177 | +} | ||
178 | + | ||
179 | +static bool gen_cmpxchg64(DisasContext *ctx, arg_atomic *a, MemOp mop) | ||
180 | +{ | ||
181 | + /* | ||
182 | + * Encodings with odd numbered registers specified in rs2 and rd are | ||
183 | + * reserved. | ||
184 | + */ | ||
185 | + if ((a->rs2 | a->rd) & 1) { | ||
186 | + return false; | ||
187 | + } | ||
188 | + | ||
189 | + TCGv_i64 dest = get_gpr_pair(ctx, a->rd); | ||
190 | + TCGv src1 = get_address(ctx, a->rs1, 0); | ||
191 | + TCGv_i64 src2 = get_gpr_pair(ctx, a->rs2); | ||
192 | + | ||
193 | + decode_save_opc(ctx); | ||
194 | + tcg_gen_atomic_cmpxchg_i64(dest, src1, dest, src2, ctx->mem_idx, mop); | ||
195 | + | ||
196 | + gen_set_gpr_pair(ctx, a->rd, dest); | ||
197 | + return true; | ||
198 | +} | ||
199 | + | ||
200 | +static bool trans_amocas_d(DisasContext *ctx, arg_amocas_d *a) | ||
201 | +{ | ||
202 | + REQUIRE_ZACAS(ctx); | ||
203 | + switch (get_ol(ctx)) { | ||
204 | + case MXL_RV32: | ||
205 | + return gen_cmpxchg64(ctx, a, MO_ALIGN | MO_TEUQ); | ||
206 | + case MXL_RV64: | ||
207 | + case MXL_RV128: | ||
208 | + return gen_cmpxchg(ctx, a, MO_ALIGN | MO_TEUQ); | ||
209 | + default: | ||
210 | + g_assert_not_reached(); | ||
211 | + } | ||
212 | +} | ||
213 | + | ||
214 | +static bool trans_amocas_q(DisasContext *ctx, arg_amocas_q *a) | ||
215 | +{ | ||
216 | + REQUIRE_ZACAS(ctx); | ||
217 | + REQUIRE_64BIT(ctx); | ||
218 | + | ||
219 | + /* | ||
220 | + * Encodings with odd numbered registers specified in rs2 and rd are | ||
221 | + * reserved. | ||
222 | + */ | ||
223 | + if ((a->rs2 | a->rd) & 1) { | ||
224 | + return false; | ||
225 | + } | ||
226 | + | ||
227 | +#ifdef TARGET_RISCV64 | ||
228 | + TCGv_i128 dest = tcg_temp_new_i128(); | ||
229 | + TCGv src1 = get_address(ctx, a->rs1, 0); | ||
230 | + TCGv_i128 src2 = tcg_temp_new_i128(); | ||
231 | + TCGv_i64 src2l = get_gpr(ctx, a->rs2, EXT_NONE); | ||
232 | + TCGv_i64 src2h = get_gpr(ctx, a->rs2 == 0 ? 0 : a->rs2 + 1, EXT_NONE); | ||
233 | + TCGv_i64 destl = get_gpr(ctx, a->rd, EXT_NONE); | ||
234 | + TCGv_i64 desth = get_gpr(ctx, a->rd == 0 ? 0 : a->rd + 1, EXT_NONE); | ||
235 | + | ||
236 | + tcg_gen_concat_i64_i128(src2, src2l, src2h); | ||
237 | + tcg_gen_concat_i64_i128(dest, destl, desth); | ||
238 | + decode_save_opc(ctx); | ||
239 | + tcg_gen_atomic_cmpxchg_i128(dest, src1, dest, src2, ctx->mem_idx, | ||
240 | + (MO_ALIGN | MO_TEUO)); | ||
241 | + | ||
242 | + tcg_gen_extr_i128_i64(destl, desth, dest); | ||
243 | + | ||
244 | + if (a->rd != 0) { | ||
245 | + gen_set_gpr(ctx, a->rd, destl); | ||
246 | + gen_set_gpr(ctx, a->rd + 1, desth); | ||
247 | + } | ||
248 | +#endif | ||
249 | + | ||
250 | + return true; | ||
251 | +} | ||
252 | -- | 33 | -- |
253 | 2.43.0 | 34 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair23@gmail.com> | 1 | From: "Fea.Wang" <fea.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | The CSRs will always be between either CSR_MHPMCOUNTER3 and | 3 | Svukte extension add UKTE bit, bit[8] in senvcfg CSR. The bit will be |
4 | CSR_MHPMCOUNTER31 or CSR_MHPMCOUNTER3H and CSR_MHPMCOUNTER31H. | 4 | supported when the svukte extension is enabled. |
5 | 5 | ||
6 | So although ctr_index can't be negative, Coverity doesn't know this and | 6 | When senvcfg[UKTE] bit is set, the memory access from U-mode should do |
7 | it isn't obvious to human readers either. Let's add an assert to ensure | 7 | the svukte check only except HLV/HLVX/HSV H-mode instructions which |
8 | that Coverity knows the values will be within range. | 8 | depend on hstatus[HUKTE]. |
9 | 9 | ||
10 | To simplify the code let's also change the RV32 adjustment. | 10 | Signed-off-by: Fea.Wang <fea.wang@sifive.com> |
11 | 11 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | |
12 | Fixes: Coverity CID 1523910 | 12 | Reviewed-by: Jim Shu <jim.shu@sifive.com> |
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 13 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
15 | Message-ID: <20240108001328.280222-2-alistair.francis@wdc.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> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
17 | --- | 17 | --- |
18 | target/riscv/csr.c | 5 ++++- | 18 | target/riscv/cpu_bits.h | 1 + |
19 | 1 file changed, 4 insertions(+), 1 deletion(-) | 19 | target/riscv/csr.c | 4 ++++ |
20 | 2 files changed, 5 insertions(+) | ||
20 | 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 | ||
21 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 34 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
22 | index XXXXXXX..XXXXXXX 100644 | 35 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/riscv/csr.c | 36 | --- a/target/riscv/csr.c |
24 | +++ b/target/riscv/csr.c | 37 | +++ b/target/riscv/csr.c |
25 | @@ -XXX,XX +XXX,XX @@ static RISCVException mctr(CPURISCVState *env, int csrno) | 38 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_senvcfg(CPURISCVState *env, int csrno, |
26 | 39 | mask |= SENVCFG_SSE; | |
27 | if ((riscv_cpu_mxl(env) == MXL_RV32) && csrno >= CSR_MCYCLEH) { | ||
28 | /* Offset for RV32 mhpmcounternh counters */ | ||
29 | - base_csrno += 0x80; | ||
30 | + csrno -= 0x80; | ||
31 | } | 40 | } |
41 | |||
42 | + if (env_archcpu(env)->cfg.ext_svukte) { | ||
43 | + mask |= SENVCFG_UKTE; | ||
44 | + } | ||
32 | + | 45 | + |
33 | + g_assert(csrno >= CSR_MHPMCOUNTER3 && csrno <= CSR_MHPMCOUNTER31); | 46 | env->senvcfg = (env->senvcfg & ~mask) | (val & mask); |
34 | + | 47 | return RISCV_EXCP_NONE; |
35 | ctr_index = csrno - base_csrno; | 48 | } |
36 | if ((BIT(ctr_index) & pmu_avail_ctrs >> 3) == 0) { | ||
37 | /* The PMU is not enabled or counter is out of range */ | ||
38 | -- | 49 | -- |
39 | 2.43.0 | 50 | 2.47.1 | diff view generated by jsdifflib |
1 | From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 1 | From: "Fea.Wang" <fea.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | If CPU does not implement the Vector extension, it usually means | 3 | Svukte extension add HUKTE bit, bit[24] in hstatus CSR. The written |
4 | mstatus vs hardwire to zero. So we should not allow write a | 4 | value will be masked when the svukte extension is not enabled. |
5 | non-zero value to this field. | ||
6 | 5 | ||
7 | Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 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> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Message-ID: <20231215023313.1708-1-zhiwei_liu@linux.alibaba.com> | 14 | Message-ID: <20241203034932.25185-4-fea.wang@sifive.com> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 16 | --- |
12 | target/riscv/csr.c | 5 ++++- | 17 | target/riscv/cpu_bits.h | 1 + |
13 | 1 file changed, 4 insertions(+), 1 deletion(-) | 18 | target/riscv/csr.c | 3 +++ |
19 | 2 files changed, 4 insertions(+) | ||
14 | 20 | ||
21 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/target/riscv/cpu_bits.h | ||
24 | +++ b/target/riscv/cpu_bits.h | ||
25 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
26 | #define HSTATUS_VTVM 0x00100000 | ||
27 | #define HSTATUS_VTW 0x00200000 | ||
28 | #define HSTATUS_VTSR 0x00400000 | ||
29 | +#define HSTATUS_HUKTE 0x01000000 | ||
30 | #define HSTATUS_VSXL 0x300000000 | ||
31 | |||
32 | #define HSTATUS32_WPRI 0xFF8FF87E | ||
15 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 33 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
16 | index XXXXXXX..XXXXXXX 100644 | 34 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/csr.c | 35 | --- a/target/riscv/csr.c |
18 | +++ b/target/riscv/csr.c | 36 | +++ b/target/riscv/csr.c |
19 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mstatus(CPURISCVState *env, int csrno, | 37 | @@ -XXX,XX +XXX,XX @@ static RISCVException read_hstatus(CPURISCVState *env, int csrno, |
20 | mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE | | 38 | static RISCVException write_hstatus(CPURISCVState *env, int csrno, |
21 | MSTATUS_SPP | MSTATUS_MPRV | MSTATUS_SUM | | 39 | target_ulong val) |
22 | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | | 40 | { |
23 | - MSTATUS_TW | MSTATUS_VS; | 41 | + if (!env_archcpu(env)->cfg.ext_svukte) { |
24 | + MSTATUS_TW; | 42 | + val = val & (~HSTATUS_HUKTE); |
25 | |||
26 | if (riscv_has_ext(env, RVF)) { | ||
27 | mask |= MSTATUS_FS; | ||
28 | } | ||
29 | + if (riscv_has_ext(env, RVV)) { | ||
30 | + mask |= MSTATUS_VS; | ||
31 | + } | 43 | + } |
32 | 44 | env->hstatus = val; | |
33 | if (xl != MXL_RV32 || env->debugger) { | 45 | if (riscv_cpu_mxl(env) != MXL_RV32 && get_field(val, HSTATUS_VSXL) != 2) { |
34 | if (riscv_has_ext(env, RVH)) { | 46 | qemu_log_mask(LOG_UNIMP, |
35 | -- | 47 | -- |
36 | 2.43.0 | 48 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: "Fea.Wang" <fea.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | 'satp_mode' is a requirement for supervisor profiles like RVA22S64. | 3 | Follow the Svukte spec, do the memory access address checking |
4 | User-mode/application profiles like RVA22U64 doesn't care. | ||
5 | 4 | ||
6 | Add 'satp_mode' to the profile description. If a profile requires it, | 5 | 1. Include instruction fetches or explicit memory accesses |
7 | set it during cpu_set_profile(). We'll also check it during finalize() | 6 | 2. System run in effective privilege U or VU |
8 | to validate if the running config implements the profile. | 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. | ||
9 | 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> | ||
10 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 17 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
11 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 18 | Reviewed-by: Jim Shu <jim.shu@sifive.com> |
12 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 19 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
13 | Message-ID: <20231218125334.37184-24-dbarboza@ventanamicro.com> | 20 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
21 | Message-ID: <20241203034932.25185-5-fea.wang@sifive.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
15 | --- | 23 | --- |
16 | target/riscv/cpu.h | 1 + | 24 | target/riscv/cpu_helper.c | 55 +++++++++++++++++++++++++++++++++++++++ |
17 | target/riscv/cpu.c | 1 + | 25 | 1 file changed, 55 insertions(+) |
18 | target/riscv/tcg/tcg-cpu.c | 40 ++++++++++++++++++++++++++++++++++++++ | ||
19 | 3 files changed, 42 insertions(+) | ||
20 | 26 | ||
21 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 27 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c |
22 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/riscv/cpu.h | 29 | --- a/target/riscv/cpu_helper.c |
24 | +++ b/target/riscv/cpu.h | 30 | +++ b/target/riscv/cpu_helper.c |
25 | @@ -XXX,XX +XXX,XX @@ typedef struct riscv_cpu_profile { | 31 | @@ -XXX,XX +XXX,XX @@ static int get_physical_address_pmp(CPURISCVState *env, int *prot, hwaddr addr, |
26 | bool enabled; | 32 | return TRANSLATE_SUCCESS; |
27 | bool user_set; | ||
28 | int priv_spec; | ||
29 | + int satp_mode; | ||
30 | const int32_t ext_offsets[]; | ||
31 | } RISCVCPUProfile; | ||
32 | |||
33 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
34 | index XXXXXXX..XXXXXXX 100644 | ||
35 | --- a/target/riscv/cpu.c | ||
36 | +++ b/target/riscv/cpu.c | ||
37 | @@ -XXX,XX +XXX,XX @@ static RISCVCPUProfile RVA22U64 = { | ||
38 | .name = "rva22u64", | ||
39 | .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU, | ||
40 | .priv_spec = RISCV_PROFILE_ATTR_UNUSED, | ||
41 | + .satp_mode = RISCV_PROFILE_ATTR_UNUSED, | ||
42 | .ext_offsets = { | ||
43 | CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause), | ||
44 | CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb), | ||
45 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
46 | index XXXXXXX..XXXXXXX 100644 | ||
47 | --- a/target/riscv/tcg/tcg-cpu.c | ||
48 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
49 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
50 | riscv_cpu_disable_priv_spec_isa_exts(cpu); | ||
51 | } | 33 | } |
52 | 34 | ||
53 | +#ifndef CONFIG_USER_ONLY | 35 | +/* Returns 'true' if a svukte address check is needed */ |
54 | +static bool riscv_cpu_validate_profile_satp(RISCVCPU *cpu, | 36 | +static bool do_svukte_check(CPURISCVState *env, bool first_stage, |
55 | + RISCVCPUProfile *profile, | 37 | + int mode, bool virt) |
56 | + bool send_warn) | ||
57 | +{ | 38 | +{ |
58 | + int satp_max = satp_mode_max_from_map(cpu->cfg.satp_mode.supported); | 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 | + } | ||
59 | + | 45 | + |
60 | + if (profile->satp_mode > satp_max) { | 46 | + /* |
61 | + if (send_warn) { | 47 | + * Check hstatus.HUKTE if the effective mode is switched to VU-mode by |
62 | + bool is_32bit = riscv_cpu_is_32bit(cpu); | 48 | + * executing HLV/HLVX/HSV in U-mode. |
63 | + const char *req_satp = satp_mode_str(profile->satp_mode, is_32bit); | 49 | + * For other cases, check senvcfg.UKTE. |
64 | + const char *cur_satp = satp_mode_str(satp_max, is_32bit); | 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 | + } | ||
65 | + | 58 | + |
66 | + warn_report("Profile %s requires satp mode %s, " | 59 | + /* |
67 | + "but satp mode %s was set", profile->name, | 60 | + * Svukte extension is qualified only in U or VU-mode. |
68 | + req_satp, cur_satp); | 61 | + * |
69 | + } | 62 | + * Effective mode can be switched to U or VU-mode by: |
70 | + | 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) { | ||
71 | + return false; | 70 | + return false; |
72 | + } | 71 | + } |
73 | + | 72 | + |
74 | + return true; | 73 | + return true; |
75 | +} | 74 | +} |
76 | +#endif | ||
77 | + | 75 | + |
78 | static void riscv_cpu_validate_profile(RISCVCPU *cpu, | 76 | +static bool check_svukte_addr(CPURISCVState *env, vaddr addr) |
79 | RISCVCPUProfile *profile) | 77 | +{ |
80 | { | 78 | + /* svukte extension excludes RV32 */ |
81 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_profile(RISCVCPU *cpu, | 79 | + uint32_t sxlen = 32 * riscv_cpu_sxl(env); |
82 | bool profile_impl = true; | 80 | + uint64_t high_bit = addr & (1UL << (sxlen - 1)); |
83 | int i; | 81 | + return !high_bit; |
84 | 82 | +} | |
85 | +#ifndef CONFIG_USER_ONLY | 83 | + |
86 | + if (profile->satp_mode != RISCV_PROFILE_ATTR_UNUSED) { | 84 | /* |
87 | + profile_impl = riscv_cpu_validate_profile_satp(cpu, profile, | 85 | * get_physical_address - get the physical address for this virtual address |
88 | + send_warn); | 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; | ||
89 | + } | 102 | + } |
90 | +#endif | ||
91 | + | 103 | + |
92 | if (profile->priv_spec != RISCV_PROFILE_ATTR_UNUSED && | 104 | /* |
93 | profile->priv_spec != env->priv_ver) { | 105 | * Check if we should use the background registers for the two |
94 | profile_impl = false; | 106 | * stage translation. We don't need to check if we actually need |
95 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name, | ||
96 | cpu->env.priv_ver = profile->priv_spec; | ||
97 | } | ||
98 | |||
99 | +#ifndef CONFIG_USER_ONLY | ||
100 | + if (profile->satp_mode != RISCV_PROFILE_ATTR_UNUSED) { | ||
101 | + const char *satp_prop = satp_mode_str(profile->satp_mode, | ||
102 | + riscv_cpu_is_32bit(cpu)); | ||
103 | + object_property_set_bool(obj, satp_prop, profile->enabled, NULL); | ||
104 | + } | ||
105 | +#endif | ||
106 | + | ||
107 | for (i = 0; misa_bits[i] != 0; i++) { | ||
108 | uint32_t bit = misa_bits[i]; | ||
109 | |||
110 | -- | 107 | -- |
111 | 2.43.0 | 108 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: "Fea.Wang" <fea.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | The rva22U64 profile, described in: | 3 | Add "svukte" in the ISA string when svukte extension is enabled. |
4 | 4 | ||
5 | https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc#rva22-profiles | 5 | Signed-off-by: Fea.Wang <fea.wang@sifive.com> |
6 | 6 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | |
7 | Contains a set of CPU extensions aimed for 64-bit userspace | 7 | Reviewed-by: Jim Shu <jim.shu@sifive.com> |
8 | applications. Enabling this set to be enabled via a single user flag | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | makes it convenient to enable a predictable set of features for the CPU, | 9 | Message-ID: <20241203034932.25185-6-fea.wang@sifive.com> |
10 | giving users more predicability when running/testing their workloads. | ||
11 | |||
12 | QEMU implements all possible extensions of this profile. All the so | ||
13 | called 'synthetic extensions' described in the profile that are cache | ||
14 | related are ignored/assumed enabled (Za64rs, Zic64b, Ziccif, Ziccrse, | ||
15 | Ziccamoa, Zicclsm) since we do not implement a cache model. | ||
16 | |||
17 | An abstraction called RISCVCPUProfile is created to store the profile. | ||
18 | 'ext_offsets' contains mandatory extensions that QEMU supports. Same | ||
19 | thing with the 'misa_ext' mask. Optional extensions must be enabled | ||
20 | manually in the command line if desired. | ||
21 | |||
22 | The design here is to use the common target/riscv/cpu.c file to store | ||
23 | the profile declaration and export it to the accelerator files. Each | ||
24 | accelerator is then responsible to expose it (or not) to users and how | ||
25 | to enable the extensions. | ||
26 | |||
27 | Next patches will implement the profile for TCG and KVM. | ||
28 | |||
29 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
30 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
31 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
32 | Message-ID: <20231218125334.37184-9-dbarboza@ventanamicro.com> | ||
33 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
34 | --- | 11 | --- |
35 | target/riscv/cpu.h | 12 ++++++++++++ | 12 | target/riscv/cpu.c | 2 ++ |
36 | target/riscv/cpu.c | 32 ++++++++++++++++++++++++++++++++ | 13 | 1 file changed, 2 insertions(+) |
37 | 2 files changed, 44 insertions(+) | ||
38 | 14 | ||
39 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/target/riscv/cpu.h | ||
42 | +++ b/target/riscv/cpu.h | ||
43 | @@ -XXX,XX +XXX,XX @@ const char *riscv_get_misa_ext_description(uint32_t bit); | ||
44 | |||
45 | #define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop) | ||
46 | |||
47 | +typedef struct riscv_cpu_profile { | ||
48 | + const char *name; | ||
49 | + uint32_t misa_ext; | ||
50 | + bool enabled; | ||
51 | + bool user_set; | ||
52 | + const int32_t ext_offsets[]; | ||
53 | +} RISCVCPUProfile; | ||
54 | + | ||
55 | +#define RISCV_PROFILE_EXT_LIST_END -1 | ||
56 | + | ||
57 | +extern RISCVCPUProfile *riscv_profiles[]; | ||
58 | + | ||
59 | /* Privileged specification version */ | ||
60 | enum { | ||
61 | PRIV_VERSION_1_10_0 = 0, | ||
62 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 15 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
63 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
64 | --- a/target/riscv/cpu.c | 17 | --- a/target/riscv/cpu.c |
65 | +++ b/target/riscv/cpu.c | 18 | +++ b/target/riscv/cpu.c |
66 | @@ -XXX,XX +XXX,XX @@ Property riscv_cpu_options[] = { | 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), | ||
67 | DEFINE_PROP_END_OF_LIST(), | 32 | DEFINE_PROP_END_OF_LIST(), |
68 | }; | 33 | }; |
69 | 34 | ||
70 | +/* | ||
71 | + * RVA22U64 defines some 'named features' or 'synthetic extensions' | ||
72 | + * that are cache related: Za64rs, Zic64b, Ziccif, Ziccrse, Ziccamoa | ||
73 | + * and Zicclsm. We do not implement caching in QEMU so we'll consider | ||
74 | + * all these named features as always enabled. | ||
75 | + * | ||
76 | + * There's no riscv,isa update for them (nor for zic64b, despite it | ||
77 | + * having a cfg offset) at this moment. | ||
78 | + */ | ||
79 | +static RISCVCPUProfile RVA22U64 = { | ||
80 | + .name = "rva22u64", | ||
81 | + .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU, | ||
82 | + .ext_offsets = { | ||
83 | + CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause), | ||
84 | + CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb), | ||
85 | + CPU_CFG_OFFSET(ext_zbs), CPU_CFG_OFFSET(ext_zfhmin), | ||
86 | + CPU_CFG_OFFSET(ext_zkt), CPU_CFG_OFFSET(ext_zicntr), | ||
87 | + CPU_CFG_OFFSET(ext_zihpm), CPU_CFG_OFFSET(ext_zicbom), | ||
88 | + CPU_CFG_OFFSET(ext_zicbop), CPU_CFG_OFFSET(ext_zicboz), | ||
89 | + | ||
90 | + /* mandatory named features for this profile */ | ||
91 | + CPU_CFG_OFFSET(zic64b), | ||
92 | + | ||
93 | + RISCV_PROFILE_EXT_LIST_END | ||
94 | + } | ||
95 | +}; | ||
96 | + | ||
97 | +RISCVCPUProfile *riscv_profiles[] = { | ||
98 | + &RVA22U64, | ||
99 | + NULL, | ||
100 | +}; | ||
101 | + | ||
102 | static Property riscv_cpu_properties[] = { | ||
103 | DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true), | ||
104 | |||
105 | -- | 35 | -- |
106 | 2.43.0 | 36 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: "Fea.Wang" <fea.wang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | The TCG emulation implements all the extensions described in the | 3 | The spec explicitly says svukte doesn't support RV32. So check that it |
4 | RVA22U64 profile, both mandatory and optional. The mandatory extensions | 4 | is not enabled in RV32. |
5 | will be enabled via the profile flag. We'll leave the optional | ||
6 | extensions to be enabled by hand. | ||
7 | 5 | ||
8 | Given that this is the first profile we're implementing in TCG we'll | 6 | Signed-off-by: Fea.Wang <fea.wang@sifive.com> |
9 | need some ground work first: | ||
10 | |||
11 | - all profiles declared in riscv_profiles[] will be exposed to users. | ||
12 | TCG is the main accelerator we're considering when adding profile | ||
13 | support in QEMU, so for now it's safe to assume that all profiles in | ||
14 | riscv_profiles[] will be relevant to TCG; | ||
15 | |||
16 | - we'll not support user profile settings for vendor CPUs. The flags | ||
17 | will still be exposed but users won't be able to change them; | ||
18 | |||
19 | - profile support, albeit available for all non-vendor CPUs, will be | ||
20 | based on top of the new 'rv64i' CPU. Setting a profile to 'true' means | ||
21 | enable all mandatory extensions of this profile, setting it to 'false' | ||
22 | will disable all mandatory profile extensions of the CPU, which will | ||
23 | obliterate preset defaults. This is not a problem for a bare CPU like | ||
24 | rv64i but it can allow for silly scenarios when using other CPUs. E.g. | ||
25 | an user can do "-cpu rv64,rva22u64=false" and have a bunch of default | ||
26 | rv64 extensions disabled. The recommended way of using profiles is the | ||
27 | rv64i CPU, but users are free to experiment. | ||
28 | |||
29 | For now we'll handle multi-letter extensions only. MISA extensions need | ||
30 | additional steps that we'll take care later. At this point we can boot a | ||
31 | Linux buildroot using rva22u64 using the following options: | ||
32 | |||
33 | -cpu rv64i,rva22u64=true,sv39=true,g=true,c=true,s=true | ||
34 | |||
35 | Note that being an usermode/application profile we still need to | ||
36 | explicitly set 's=true' to enable Supervisor mode to boot Linux. | ||
37 | |||
38 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
39 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
40 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
41 | Message-ID: <20231218125334.37184-11-dbarboza@ventanamicro.com> | 8 | Message-ID: <20241203034932.25185-7-fea.wang@sifive.com> |
42 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
43 | --- | 10 | --- |
44 | target/riscv/tcg/tcg-cpu.c | 80 ++++++++++++++++++++++++++++++++++++++ | 11 | target/riscv/tcg/tcg-cpu.c | 5 +++++ |
45 | 1 file changed, 80 insertions(+) | 12 | 1 file changed, 5 insertions(+) |
46 | 13 | ||
47 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 14 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c |
48 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
49 | --- a/target/riscv/tcg/tcg-cpu.c | 16 | --- a/target/riscv/tcg/tcg-cpu.c |
50 | +++ b/target/riscv/tcg/tcg-cpu.c | 17 | +++ b/target/riscv/tcg/tcg-cpu.c |
51 | @@ -XXX,XX +XXX,XX @@ static bool cpu_cfg_offset_is_named_feat(uint32_t ext_offset) | 18 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) |
52 | return false; | 19 | return; |
53 | } | ||
54 | |||
55 | +static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset) | ||
56 | +{ | ||
57 | + switch (feat_offset) { | ||
58 | + case CPU_CFG_OFFSET(zic64b): | ||
59 | + cpu->cfg.cbom_blocksize = 64; | ||
60 | + cpu->cfg.cbop_blocksize = 64; | ||
61 | + cpu->cfg.cboz_blocksize = 64; | ||
62 | + break; | ||
63 | + default: | ||
64 | + g_assert_not_reached(); | ||
65 | + } | ||
66 | +} | ||
67 | + | ||
68 | static void cpu_bump_multi_ext_priv_ver(CPURISCVState *env, | ||
69 | uint32_t ext_offset) | ||
70 | { | ||
71 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj) | ||
72 | } | 20 | } |
73 | } | 21 | |
74 | 22 | + if (mcc->misa_mxl_max == MXL_RV32 && cpu->cfg.ext_svukte) { | |
75 | +static void cpu_set_profile(Object *obj, Visitor *v, const char *name, | 23 | + error_setg(errp, "svukte is not supported for RV32"); |
76 | + void *opaque, Error **errp) | ||
77 | +{ | ||
78 | + RISCVCPUProfile *profile = opaque; | ||
79 | + RISCVCPU *cpu = RISCV_CPU(obj); | ||
80 | + bool value; | ||
81 | + int i, ext_offset; | ||
82 | + | ||
83 | + if (riscv_cpu_is_vendor(obj)) { | ||
84 | + error_setg(errp, "Profile %s is not available for vendor CPUs", | ||
85 | + profile->name); | ||
86 | + return; | 24 | + return; |
87 | + } | 25 | + } |
88 | + | 26 | + |
89 | + if (cpu->env.misa_mxl != MXL_RV64) { | 27 | /* |
90 | + error_setg(errp, "Profile %s only available for 64 bit CPUs", | 28 | * Disable isa extensions based on priv spec after we |
91 | + profile->name); | 29 | * validated and set everything we need. |
92 | + return; | ||
93 | + } | ||
94 | + | ||
95 | + if (!visit_type_bool(v, name, &value, errp)) { | ||
96 | + return; | ||
97 | + } | ||
98 | + | ||
99 | + profile->user_set = true; | ||
100 | + profile->enabled = value; | ||
101 | + | ||
102 | + for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) { | ||
103 | + ext_offset = profile->ext_offsets[i]; | ||
104 | + | ||
105 | + if (profile->enabled) { | ||
106 | + if (cpu_cfg_offset_is_named_feat(ext_offset)) { | ||
107 | + riscv_cpu_enable_named_feat(cpu, ext_offset); | ||
108 | + } | ||
109 | + | ||
110 | + cpu_bump_multi_ext_priv_ver(&cpu->env, ext_offset); | ||
111 | + } | ||
112 | + | ||
113 | + g_hash_table_insert(multi_ext_user_opts, | ||
114 | + GUINT_TO_POINTER(ext_offset), | ||
115 | + (gpointer)profile->enabled); | ||
116 | + isa_ext_update_enabled(cpu, ext_offset, profile->enabled); | ||
117 | + } | ||
118 | +} | ||
119 | + | ||
120 | +static void cpu_get_profile(Object *obj, Visitor *v, const char *name, | ||
121 | + void *opaque, Error **errp) | ||
122 | +{ | ||
123 | + RISCVCPUProfile *profile = opaque; | ||
124 | + bool value = profile->enabled; | ||
125 | + | ||
126 | + visit_type_bool(v, name, &value, errp); | ||
127 | +} | ||
128 | + | ||
129 | +static void riscv_cpu_add_profiles(Object *cpu_obj) | ||
130 | +{ | ||
131 | + for (int i = 0; riscv_profiles[i] != NULL; i++) { | ||
132 | + const RISCVCPUProfile *profile = riscv_profiles[i]; | ||
133 | + | ||
134 | + object_property_add(cpu_obj, profile->name, "bool", | ||
135 | + cpu_get_profile, cpu_set_profile, | ||
136 | + NULL, (void *)profile); | ||
137 | + } | ||
138 | +} | ||
139 | + | ||
140 | static bool cpu_ext_is_deprecated(const char *ext_name) | ||
141 | { | ||
142 | return isupper(ext_name[0]); | ||
143 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_user_properties(Object *obj) | ||
144 | |||
145 | riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_deprecated_exts); | ||
146 | |||
147 | + riscv_cpu_add_profiles(obj); | ||
148 | + | ||
149 | for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) { | ||
150 | qdev_property_add_static(DEVICE(obj), prop); | ||
151 | } | ||
152 | -- | 30 | -- |
153 | 2.43.0 | 31 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | mvendorid is an uint32 property, mimpid/marchid are uint64 properties. | 3 | Rather than relying on implicit includes, explicit them, |
4 | But their getters are returning bools. The reason this went under the | 4 | in order to avoid when refactoring unrelated headers: |
5 | radar for this long is because we have no code using the getters. | ||
6 | 5 | ||
7 | The problem can be seem via the 'qom-get' API though. Launching QEMU | 6 | target/riscv/vector_internals.h:36:12: error: call to undeclared function 'FIELD_EX32'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] |
8 | with the 'veyron-v1' CPU, a model with: | 7 | 36 | return FIELD_EX32(simd_data(desc), VDATA, NF); |
8 | | ^ | ||
9 | 9 | ||
10 | VEYRON_V1_MVENDORID: 0x61f (1567) | 10 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
11 | VEYRON_V1_MIMPID: 0x111 (273) | ||
12 | VEYRON_V1_MARCHID: 0x8000000000010000 (9223372036854841344) | ||
13 | |||
14 | This is what the API returns when retrieving these properties: | ||
15 | |||
16 | (qemu) qom-get /machine/soc0/harts[0] mvendorid | ||
17 | true | ||
18 | (qemu) qom-get /machine/soc0/harts[0] mimpid | ||
19 | true | ||
20 | (qemu) qom-get /machine/soc0/harts[0] marchid | ||
21 | true | ||
22 | |||
23 | After this patch: | ||
24 | |||
25 | (qemu) qom-get /machine/soc0/harts[0] mvendorid | ||
26 | 1567 | ||
27 | (qemu) qom-get /machine/soc0/harts[0] mimpid | ||
28 | 273 | ||
29 | (qemu) qom-get /machine/soc0/harts[0] marchid | ||
30 | 9223372036854841344 | ||
31 | |||
32 | Fixes: 1e34150045 ("target/riscv/cpu.c: restrict 'mvendorid' value") | ||
33 | Fixes: a1863ad368 ("target/riscv/cpu.c: restrict 'mimpid' value") | ||
34 | Fixes: d6a427e2c0 ("target/riscv/cpu.c: restrict 'marchid' value") | ||
35 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
36 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
37 | Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> | 12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
38 | Message-ID: <20231211170732.2541368-1-dbarboza@ventanamicro.com> | 13 | Message-ID: <20241203200828.47311-2-philmd@linaro.org> |
39 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
40 | --- | 15 | --- |
41 | target/riscv/cpu.c | 12 ++++++------ | 16 | target/riscv/vector_internals.h | 1 + |
42 | 1 file changed, 6 insertions(+), 6 deletions(-) | 17 | 1 file changed, 1 insertion(+) |
43 | 18 | ||
44 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 19 | diff --git a/target/riscv/vector_internals.h b/target/riscv/vector_internals.h |
45 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
46 | --- a/target/riscv/cpu.c | 21 | --- a/target/riscv/vector_internals.h |
47 | +++ b/target/riscv/cpu.c | 22 | +++ b/target/riscv/vector_internals.h |
48 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_mvendorid(Object *obj, Visitor *v, const char *name, | 23 | @@ -XXX,XX +XXX,XX @@ |
49 | static void cpu_get_mvendorid(Object *obj, Visitor *v, const char *name, | 24 | #define TARGET_RISCV_VECTOR_INTERNALS_H |
50 | void *opaque, Error **errp) | 25 | |
51 | { | 26 | #include "qemu/bitops.h" |
52 | - bool value = RISCV_CPU(obj)->cfg.mvendorid; | 27 | +#include "hw/registerfields.h" |
53 | + uint32_t value = RISCV_CPU(obj)->cfg.mvendorid; | 28 | #include "cpu.h" |
54 | 29 | #include "tcg/tcg-gvec-desc.h" | |
55 | - visit_type_bool(v, name, &value, errp); | 30 | #include "internals.h" |
56 | + visit_type_uint32(v, name, &value, errp); | ||
57 | } | ||
58 | |||
59 | static void cpu_set_mimpid(Object *obj, Visitor *v, const char *name, | ||
60 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_mimpid(Object *obj, Visitor *v, const char *name, | ||
61 | static void cpu_get_mimpid(Object *obj, Visitor *v, const char *name, | ||
62 | void *opaque, Error **errp) | ||
63 | { | ||
64 | - bool value = RISCV_CPU(obj)->cfg.mimpid; | ||
65 | + uint64_t value = RISCV_CPU(obj)->cfg.mimpid; | ||
66 | |||
67 | - visit_type_bool(v, name, &value, errp); | ||
68 | + visit_type_uint64(v, name, &value, errp); | ||
69 | } | ||
70 | |||
71 | static void cpu_set_marchid(Object *obj, Visitor *v, const char *name, | ||
72 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_marchid(Object *obj, Visitor *v, const char *name, | ||
73 | static void cpu_get_marchid(Object *obj, Visitor *v, const char *name, | ||
74 | void *opaque, Error **errp) | ||
75 | { | ||
76 | - bool value = RISCV_CPU(obj)->cfg.marchid; | ||
77 | + uint64_t value = RISCV_CPU(obj)->cfg.marchid; | ||
78 | |||
79 | - visit_type_bool(v, name, &value, errp); | ||
80 | + visit_type_uint64(v, name, &value, errp); | ||
81 | } | ||
82 | |||
83 | static void riscv_cpu_class_init(ObjectClass *c, void *data) | ||
84 | -- | 31 | -- |
85 | 2.43.0 | 32 | 2.47.1 |
86 | 33 | ||
87 | 34 | diff view generated by jsdifflib |
1 | From: Max Chou <max.chou@sifive.com> | 1 | From: Philippe Mathieu-Daudé <philmd@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | The ratified version of RISC-V V spec section 16.6 says that | 3 | Rather than relying on implicit includes, explicit them, |
4 | `The instructions operate as if EEW=SEW`. | 4 | in order to avoid when refactoring unrelated headers: |
5 | 5 | ||
6 | So the whole vector register move instructions depend on the vtype | 6 | target/riscv/internals.h:49:15: error: use of undeclared identifier 'PRV_S' |
7 | register that means the whole vector register move instructions should | 7 | 49 | ret = PRV_S; |
8 | raise an illegal-instruction exception when vtype.vill=1. | 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 | ||
9 | 16 | ||
10 | Signed-off-by: Max Chou <max.chou@sifive.com> | 17 | Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> |
18 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 19 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
12 | Message-ID: <20231129170400.21251-2-max.chou@sifive.com> | 20 | Message-ID: <20241203200828.47311-3-philmd@linaro.org> |
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 22 | --- |
15 | target/riscv/insn_trans/trans_rvv.c.inc | 5 +++-- | 23 | target/riscv/internals.h | 3 +++ |
16 | 1 file changed, 3 insertions(+), 2 deletions(-) | 24 | 1 file changed, 3 insertions(+) |
17 | 25 | ||
18 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | 26 | diff --git a/target/riscv/internals.h b/target/riscv/internals.h |
19 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | 28 | --- a/target/riscv/internals.h |
21 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | 29 | +++ b/target/riscv/internals.h |
22 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a) | 30 | @@ -XXX,XX +XXX,XX @@ |
23 | } | 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" | ||
24 | 38 | ||
25 | /* | 39 | /* |
26 | - * Whole Vector Register Move Instructions ignore vtype and vl setting. | 40 | * The current MMU Modes are: |
27 | - * Thus, we don't need to check vill bit. (Section 16.6) | ||
28 | + * Whole Vector Register Move Instructions depend on vtype register(vsew). | ||
29 | + * Thus, we need to check vill bit. (Section 16.6) | ||
30 | */ | ||
31 | #define GEN_VMV_WHOLE_TRANS(NAME, LEN) \ | ||
32 | static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
33 | { \ | ||
34 | if (require_rvv(s) && \ | ||
35 | + vext_check_isa_ill(s) && \ | ||
36 | QEMU_IS_ALIGNED(a->rd, LEN) && \ | ||
37 | QEMU_IS_ALIGNED(a->rs2, LEN)) { \ | ||
38 | uint32_t maxsz = (s->cfg_ptr->vlen >> 3) * LEN; \ | ||
39 | -- | 41 | -- |
40 | 2.43.0 | 42 | 2.47.1 |
43 | |||
44 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Max Chou <max.chou@sifive.com> | ||
2 | 1 | ||
3 | The RISC-V v spec 16.6 section says that the whole vector register move | ||
4 | instructions operate as if EEW=SEW. So it should depends on the vsew | ||
5 | field of vtype register. | ||
6 | |||
7 | Signed-off-by: Max Chou <max.chou@sifive.com> | ||
8 | Acked-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Message-ID: <20231129170400.21251-3-max.chou@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | --- | ||
12 | target/riscv/insn_trans/trans_rvv.c.inc | 3 +-- | ||
13 | 1 file changed, 1 insertion(+), 2 deletions(-) | ||
14 | |||
15 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
16 | index XXXXXXX..XXXXXXX 100644 | ||
17 | --- a/target/riscv/insn_trans/trans_rvv.c.inc | ||
18 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc | ||
19 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
20 | QEMU_IS_ALIGNED(a->rs2, LEN)) { \ | ||
21 | uint32_t maxsz = (s->cfg_ptr->vlen >> 3) * LEN; \ | ||
22 | if (s->vstart_eq_zero) { \ | ||
23 | - /* EEW = 8 */ \ | ||
24 | - tcg_gen_gvec_mov(MO_8, vreg_ofs(s, a->rd), \ | ||
25 | + tcg_gen_gvec_mov(s->sew, vreg_ofs(s, a->rd), \ | ||
26 | vreg_ofs(s, a->rs2), maxsz, maxsz); \ | ||
27 | mark_vs_dirty(s); \ | ||
28 | } else { \ | ||
29 | -- | ||
30 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
2 | 1 | ||
3 | According to the specification, the th.dcache.cvall1 can be executed | ||
4 | under all priviledges. | ||
5 | The specification about xtheadcmo located in, | ||
6 | https://github.com/T-head-Semi/thead-extension-spec/blob/master/xtheadcmo/dcache_cval1.adoc | ||
7 | |||
8 | Signed-off-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Reviewed-by: Christoph Muellner <christoph.muellner@vrull.eu> | ||
11 | Message-ID: <20231208094315.177-1-zhiwei_liu@linux.alibaba.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/insn_trans/trans_xthead.c.inc | 2 +- | ||
15 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/target/riscv/insn_trans/trans_xthead.c.inc b/target/riscv/insn_trans/trans_xthead.c.inc | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/insn_trans/trans_xthead.c.inc | ||
20 | +++ b/target/riscv/insn_trans/trans_xthead.c.inc | ||
21 | @@ -XXX,XX +XXX,XX @@ NOP_PRIVCHECK(th_dcache_csw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS) | ||
22 | NOP_PRIVCHECK(th_dcache_cisw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS) | ||
23 | NOP_PRIVCHECK(th_dcache_isw, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS) | ||
24 | NOP_PRIVCHECK(th_dcache_cpal1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS) | ||
25 | -NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS) | ||
26 | +NOP_PRIVCHECK(th_dcache_cval1, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MSU) | ||
27 | |||
28 | NOP_PRIVCHECK(th_icache_iall, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS) | ||
29 | NOP_PRIVCHECK(th_icache_ialls, REQUIRE_XTHEADCMO, REQUIRE_PRIV_MS) | ||
30 | -- | ||
31 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Ivan Klokov <ivan.klokov@syntacore.com> | ||
2 | 1 | ||
3 | The Sv32 page-based virtual-memory scheme described in RISCV privileged | ||
4 | spec Section 5.3 supports 34-bit physical addresses for RV32, so the | ||
5 | PMP scheme must support addresses wider than XLEN for RV32. However, | ||
6 | PMP address register format is still 32 bit wide. | ||
7 | |||
8 | Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Message-ID: <20231123091214.20312-1-ivan.klokov@syntacore.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | target/riscv/pmp.h | 8 ++++---- | ||
14 | target/riscv/pmp.c | 26 ++++++++++++-------------- | ||
15 | 2 files changed, 16 insertions(+), 18 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/pmp.h | ||
20 | +++ b/target/riscv/pmp.h | ||
21 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
22 | } pmp_entry_t; | ||
23 | |||
24 | typedef struct { | ||
25 | - target_ulong sa; | ||
26 | - target_ulong ea; | ||
27 | + hwaddr sa; | ||
28 | + hwaddr ea; | ||
29 | } pmp_addr_t; | ||
30 | |||
31 | typedef struct { | ||
32 | @@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env); | ||
33 | void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index, | ||
34 | target_ulong val); | ||
35 | target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index); | ||
36 | -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
37 | +bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr, | ||
38 | target_ulong size, pmp_priv_t privs, | ||
39 | pmp_priv_t *allowed_privs, | ||
40 | target_ulong mode); | ||
41 | -target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr); | ||
42 | +target_ulong pmp_get_tlb_size(CPURISCVState *env, hwaddr addr); | ||
43 | void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index); | ||
44 | void pmp_update_rule_nums(CPURISCVState *env); | ||
45 | uint32_t pmp_get_num_rules(CPURISCVState *env); | ||
46 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
47 | index XXXXXXX..XXXXXXX 100644 | ||
48 | --- a/target/riscv/pmp.c | ||
49 | +++ b/target/riscv/pmp.c | ||
50 | @@ -XXX,XX +XXX,XX @@ void pmp_unlock_entries(CPURISCVState *env) | ||
51 | } | ||
52 | } | ||
53 | |||
54 | -static void pmp_decode_napot(target_ulong a, target_ulong *sa, | ||
55 | - target_ulong *ea) | ||
56 | +static void pmp_decode_napot(hwaddr a, hwaddr *sa, hwaddr *ea) | ||
57 | { | ||
58 | /* | ||
59 | * aaaa...aaa0 8-byte NAPOT range | ||
60 | @@ -XXX,XX +XXX,XX @@ void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index) | ||
61 | uint8_t this_cfg = env->pmp_state.pmp[pmp_index].cfg_reg; | ||
62 | target_ulong this_addr = env->pmp_state.pmp[pmp_index].addr_reg; | ||
63 | target_ulong prev_addr = 0u; | ||
64 | - target_ulong sa = 0u; | ||
65 | - target_ulong ea = 0u; | ||
66 | + hwaddr sa = 0u; | ||
67 | + hwaddr ea = 0u; | ||
68 | |||
69 | if (pmp_index >= 1u) { | ||
70 | prev_addr = env->pmp_state.pmp[pmp_index - 1].addr_reg; | ||
71 | @@ -XXX,XX +XXX,XX @@ void pmp_update_rule_nums(CPURISCVState *env) | ||
72 | } | ||
73 | } | ||
74 | |||
75 | -static int pmp_is_in_range(CPURISCVState *env, int pmp_index, | ||
76 | - target_ulong addr) | ||
77 | +static int pmp_is_in_range(CPURISCVState *env, int pmp_index, hwaddr addr) | ||
78 | { | ||
79 | int result = 0; | ||
80 | |||
81 | @@ -XXX,XX +XXX,XX @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, pmp_priv_t privs, | ||
82 | * Return true if a pmp rule match or default match | ||
83 | * Return false if no match | ||
84 | */ | ||
85 | -bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr, | ||
86 | +bool pmp_hart_has_privs(CPURISCVState *env, hwaddr addr, | ||
87 | target_ulong size, pmp_priv_t privs, | ||
88 | pmp_priv_t *allowed_privs, target_ulong mode) | ||
89 | { | ||
90 | int i = 0; | ||
91 | int pmp_size = 0; | ||
92 | - target_ulong s = 0; | ||
93 | - target_ulong e = 0; | ||
94 | + hwaddr s = 0; | ||
95 | + hwaddr e = 0; | ||
96 | |||
97 | /* Short cut if no rules */ | ||
98 | if (0 == pmp_get_num_rules(env)) { | ||
99 | @@ -XXX,XX +XXX,XX @@ target_ulong mseccfg_csr_read(CPURISCVState *env) | ||
100 | * To avoid this we return a size of 1 (which means no caching) if the PMP | ||
101 | * region only covers partial of the TLB page. | ||
102 | */ | ||
103 | -target_ulong pmp_get_tlb_size(CPURISCVState *env, target_ulong addr) | ||
104 | +target_ulong pmp_get_tlb_size(CPURISCVState *env, hwaddr addr) | ||
105 | { | ||
106 | - target_ulong pmp_sa; | ||
107 | - target_ulong pmp_ea; | ||
108 | - target_ulong tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1); | ||
109 | - target_ulong tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1; | ||
110 | + hwaddr pmp_sa; | ||
111 | + hwaddr pmp_ea; | ||
112 | + hwaddr tlb_sa = addr & ~(TARGET_PAGE_SIZE - 1); | ||
113 | + hwaddr tlb_ea = tlb_sa + TARGET_PAGE_SIZE - 1; | ||
114 | int i; | ||
115 | |||
116 | /* | ||
117 | -- | ||
118 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | KVM_REG_RISCV_FP_F regs have u32 size according to the API, but by using | ||
4 | kvm_riscv_reg_id() in RISCV_FP_F_REG() we're returning u64 sizes when | ||
5 | running with TARGET_RISCV64. The most likely reason why no one noticed | ||
6 | this is because we're not implementing kvm_cpu_synchronize_state() in | ||
7 | RISC-V yet. | ||
8 | |||
9 | Create a new helper that returns a KVM ID with u32 size and use it in | ||
10 | RISCV_FP_F_REG(). | ||
11 | |||
12 | Reported-by: Andrew Jones <ajones@ventanamicro.com> | ||
13 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
14 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
15 | Message-ID: <20231208183835.2411523-2-dbarboza@ventanamicro.com> | ||
16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
17 | --- | ||
18 | target/riscv/kvm/kvm-cpu.c | 11 ++++++++--- | ||
19 | 1 file changed, 8 insertions(+), 3 deletions(-) | ||
20 | |||
21 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/target/riscv/kvm/kvm-cpu.c | ||
24 | +++ b/target/riscv/kvm/kvm-cpu.c | ||
25 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, | ||
26 | return id; | ||
27 | } | ||
28 | |||
29 | +static uint64_t kvm_riscv_reg_id_u32(uint64_t type, uint64_t idx) | ||
30 | +{ | ||
31 | + return KVM_REG_RISCV | KVM_REG_SIZE_U32 | type | idx; | ||
32 | +} | ||
33 | + | ||
34 | #define RISCV_CORE_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \ | ||
35 | KVM_REG_RISCV_CORE_REG(name)) | ||
36 | |||
37 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, | ||
38 | #define RISCV_TIMER_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_TIMER, \ | ||
39 | KVM_REG_RISCV_TIMER_REG(name)) | ||
40 | |||
41 | -#define RISCV_FP_F_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, idx) | ||
42 | +#define RISCV_FP_F_REG(idx) kvm_riscv_reg_id_u32(KVM_REG_RISCV_FP_F, idx) | ||
43 | |||
44 | #define RISCV_FP_D_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx) | ||
45 | |||
46 | @@ -XXX,XX +XXX,XX @@ static int kvm_riscv_get_regs_fp(CPUState *cs) | ||
47 | if (riscv_has_ext(env, RVF)) { | ||
48 | uint32_t reg; | ||
49 | for (i = 0; i < 32; i++) { | ||
50 | - ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(env, i), ®); | ||
51 | + ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(i), ®); | ||
52 | if (ret) { | ||
53 | return ret; | ||
54 | } | ||
55 | @@ -XXX,XX +XXX,XX @@ static int kvm_riscv_put_regs_fp(CPUState *cs) | ||
56 | uint32_t reg; | ||
57 | for (i = 0; i < 32; i++) { | ||
58 | reg = env->fpr[i]; | ||
59 | - ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(env, i), ®); | ||
60 | + ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(i), ®); | ||
61 | if (ret) { | ||
62 | return ret; | ||
63 | } | ||
64 | -- | ||
65 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | KVM_REG_RISCV_FP_D regs are always u64 size. Using kvm_riscv_reg_id() in | ||
4 | RISCV_FP_D_REG() ends up encoding the wrong size if we're running with | ||
5 | TARGET_RISCV32. | ||
6 | |||
7 | Create a new helper that returns a KVM ID with u64 size and use it with | ||
8 | RISCV_FP_D_REG(). | ||
9 | |||
10 | Reported-by: Andrew Jones <ajones@ventanamicro.com> | ||
11 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
12 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
13 | Message-ID: <20231208183835.2411523-3-dbarboza@ventanamicro.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/kvm/kvm-cpu.c | 11 ++++++++--- | ||
17 | 1 file changed, 8 insertions(+), 3 deletions(-) | ||
18 | |||
19 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/riscv/kvm/kvm-cpu.c | ||
22 | +++ b/target/riscv/kvm/kvm-cpu.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id_u32(uint64_t type, uint64_t idx) | ||
24 | return KVM_REG_RISCV | KVM_REG_SIZE_U32 | type | idx; | ||
25 | } | ||
26 | |||
27 | +static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t idx) | ||
28 | +{ | ||
29 | + return KVM_REG_RISCV | KVM_REG_SIZE_U64 | type | idx; | ||
30 | +} | ||
31 | + | ||
32 | #define RISCV_CORE_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \ | ||
33 | KVM_REG_RISCV_CORE_REG(name)) | ||
34 | |||
35 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id_u32(uint64_t type, uint64_t idx) | ||
36 | |||
37 | #define RISCV_FP_F_REG(idx) kvm_riscv_reg_id_u32(KVM_REG_RISCV_FP_F, idx) | ||
38 | |||
39 | -#define RISCV_FP_D_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx) | ||
40 | +#define RISCV_FP_D_REG(idx) kvm_riscv_reg_id_u64(KVM_REG_RISCV_FP_D, idx) | ||
41 | |||
42 | #define KVM_RISCV_GET_CSR(cs, env, csr, reg) \ | ||
43 | do { \ | ||
44 | @@ -XXX,XX +XXX,XX @@ static int kvm_riscv_get_regs_fp(CPUState *cs) | ||
45 | if (riscv_has_ext(env, RVD)) { | ||
46 | uint64_t reg; | ||
47 | for (i = 0; i < 32; i++) { | ||
48 | - ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(env, i), ®); | ||
49 | + ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(i), ®); | ||
50 | if (ret) { | ||
51 | return ret; | ||
52 | } | ||
53 | @@ -XXX,XX +XXX,XX @@ static int kvm_riscv_put_regs_fp(CPUState *cs) | ||
54 | uint64_t reg; | ||
55 | for (i = 0; i < 32; i++) { | ||
56 | reg = env->fpr[i]; | ||
57 | - ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(env, i), ®); | ||
58 | + ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(i), ®); | ||
59 | if (ret) { | ||
60 | return ret; | ||
61 | } | ||
62 | -- | ||
63 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | KVM_REG_RISCV_TIMER regs are always u64 according to the KVM API, but at | ||
4 | this moment we'll return u32 regs if we're running a RISCV32 target. | ||
5 | |||
6 | Use the kvm_riscv_reg_id_u64() helper in RISCV_TIMER_REG() to fix it. | ||
7 | |||
8 | Reported-by: Andrew Jones <ajones@ventanamicro.com> | ||
9 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
10 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
11 | Message-ID: <20231208183835.2411523-4-dbarboza@ventanamicro.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/kvm/kvm-cpu.c | 26 +++++++++++++------------- | ||
15 | 1 file changed, 13 insertions(+), 13 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/kvm/kvm-cpu.c | ||
20 | +++ b/target/riscv/kvm/kvm-cpu.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t idx) | ||
22 | #define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \ | ||
23 | KVM_REG_RISCV_CSR_REG(name)) | ||
24 | |||
25 | -#define RISCV_TIMER_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_TIMER, \ | ||
26 | +#define RISCV_TIMER_REG(name) kvm_riscv_reg_id_u64(KVM_REG_RISCV_TIMER, \ | ||
27 | KVM_REG_RISCV_TIMER_REG(name)) | ||
28 | |||
29 | #define RISCV_FP_F_REG(idx) kvm_riscv_reg_id_u32(KVM_REG_RISCV_FP_F, idx) | ||
30 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t idx) | ||
31 | } \ | ||
32 | } while (0) | ||
33 | |||
34 | -#define KVM_RISCV_GET_TIMER(cs, env, name, reg) \ | ||
35 | +#define KVM_RISCV_GET_TIMER(cs, name, reg) \ | ||
36 | do { \ | ||
37 | - int ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, name), ®); \ | ||
38 | + int ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(name), ®); \ | ||
39 | if (ret) { \ | ||
40 | abort(); \ | ||
41 | } \ | ||
42 | } while (0) | ||
43 | |||
44 | -#define KVM_RISCV_SET_TIMER(cs, env, name, reg) \ | ||
45 | +#define KVM_RISCV_SET_TIMER(cs, name, reg) \ | ||
46 | do { \ | ||
47 | - int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, name), ®); \ | ||
48 | + int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(name), ®); \ | ||
49 | if (ret) { \ | ||
50 | abort(); \ | ||
51 | } \ | ||
52 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_get_regs_timer(CPUState *cs) | ||
53 | return; | ||
54 | } | ||
55 | |||
56 | - KVM_RISCV_GET_TIMER(cs, env, time, env->kvm_timer_time); | ||
57 | - KVM_RISCV_GET_TIMER(cs, env, compare, env->kvm_timer_compare); | ||
58 | - KVM_RISCV_GET_TIMER(cs, env, state, env->kvm_timer_state); | ||
59 | - KVM_RISCV_GET_TIMER(cs, env, frequency, env->kvm_timer_frequency); | ||
60 | + KVM_RISCV_GET_TIMER(cs, time, env->kvm_timer_time); | ||
61 | + KVM_RISCV_GET_TIMER(cs, compare, env->kvm_timer_compare); | ||
62 | + KVM_RISCV_GET_TIMER(cs, state, env->kvm_timer_state); | ||
63 | + KVM_RISCV_GET_TIMER(cs, frequency, env->kvm_timer_frequency); | ||
64 | |||
65 | env->kvm_timer_dirty = true; | ||
66 | } | ||
67 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs) | ||
68 | return; | ||
69 | } | ||
70 | |||
71 | - KVM_RISCV_SET_TIMER(cs, env, time, env->kvm_timer_time); | ||
72 | - KVM_RISCV_SET_TIMER(cs, env, compare, env->kvm_timer_compare); | ||
73 | + KVM_RISCV_SET_TIMER(cs, time, env->kvm_timer_time); | ||
74 | + KVM_RISCV_SET_TIMER(cs, compare, env->kvm_timer_compare); | ||
75 | |||
76 | /* | ||
77 | * To set register of RISCV_TIMER_REG(state) will occur a error from KVM | ||
78 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs) | ||
79 | * TODO If KVM changes, adapt here. | ||
80 | */ | ||
81 | if (env->kvm_timer_state) { | ||
82 | - KVM_RISCV_SET_TIMER(cs, env, state, env->kvm_timer_state); | ||
83 | + KVM_RISCV_SET_TIMER(cs, state, env->kvm_timer_state); | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_put_regs_timer(CPUState *cs) | ||
88 | * during the migration. | ||
89 | */ | ||
90 | if (migration_is_running(migrate_get_current()->state)) { | ||
91 | - KVM_RISCV_GET_TIMER(cs, env, frequency, reg); | ||
92 | + KVM_RISCV_GET_TIMER(cs, frequency, reg); | ||
93 | if (reg != env->kvm_timer_frequency) { | ||
94 | error_report("Dst Hosts timer frequency != Src Hosts"); | ||
95 | } | ||
96 | -- | ||
97 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | Create a RISCV_CONFIG_REG() macro, similar to what other regs use, to | ||
4 | hide away some of the boilerplate. | ||
5 | |||
6 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
7 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
8 | Message-ID: <20231208183835.2411523-5-dbarboza@ventanamicro.com> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | --- | ||
11 | target/riscv/kvm/kvm-cpu.c | 25 +++++++++++-------------- | ||
12 | 1 file changed, 11 insertions(+), 14 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 @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t idx) | ||
19 | #define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \ | ||
20 | KVM_REG_RISCV_CSR_REG(name)) | ||
21 | |||
22 | +#define RISCV_CONFIG_REG(env, name) \ | ||
23 | + kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, \ | ||
24 | + KVM_REG_RISCV_CONFIG_REG(name)) | ||
25 | + | ||
26 | #define RISCV_TIMER_REG(name) kvm_riscv_reg_id_u64(KVM_REG_RISCV_TIMER, \ | ||
27 | KVM_REG_RISCV_TIMER_REG(name)) | ||
28 | |||
29 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, KVMScratchCPU *kvmcpu) | ||
30 | struct kvm_one_reg reg; | ||
31 | int ret; | ||
32 | |||
33 | - reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
34 | - KVM_REG_RISCV_CONFIG_REG(mvendorid)); | ||
35 | + reg.id = RISCV_CONFIG_REG(env, mvendorid); | ||
36 | reg.addr = (uint64_t)&cpu->cfg.mvendorid; | ||
37 | ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); | ||
38 | if (ret != 0) { | ||
39 | error_report("Unable to retrieve mvendorid from host, error %d", ret); | ||
40 | } | ||
41 | |||
42 | - reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
43 | - KVM_REG_RISCV_CONFIG_REG(marchid)); | ||
44 | + reg.id = RISCV_CONFIG_REG(env, marchid); | ||
45 | reg.addr = (uint64_t)&cpu->cfg.marchid; | ||
46 | ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); | ||
47 | if (ret != 0) { | ||
48 | error_report("Unable to retrieve marchid from host, error %d", ret); | ||
49 | } | ||
50 | |||
51 | - reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
52 | - KVM_REG_RISCV_CONFIG_REG(mimpid)); | ||
53 | + reg.id = RISCV_CONFIG_REG(env, mimpid); | ||
54 | reg.addr = (uint64_t)&cpu->cfg.mimpid; | ||
55 | ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); | ||
56 | if (ret != 0) { | ||
57 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_misa_ext_mask(RISCVCPU *cpu, | ||
58 | struct kvm_one_reg reg; | ||
59 | int ret; | ||
60 | |||
61 | - reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
62 | - KVM_REG_RISCV_CONFIG_REG(isa)); | ||
63 | + reg.id = RISCV_CONFIG_REG(env, isa); | ||
64 | reg.addr = (uint64_t)&env->misa_ext_mask; | ||
65 | ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); | ||
66 | |||
67 | @@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs) | ||
68 | uint64_t id; | ||
69 | int ret; | ||
70 | |||
71 | - id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
72 | - KVM_REG_RISCV_CONFIG_REG(mvendorid)); | ||
73 | + id = RISCV_CONFIG_REG(env, mvendorid); | ||
74 | /* | ||
75 | * cfg.mvendorid is an uint32 but a target_ulong will | ||
76 | * be written. Assign it to a target_ulong var to avoid | ||
77 | @@ -XXX,XX +XXX,XX @@ static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs) | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | - id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
82 | - KVM_REG_RISCV_CONFIG_REG(marchid)); | ||
83 | + id = RISCV_CONFIG_REG(env, marchid); | ||
84 | ret = kvm_set_one_reg(cs, id, &cpu->cfg.marchid); | ||
85 | if (ret != 0) { | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | - id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
90 | - KVM_REG_RISCV_CONFIG_REG(mimpid)); | ||
91 | + id = RISCV_CONFIG_REG(env, mimpid); | ||
92 | ret = kvm_set_one_reg(cs, id, &cpu->cfg.mimpid); | ||
93 | |||
94 | return ret; | ||
95 | -- | ||
96 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | kvm_riscv_reg_id() returns an id encoded with an ulong size, i.e. an u32 | ||
4 | size when running TARGET_RISCV32 and u64 when running TARGET_RISCV64. | ||
5 | |||
6 | Rename it to kvm_riscv_reg_id_ulong() to enhance code readability. It'll | ||
7 | be in line with the existing kvm_riscv_reg_id_<size>() helpers. | ||
8 | |||
9 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
10 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
11 | Message-ID: <20231208183835.2411523-6-dbarboza@ventanamicro.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/kvm/kvm-cpu.c | 40 ++++++++++++++++++++------------------ | ||
15 | 1 file changed, 21 insertions(+), 19 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/kvm/kvm-cpu.c | ||
20 | +++ b/target/riscv/kvm/kvm-cpu.c | ||
21 | @@ -XXX,XX +XXX,XX @@ void riscv_kvm_aplic_request(void *opaque, int irq, int level) | ||
22 | |||
23 | static bool cap_has_mp_state; | ||
24 | |||
25 | -static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type, | ||
26 | +static uint64_t kvm_riscv_reg_id_ulong(CPURISCVState *env, uint64_t type, | ||
27 | uint64_t idx) | ||
28 | { | ||
29 | uint64_t id = KVM_REG_RISCV | type | idx; | ||
30 | @@ -XXX,XX +XXX,XX @@ static uint64_t kvm_riscv_reg_id_u64(uint64_t type, uint64_t idx) | ||
31 | return KVM_REG_RISCV | KVM_REG_SIZE_U64 | type | idx; | ||
32 | } | ||
33 | |||
34 | -#define RISCV_CORE_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \ | ||
35 | - KVM_REG_RISCV_CORE_REG(name)) | ||
36 | +#define RISCV_CORE_REG(env, name) \ | ||
37 | + kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CORE, \ | ||
38 | + KVM_REG_RISCV_CORE_REG(name)) | ||
39 | |||
40 | -#define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \ | ||
41 | - KVM_REG_RISCV_CSR_REG(name)) | ||
42 | +#define RISCV_CSR_REG(env, name) \ | ||
43 | + kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CSR, \ | ||
44 | + KVM_REG_RISCV_CSR_REG(name)) | ||
45 | |||
46 | #define RISCV_CONFIG_REG(env, name) \ | ||
47 | - kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, \ | ||
48 | - KVM_REG_RISCV_CONFIG_REG(name)) | ||
49 | + kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CONFIG, \ | ||
50 | + KVM_REG_RISCV_CONFIG_REG(name)) | ||
51 | |||
52 | #define RISCV_TIMER_REG(name) kvm_riscv_reg_id_u64(KVM_REG_RISCV_TIMER, \ | ||
53 | KVM_REG_RISCV_TIMER_REG(name)) | ||
54 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, CPUState *cs) | ||
55 | |||
56 | /* If we're here we're going to disable the MISA bit */ | ||
57 | reg = 0; | ||
58 | - id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT, | ||
59 | - misa_cfg->kvm_reg_id); | ||
60 | + id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_ISA_EXT, | ||
61 | + misa_cfg->kvm_reg_id); | ||
62 | ret = kvm_set_one_reg(cs, id, ®); | ||
63 | if (ret != 0) { | ||
64 | /* | ||
65 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs) | ||
66 | continue; | ||
67 | } | ||
68 | |||
69 | - id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT, | ||
70 | - multi_ext_cfg->kvm_reg_id); | ||
71 | + id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_ISA_EXT, | ||
72 | + multi_ext_cfg->kvm_reg_id); | ||
73 | reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg); | ||
74 | ret = kvm_set_one_reg(cs, id, ®); | ||
75 | if (ret != 0) { | ||
76 | @@ -XXX,XX +XXX,XX @@ static int kvm_riscv_get_regs_core(CPUState *cs) | ||
77 | env->pc = reg; | ||
78 | |||
79 | for (i = 1; i < 32; i++) { | ||
80 | - uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i); | ||
81 | + uint64_t id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CORE, i); | ||
82 | ret = kvm_get_one_reg(cs, id, ®); | ||
83 | if (ret) { | ||
84 | return ret; | ||
85 | @@ -XXX,XX +XXX,XX @@ static int kvm_riscv_put_regs_core(CPUState *cs) | ||
86 | } | ||
87 | |||
88 | for (i = 1; i < 32; i++) { | ||
89 | - uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i); | ||
90 | + uint64_t id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CORE, i); | ||
91 | reg = env->gpr[i]; | ||
92 | ret = kvm_set_one_reg(cs, id, ®); | ||
93 | if (ret) { | ||
94 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_read_cbomz_blksize(RISCVCPU *cpu, KVMScratchCPU *kvmcpu, | ||
95 | struct kvm_one_reg reg; | ||
96 | int ret; | ||
97 | |||
98 | - reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, | ||
99 | - cbomz_cfg->kvm_reg_id); | ||
100 | + reg.id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_CONFIG, | ||
101 | + cbomz_cfg->kvm_reg_id); | ||
102 | reg.addr = (uint64_t)kvmconfig_get_cfg_addr(cpu, cbomz_cfg); | ||
103 | ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); | ||
104 | if (ret != 0) { | ||
105 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_read_multiext_legacy(RISCVCPU *cpu, | ||
106 | KVMCPUConfig *multi_ext_cfg = &kvm_multi_ext_cfgs[i]; | ||
107 | struct kvm_one_reg reg; | ||
108 | |||
109 | - reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT, | ||
110 | - multi_ext_cfg->kvm_reg_id); | ||
111 | + reg.id = kvm_riscv_reg_id_ulong(env, KVM_REG_RISCV_ISA_EXT, | ||
112 | + multi_ext_cfg->kvm_reg_id); | ||
113 | reg.addr = (uint64_t)&val; | ||
114 | ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); | ||
115 | if (ret != 0) { | ||
116 | @@ -XXX,XX +XXX,XX @@ static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu) | ||
117 | |||
118 | for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) { | ||
119 | multi_ext_cfg = &kvm_multi_ext_cfgs[i]; | ||
120 | - reg_id = kvm_riscv_reg_id(&cpu->env, KVM_REG_RISCV_ISA_EXT, | ||
121 | - multi_ext_cfg->kvm_reg_id); | ||
122 | + reg_id = kvm_riscv_reg_id_ulong(&cpu->env, KVM_REG_RISCV_ISA_EXT, | ||
123 | + multi_ext_cfg->kvm_reg_id); | ||
124 | reg_search = bsearch(®_id, reglist->reg, reglist->n, | ||
125 | sizeof(uint64_t), uint64_cmp); | ||
126 | if (!reg_search) { | ||
127 | -- | ||
128 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | With common function to add virtio in DSDT created now, update microvm | ||
4 | code also to use it instead of duplicate code. | ||
5 | |||
6 | Suggested-by: Andrew Jones <ajones@ventanamicro.com> | ||
7 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
10 | Message-ID: <20231218150247.466427-4-sunilvl@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | hw/i386/acpi-microvm.c | 15 ++------------- | ||
14 | 1 file changed, 2 insertions(+), 13 deletions(-) | ||
15 | |||
16 | diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/hw/i386/acpi-microvm.c | ||
19 | +++ b/hw/i386/acpi-microvm.c | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | #include "hw/pci/pci.h" | ||
22 | #include "hw/pci/pcie_host.h" | ||
23 | #include "hw/usb/xhci.h" | ||
24 | +#include "hw/virtio/virtio-acpi.h" | ||
25 | #include "hw/virtio/virtio-mmio.h" | ||
26 | #include "hw/input/i8042.h" | ||
27 | |||
28 | @@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_virtio(Aml *scope, | ||
29 | uint32_t irq = mms->virtio_irq_base + index; | ||
30 | hwaddr base = VIRTIO_MMIO_BASE + index * 512; | ||
31 | hwaddr size = 512; | ||
32 | - | ||
33 | - Aml *dev = aml_device("VR%02u", (unsigned)index); | ||
34 | - aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005"))); | ||
35 | - aml_append(dev, aml_name_decl("_UID", aml_int(index))); | ||
36 | - aml_append(dev, aml_name_decl("_CCA", aml_int(1))); | ||
37 | - | ||
38 | - Aml *crs = aml_resource_template(); | ||
39 | - aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE)); | ||
40 | - aml_append(crs, | ||
41 | - aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, | ||
42 | - AML_EXCLUSIVE, &irq, 1)); | ||
43 | - aml_append(dev, aml_name_decl("_CRS", crs)); | ||
44 | - aml_append(scope, dev); | ||
45 | + virtio_acpi_dsdt_add(scope, base, size, irq, index, 1); | ||
46 | } | ||
47 | } | ||
48 | } | ||
49 | -- | ||
50 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | Update the RINTC structure in MADT with AIA related fields. | ||
4 | |||
5 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
6 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
7 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
9 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
10 | Message-ID: <20231218150247.466427-6-sunilvl@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | hw/riscv/virt-acpi-build.c | 43 ++++++++++++++++++++++++++++++++++---- | ||
14 | 1 file changed, 39 insertions(+), 4 deletions(-) | ||
15 | |||
16 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | ||
17 | index XXXXXXX..XXXXXXX 100644 | ||
18 | --- a/hw/riscv/virt-acpi-build.c | ||
19 | +++ b/hw/riscv/virt-acpi-build.c | ||
20 | @@ -XXX,XX +XXX,XX @@ | ||
21 | #include "hw/intc/riscv_aclint.h" | ||
22 | |||
23 | #define ACPI_BUILD_TABLE_SIZE 0x20000 | ||
24 | +#define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index)) | ||
25 | |||
26 | typedef struct AcpiBuildState { | ||
27 | /* Copy of table in RAM (for patching) */ | ||
28 | @@ -XXX,XX +XXX,XX @@ static void acpi_align_size(GArray *blob, unsigned align) | ||
29 | |||
30 | static void riscv_acpi_madt_add_rintc(uint32_t uid, | ||
31 | const CPUArchIdList *arch_ids, | ||
32 | - GArray *entry) | ||
33 | + GArray *entry, | ||
34 | + RISCVVirtState *s) | ||
35 | { | ||
36 | + uint8_t guest_index_bits = imsic_num_bits(s->aia_guests + 1); | ||
37 | uint64_t hart_id = arch_ids->cpus[uid].arch_id; | ||
38 | + uint32_t imsic_size, local_cpu_id, socket_id; | ||
39 | + uint64_t imsic_socket_addr, imsic_addr; | ||
40 | + MachineState *ms = MACHINE(s); | ||
41 | |||
42 | + socket_id = arch_ids->cpus[uid].props.node_id; | ||
43 | + local_cpu_id = (arch_ids->cpus[uid].arch_id - | ||
44 | + riscv_socket_first_hartid(ms, socket_id)) % | ||
45 | + riscv_socket_hart_count(ms, socket_id); | ||
46 | + imsic_socket_addr = s->memmap[VIRT_IMSIC_S].base + | ||
47 | + (socket_id * VIRT_IMSIC_GROUP_MAX_SIZE); | ||
48 | + imsic_size = IMSIC_HART_SIZE(guest_index_bits); | ||
49 | + imsic_addr = imsic_socket_addr + local_cpu_id * imsic_size; | ||
50 | build_append_int_noprefix(entry, 0x18, 1); /* Type */ | ||
51 | - build_append_int_noprefix(entry, 20, 1); /* Length */ | ||
52 | + build_append_int_noprefix(entry, 36, 1); /* Length */ | ||
53 | build_append_int_noprefix(entry, 1, 1); /* Version */ | ||
54 | build_append_int_noprefix(entry, 0, 1); /* Reserved */ | ||
55 | build_append_int_noprefix(entry, 0x1, 4); /* Flags */ | ||
56 | build_append_int_noprefix(entry, hart_id, 8); /* Hart ID */ | ||
57 | build_append_int_noprefix(entry, uid, 4); /* ACPI Processor UID */ | ||
58 | + /* External Interrupt Controller ID */ | ||
59 | + if (s->aia_type == VIRT_AIA_TYPE_APLIC) { | ||
60 | + build_append_int_noprefix(entry, | ||
61 | + ACPI_BUILD_INTC_ID( | ||
62 | + arch_ids->cpus[uid].props.node_id, | ||
63 | + local_cpu_id), | ||
64 | + 4); | ||
65 | + } else { | ||
66 | + build_append_int_noprefix(entry, 0, 4); | ||
67 | + } | ||
68 | + | ||
69 | + if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { | ||
70 | + /* IMSIC Base address */ | ||
71 | + build_append_int_noprefix(entry, imsic_addr, 8); | ||
72 | + /* IMSIC Size */ | ||
73 | + build_append_int_noprefix(entry, imsic_size, 4); | ||
74 | + } else { | ||
75 | + build_append_int_noprefix(entry, 0, 8); | ||
76 | + build_append_int_noprefix(entry, 0, 4); | ||
77 | + } | ||
78 | } | ||
79 | |||
80 | static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s) | ||
81 | @@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s) | ||
82 | aml_int(arch_ids->cpus[i].arch_id))); | ||
83 | |||
84 | /* build _MAT object */ | ||
85 | - riscv_acpi_madt_add_rintc(i, arch_ids, madt_buf); | ||
86 | + riscv_acpi_madt_add_rintc(i, arch_ids, madt_buf, s); | ||
87 | aml_append(dev, aml_name_decl("_MAT", | ||
88 | aml_buffer(madt_buf->len, | ||
89 | (uint8_t *)madt_buf->data))); | ||
90 | @@ -XXX,XX +XXX,XX @@ static void build_dsdt(GArray *table_data, | ||
91 | * 5.2.12 Multiple APIC Description Table (MADT) | ||
92 | * REF: https://github.com/riscv-non-isa/riscv-acpi/issues/15 | ||
93 | * https://drive.google.com/file/d/1R6k4MshhN3WTT-hwqAquu5nX6xSEqK2l/view | ||
94 | + * https://drive.google.com/file/d/1oMGPyOD58JaPgMl1pKasT-VKsIKia7zR/view | ||
95 | */ | ||
96 | static void build_madt(GArray *table_data, | ||
97 | BIOSLinker *linker, | ||
98 | @@ -XXX,XX +XXX,XX @@ static void build_madt(GArray *table_data, | ||
99 | |||
100 | /* RISC-V Local INTC structures per HART */ | ||
101 | for (int i = 0; i < arch_ids->len; i++) { | ||
102 | - riscv_acpi_madt_add_rintc(i, arch_ids, table_data); | ||
103 | + riscv_acpi_madt_add_rintc(i, arch_ids, table_data, s); | ||
104 | } | ||
105 | |||
106 | acpi_table_end(linker, &table); | ||
107 | -- | ||
108 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | Add APLIC structures for each socket in the MADT when system is configured | ||
4 | with APLIC as the external wired interrupt controller. | ||
5 | |||
6 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
9 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
11 | Message-ID: <20231218150247.466427-8-sunilvl@ventanamicro.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | hw/riscv/virt-acpi-build.c | 34 ++++++++++++++++++++++++++++++++++ | ||
15 | 1 file changed, 34 insertions(+) | ||
16 | |||
17 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/riscv/virt-acpi-build.c | ||
20 | +++ b/hw/riscv/virt-acpi-build.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static void build_madt(GArray *table_data, | ||
22 | uint8_t guest_index_bits = imsic_num_bits(s->aia_guests + 1); | ||
23 | uint16_t imsic_max_hart_per_socket = 0; | ||
24 | uint8_t hart_index_bits; | ||
25 | + uint64_t aplic_addr; | ||
26 | + uint32_t gsi_base; | ||
27 | uint8_t socket; | ||
28 | |||
29 | for (socket = 0; socket < riscv_socket_count(ms); socket++) { | ||
30 | @@ -XXX,XX +XXX,XX @@ static void build_madt(GArray *table_data, | ||
31 | build_append_int_noprefix(table_data, IMSIC_MMIO_GROUP_MIN_SHIFT, 1); | ||
32 | } | ||
33 | |||
34 | + if (s->aia_type != VIRT_AIA_TYPE_NONE) { | ||
35 | + /* APLICs */ | ||
36 | + for (socket = 0; socket < riscv_socket_count(ms); socket++) { | ||
37 | + aplic_addr = s->memmap[VIRT_APLIC_S].base + | ||
38 | + s->memmap[VIRT_APLIC_S].size * socket; | ||
39 | + gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket; | ||
40 | + build_append_int_noprefix(table_data, 0x1A, 1); /* Type */ | ||
41 | + build_append_int_noprefix(table_data, 36, 1); /* Length */ | ||
42 | + build_append_int_noprefix(table_data, 1, 1); /* Version */ | ||
43 | + build_append_int_noprefix(table_data, socket, 1); /* APLIC ID */ | ||
44 | + build_append_int_noprefix(table_data, 0, 4); /* Flags */ | ||
45 | + build_append_int_noprefix(table_data, 0, 8); /* Hardware ID */ | ||
46 | + /* Number of IDCs */ | ||
47 | + if (s->aia_type == VIRT_AIA_TYPE_APLIC) { | ||
48 | + build_append_int_noprefix(table_data, | ||
49 | + s->soc[socket].num_harts, | ||
50 | + 2); | ||
51 | + } else { | ||
52 | + build_append_int_noprefix(table_data, 0, 2); | ||
53 | + } | ||
54 | + /* Total External Interrupt Sources Supported */ | ||
55 | + build_append_int_noprefix(table_data, VIRT_IRQCHIP_NUM_SOURCES, 2); | ||
56 | + /* Global System Interrupt Base */ | ||
57 | + build_append_int_noprefix(table_data, gsi_base, 4); | ||
58 | + /* APLIC Address */ | ||
59 | + build_append_int_noprefix(table_data, aplic_addr, 8); | ||
60 | + /* APLIC size */ | ||
61 | + build_append_int_noprefix(table_data, | ||
62 | + s->memmap[VIRT_APLIC_S].size, 4); | ||
63 | + } | ||
64 | + } | ||
65 | + | ||
66 | acpi_table_end(linker, &table); | ||
67 | } | ||
68 | |||
69 | -- | ||
70 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | When CMO related extensions like Zicboz, Zicbom and Zicbop are enabled, the | ||
4 | block size for those extensions need to be communicated via CMO node in | ||
5 | RHCT. Add CMO node in RHCT if any of those CMO extensions are detected. | ||
6 | |||
7 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
9 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
10 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
12 | Message-ID: <20231218150247.466427-9-sunilvl@ventanamicro.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | hw/riscv/virt-acpi-build.c | 64 +++++++++++++++++++++++++++++++++----- | ||
16 | 1 file changed, 56 insertions(+), 8 deletions(-) | ||
17 | |||
18 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/hw/riscv/virt-acpi-build.c | ||
21 | +++ b/hw/riscv/virt-acpi-build.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s) | ||
23 | * 5.2.36 RISC-V Hart Capabilities Table (RHCT) | ||
24 | * REF: https://github.com/riscv-non-isa/riscv-acpi/issues/16 | ||
25 | * https://drive.google.com/file/d/1nP3nFiH4jkPMp6COOxP6123DCZKR-tia/view | ||
26 | + * https://drive.google.com/file/d/1sKbOa8m1UZw1JkquZYe3F1zQBN1xXsaf/view | ||
27 | */ | ||
28 | static void build_rhct(GArray *table_data, | ||
29 | BIOSLinker *linker, | ||
30 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
31 | MachineState *ms = MACHINE(s); | ||
32 | const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms); | ||
33 | size_t len, aligned_len; | ||
34 | - uint32_t isa_offset, num_rhct_nodes; | ||
35 | - RISCVCPU *cpu; | ||
36 | + uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0; | ||
37 | + RISCVCPU *cpu = &s->soc[0].harts[0]; | ||
38 | char *isa; | ||
39 | |||
40 | AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id, | ||
41 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
42 | |||
43 | /* ISA + N hart info */ | ||
44 | num_rhct_nodes = 1 + ms->smp.cpus; | ||
45 | + if (cpu->cfg.ext_zicbom || cpu->cfg.ext_zicboz) { | ||
46 | + num_rhct_nodes++; | ||
47 | + } | ||
48 | |||
49 | /* Number of RHCT nodes*/ | ||
50 | build_append_int_noprefix(table_data, num_rhct_nodes, 4); | ||
51 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
52 | isa_offset = table_data->len - table.table_offset; | ||
53 | build_append_int_noprefix(table_data, 0, 2); /* Type 0 */ | ||
54 | |||
55 | - cpu = &s->soc[0].harts[0]; | ||
56 | isa = riscv_isa_string(cpu); | ||
57 | len = 8 + strlen(isa) + 1; | ||
58 | aligned_len = (len % 2) ? (len + 1) : len; | ||
59 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
60 | build_append_int_noprefix(table_data, 0x0, 1); /* Optional Padding */ | ||
61 | } | ||
62 | |||
63 | + /* CMO node */ | ||
64 | + if (cpu->cfg.ext_zicbom || cpu->cfg.ext_zicboz) { | ||
65 | + cmo_offset = table_data->len - table.table_offset; | ||
66 | + build_append_int_noprefix(table_data, 1, 2); /* Type */ | ||
67 | + build_append_int_noprefix(table_data, 10, 2); /* Length */ | ||
68 | + build_append_int_noprefix(table_data, 0x1, 2); /* Revision */ | ||
69 | + build_append_int_noprefix(table_data, 0, 1); /* Reserved */ | ||
70 | + | ||
71 | + /* CBOM block size */ | ||
72 | + if (cpu->cfg.cbom_blocksize) { | ||
73 | + build_append_int_noprefix(table_data, | ||
74 | + __builtin_ctz(cpu->cfg.cbom_blocksize), | ||
75 | + 1); | ||
76 | + } else { | ||
77 | + build_append_int_noprefix(table_data, 0, 1); | ||
78 | + } | ||
79 | + | ||
80 | + /* CBOP block size */ | ||
81 | + build_append_int_noprefix(table_data, 0, 1); | ||
82 | + | ||
83 | + /* CBOZ block size */ | ||
84 | + if (cpu->cfg.cboz_blocksize) { | ||
85 | + build_append_int_noprefix(table_data, | ||
86 | + __builtin_ctz(cpu->cfg.cboz_blocksize), | ||
87 | + 1); | ||
88 | + } else { | ||
89 | + build_append_int_noprefix(table_data, 0, 1); | ||
90 | + } | ||
91 | + } | ||
92 | + | ||
93 | /* Hart Info Node */ | ||
94 | for (int i = 0; i < arch_ids->len; i++) { | ||
95 | + len = 16; | ||
96 | + int num_offsets = 1; | ||
97 | build_append_int_noprefix(table_data, 0xFFFF, 2); /* Type */ | ||
98 | - build_append_int_noprefix(table_data, 16, 2); /* Length */ | ||
99 | - build_append_int_noprefix(table_data, 0x1, 2); /* Revision */ | ||
100 | - build_append_int_noprefix(table_data, 1, 2); /* Number of offsets */ | ||
101 | - build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ | ||
102 | - build_append_int_noprefix(table_data, isa_offset, 4); /* Offsets[0] */ | ||
103 | + | ||
104 | + /* Length */ | ||
105 | + if (cmo_offset) { | ||
106 | + len += 4; | ||
107 | + num_offsets++; | ||
108 | + } | ||
109 | + | ||
110 | + build_append_int_noprefix(table_data, len, 2); | ||
111 | + build_append_int_noprefix(table_data, 0x1, 2); /* Revision */ | ||
112 | + /* Number of offsets */ | ||
113 | + build_append_int_noprefix(table_data, num_offsets, 2); | ||
114 | + build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ | ||
115 | + | ||
116 | + /* Offsets */ | ||
117 | + build_append_int_noprefix(table_data, isa_offset, 4); | ||
118 | + if (cmo_offset) { | ||
119 | + build_append_int_noprefix(table_data, cmo_offset, 4); | ||
120 | + } | ||
121 | } | ||
122 | |||
123 | acpi_table_end(linker, &table); | ||
124 | -- | ||
125 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | MMU type information is available via MMU node in RHCT. Add this node in | ||
4 | RHCT. | ||
5 | |||
6 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
9 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
11 | Message-ID: <20231218150247.466427-10-sunilvl@ventanamicro.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | hw/riscv/virt-acpi-build.c | 36 +++++++++++++++++++++++++++++++++++- | ||
15 | 1 file changed, 35 insertions(+), 1 deletion(-) | ||
16 | |||
17 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/riscv/virt-acpi-build.c | ||
20 | +++ b/hw/riscv/virt-acpi-build.c | ||
21 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
22 | size_t len, aligned_len; | ||
23 | uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0; | ||
24 | RISCVCPU *cpu = &s->soc[0].harts[0]; | ||
25 | + uint32_t mmu_offset = 0; | ||
26 | + uint8_t satp_mode_max; | ||
27 | char *isa; | ||
28 | |||
29 | AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id, | ||
30 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
31 | num_rhct_nodes++; | ||
32 | } | ||
33 | |||
34 | + if (cpu->cfg.satp_mode.supported != 0) { | ||
35 | + num_rhct_nodes++; | ||
36 | + } | ||
37 | + | ||
38 | /* Number of RHCT nodes*/ | ||
39 | build_append_int_noprefix(table_data, num_rhct_nodes, 4); | ||
40 | |||
41 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
42 | } | ||
43 | } | ||
44 | |||
45 | + /* MMU node structure */ | ||
46 | + if (cpu->cfg.satp_mode.supported != 0) { | ||
47 | + satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map); | ||
48 | + mmu_offset = table_data->len - table.table_offset; | ||
49 | + build_append_int_noprefix(table_data, 2, 2); /* Type */ | ||
50 | + build_append_int_noprefix(table_data, 8, 2); /* Length */ | ||
51 | + build_append_int_noprefix(table_data, 0x1, 2); /* Revision */ | ||
52 | + build_append_int_noprefix(table_data, 0, 1); /* Reserved */ | ||
53 | + /* MMU Type */ | ||
54 | + if (satp_mode_max == VM_1_10_SV57) { | ||
55 | + build_append_int_noprefix(table_data, 2, 1); /* Sv57 */ | ||
56 | + } else if (satp_mode_max == VM_1_10_SV48) { | ||
57 | + build_append_int_noprefix(table_data, 1, 1); /* Sv48 */ | ||
58 | + } else if (satp_mode_max == VM_1_10_SV39) { | ||
59 | + build_append_int_noprefix(table_data, 0, 1); /* Sv39 */ | ||
60 | + } else { | ||
61 | + assert(1); | ||
62 | + } | ||
63 | + } | ||
64 | + | ||
65 | /* Hart Info Node */ | ||
66 | for (int i = 0; i < arch_ids->len; i++) { | ||
67 | len = 16; | ||
68 | @@ -XXX,XX +XXX,XX @@ static void build_rhct(GArray *table_data, | ||
69 | num_offsets++; | ||
70 | } | ||
71 | |||
72 | + if (mmu_offset) { | ||
73 | + len += 4; | ||
74 | + num_offsets++; | ||
75 | + } | ||
76 | + | ||
77 | build_append_int_noprefix(table_data, len, 2); | ||
78 | build_append_int_noprefix(table_data, 0x1, 2); /* Revision */ | ||
79 | /* Number of offsets */ | ||
80 | build_append_int_noprefix(table_data, num_offsets, 2); | ||
81 | build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */ | ||
82 | - | ||
83 | /* Offsets */ | ||
84 | build_append_int_noprefix(table_data, isa_offset, 4); | ||
85 | if (cmo_offset) { | ||
86 | build_append_int_noprefix(table_data, cmo_offset, 4); | ||
87 | } | ||
88 | + | ||
89 | + if (mmu_offset) { | ||
90 | + build_append_int_noprefix(table_data, mmu_offset, 4); | ||
91 | + } | ||
92 | } | ||
93 | |||
94 | acpi_table_end(linker, &table); | ||
95 | -- | ||
96 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | ACPI DSDT generator needs information like ECAM range, PIO range, 32-bit | ||
4 | and 64-bit PCI MMIO range etc related to the PCI host bridge. Instead of | ||
5 | making these values machine specific, create properties for the GPEX | ||
6 | host bridge with default value 0. During initialization, the firmware | ||
7 | can initialize these properties with correct values for the platform. | ||
8 | This basically allows DSDT generator code independent of the machine | ||
9 | specific memory map accesses. | ||
10 | |||
11 | Suggested-by: Igor Mammedov <imammedo@redhat.com> | ||
12 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
13 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
15 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
16 | Message-ID: <20231218150247.466427-11-sunilvl@ventanamicro.com> | ||
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | --- | ||
19 | include/hw/pci-host/gpex.h | 28 ++++++++++++++++++++-------- | ||
20 | hw/pci-host/gpex-acpi.c | 13 +++++++++++++ | ||
21 | hw/pci-host/gpex.c | 12 ++++++++++++ | ||
22 | 3 files changed, 45 insertions(+), 8 deletions(-) | ||
23 | |||
24 | diff --git a/include/hw/pci-host/gpex.h b/include/hw/pci-host/gpex.h | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/include/hw/pci-host/gpex.h | ||
27 | +++ b/include/hw/pci-host/gpex.h | ||
28 | @@ -XXX,XX +XXX,XX @@ struct GPEXRootState { | ||
29 | /*< public >*/ | ||
30 | }; | ||
31 | |||
32 | +struct GPEXConfig { | ||
33 | + MemMapEntry ecam; | ||
34 | + MemMapEntry mmio32; | ||
35 | + MemMapEntry mmio64; | ||
36 | + MemMapEntry pio; | ||
37 | + int irq; | ||
38 | + PCIBus *bus; | ||
39 | +}; | ||
40 | + | ||
41 | struct GPEXHost { | ||
42 | /*< private >*/ | ||
43 | PCIExpressHost parent_obj; | ||
44 | @@ -XXX,XX +XXX,XX @@ struct GPEXHost { | ||
45 | int irq_num[GPEX_NUM_IRQS]; | ||
46 | |||
47 | bool allow_unmapped_accesses; | ||
48 | -}; | ||
49 | |||
50 | -struct GPEXConfig { | ||
51 | - MemMapEntry ecam; | ||
52 | - MemMapEntry mmio32; | ||
53 | - MemMapEntry mmio64; | ||
54 | - MemMapEntry pio; | ||
55 | - int irq; | ||
56 | - PCIBus *bus; | ||
57 | + struct GPEXConfig gpex_cfg; | ||
58 | }; | ||
59 | |||
60 | int gpex_set_irq_num(GPEXHost *s, int index, int gsi); | ||
61 | |||
62 | void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg); | ||
63 | +void acpi_dsdt_add_gpex_host(Aml *scope, uint32_t irq); | ||
64 | + | ||
65 | +#define PCI_HOST_PIO_BASE "x-pio-base" | ||
66 | +#define PCI_HOST_PIO_SIZE "x-pio-size" | ||
67 | +#define PCI_HOST_ECAM_BASE "x-ecam-base" | ||
68 | +#define PCI_HOST_ECAM_SIZE "x-ecam-size" | ||
69 | +#define PCI_HOST_BELOW_4G_MMIO_BASE "x-below-4g-mmio-base" | ||
70 | +#define PCI_HOST_BELOW_4G_MMIO_SIZE "x-below-4g-mmio-size" | ||
71 | +#define PCI_HOST_ABOVE_4G_MMIO_BASE "x-above-4g-mmio-base" | ||
72 | +#define PCI_HOST_ABOVE_4G_MMIO_SIZE "x-above-4g-mmio-size" | ||
73 | |||
74 | #endif /* HW_GPEX_H */ | ||
75 | diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c | ||
76 | index XXXXXXX..XXXXXXX 100644 | ||
77 | --- a/hw/pci-host/gpex-acpi.c | ||
78 | +++ b/hw/pci-host/gpex-acpi.c | ||
79 | @@ -XXX,XX +XXX,XX @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg) | ||
80 | |||
81 | crs_range_set_free(&crs_range_set); | ||
82 | } | ||
83 | + | ||
84 | +void acpi_dsdt_add_gpex_host(Aml *scope, uint32_t irq) | ||
85 | +{ | ||
86 | + bool ambig; | ||
87 | + Object *obj = object_resolve_path_type("", TYPE_GPEX_HOST, &ambig); | ||
88 | + | ||
89 | + if (!obj || ambig) { | ||
90 | + return; | ||
91 | + } | ||
92 | + | ||
93 | + GPEX_HOST(obj)->gpex_cfg.irq = irq; | ||
94 | + acpi_dsdt_add_gpex(scope, &GPEX_HOST(obj)->gpex_cfg); | ||
95 | +} | ||
96 | diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c | ||
97 | index XXXXXXX..XXXXXXX 100644 | ||
98 | --- a/hw/pci-host/gpex.c | ||
99 | +++ b/hw/pci-host/gpex.c | ||
100 | @@ -XXX,XX +XXX,XX @@ static Property gpex_host_properties[] = { | ||
101 | */ | ||
102 | DEFINE_PROP_BOOL("allow-unmapped-accesses", GPEXHost, | ||
103 | allow_unmapped_accesses, true), | ||
104 | + DEFINE_PROP_UINT64(PCI_HOST_ECAM_BASE, GPEXHost, gpex_cfg.ecam.base, 0), | ||
105 | + DEFINE_PROP_SIZE(PCI_HOST_ECAM_SIZE, GPEXHost, gpex_cfg.ecam.size, 0), | ||
106 | + DEFINE_PROP_UINT64(PCI_HOST_PIO_BASE, GPEXHost, gpex_cfg.pio.base, 0), | ||
107 | + DEFINE_PROP_SIZE(PCI_HOST_PIO_SIZE, GPEXHost, gpex_cfg.pio.size, 0), | ||
108 | + DEFINE_PROP_UINT64(PCI_HOST_BELOW_4G_MMIO_BASE, GPEXHost, | ||
109 | + gpex_cfg.mmio32.base, 0), | ||
110 | + DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MMIO_SIZE, GPEXHost, | ||
111 | + gpex_cfg.mmio32.size, 0), | ||
112 | + DEFINE_PROP_UINT64(PCI_HOST_ABOVE_4G_MMIO_BASE, GPEXHost, | ||
113 | + gpex_cfg.mmio64.base, 0), | ||
114 | + DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MMIO_SIZE, GPEXHost, | ||
115 | + gpex_cfg.mmio64.size, 0), | ||
116 | DEFINE_PROP_END_OF_LIST(), | ||
117 | }; | ||
118 | |||
119 | -- | ||
120 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | Add basic IO controllers and devices like PCI, VirtIO and UART in the | ||
4 | ACPI namespace. | ||
5 | |||
6 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
7 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
10 | Message-ID: <20231218150247.466427-13-sunilvl@ventanamicro.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | --- | ||
13 | hw/riscv/virt-acpi-build.c | 79 ++++++++++++++++++++++++++++++++++++-- | ||
14 | hw/riscv/Kconfig | 1 + | ||
15 | 2 files changed, 76 insertions(+), 4 deletions(-) | ||
16 | |||
17 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/hw/riscv/virt-acpi-build.c | ||
20 | +++ b/hw/riscv/virt-acpi-build.c | ||
21 | @@ -XXX,XX +XXX,XX @@ | ||
22 | #include "hw/acpi/acpi-defs.h" | ||
23 | #include "hw/acpi/acpi.h" | ||
24 | #include "hw/acpi/aml-build.h" | ||
25 | +#include "hw/acpi/pci.h" | ||
26 | #include "hw/acpi/utils.h" | ||
27 | +#include "hw/intc/riscv_aclint.h" | ||
28 | #include "hw/nvram/fw_cfg_acpi.h" | ||
29 | +#include "hw/pci-host/gpex.h" | ||
30 | +#include "hw/riscv/virt.h" | ||
31 | +#include "hw/riscv/numa.h" | ||
32 | +#include "hw/virtio/virtio-acpi.h" | ||
33 | +#include "migration/vmstate.h" | ||
34 | #include "qapi/error.h" | ||
35 | #include "qemu/error-report.h" | ||
36 | #include "sysemu/reset.h" | ||
37 | -#include "migration/vmstate.h" | ||
38 | -#include "hw/riscv/virt.h" | ||
39 | -#include "hw/riscv/numa.h" | ||
40 | -#include "hw/intc/riscv_aclint.h" | ||
41 | |||
42 | #define ACPI_BUILD_TABLE_SIZE 0x20000 | ||
43 | #define ACPI_BUILD_INTC_ID(socket, index) ((socket << 24) | (index)) | ||
44 | @@ -XXX,XX +XXX,XX @@ static void acpi_dsdt_add_cpus(Aml *scope, RISCVVirtState *s) | ||
45 | } | ||
46 | } | ||
47 | |||
48 | +static void | ||
49 | +acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, | ||
50 | + uint32_t uart_irq) | ||
51 | +{ | ||
52 | + Aml *dev = aml_device("COM0"); | ||
53 | + aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501"))); | ||
54 | + aml_append(dev, aml_name_decl("_UID", aml_int(0))); | ||
55 | + | ||
56 | + Aml *crs = aml_resource_template(); | ||
57 | + aml_append(crs, aml_memory32_fixed(uart_memmap->base, | ||
58 | + uart_memmap->size, AML_READ_WRITE)); | ||
59 | + aml_append(crs, | ||
60 | + aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, | ||
61 | + AML_EXCLUSIVE, &uart_irq, 1)); | ||
62 | + aml_append(dev, aml_name_decl("_CRS", crs)); | ||
63 | + | ||
64 | + Aml *pkg = aml_package(2); | ||
65 | + aml_append(pkg, aml_string("clock-frequency")); | ||
66 | + aml_append(pkg, aml_int(3686400)); | ||
67 | + | ||
68 | + Aml *UUID = aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"); | ||
69 | + | ||
70 | + Aml *pkg1 = aml_package(1); | ||
71 | + aml_append(pkg1, pkg); | ||
72 | + | ||
73 | + Aml *package = aml_package(2); | ||
74 | + aml_append(package, UUID); | ||
75 | + aml_append(package, pkg1); | ||
76 | + | ||
77 | + aml_append(dev, aml_name_decl("_DSD", package)); | ||
78 | + aml_append(scope, dev); | ||
79 | +} | ||
80 | + | ||
81 | /* RHCT Node[N] starts at offset 56 */ | ||
82 | #define RHCT_NODE_ARRAY_OFFSET 56 | ||
83 | |||
84 | @@ -XXX,XX +XXX,XX @@ static void build_dsdt(GArray *table_data, | ||
85 | RISCVVirtState *s) | ||
86 | { | ||
87 | Aml *scope, *dsdt; | ||
88 | + MachineState *ms = MACHINE(s); | ||
89 | + uint8_t socket_count; | ||
90 | const MemMapEntry *memmap = s->memmap; | ||
91 | AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = s->oem_id, | ||
92 | .oem_table_id = s->oem_table_id }; | ||
93 | @@ -XXX,XX +XXX,XX @@ static void build_dsdt(GArray *table_data, | ||
94 | |||
95 | fw_cfg_acpi_dsdt_add(scope, &memmap[VIRT_FW_CFG]); | ||
96 | |||
97 | + socket_count = riscv_socket_count(ms); | ||
98 | + | ||
99 | + acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ); | ||
100 | + | ||
101 | + if (socket_count == 1) { | ||
102 | + virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, | ||
103 | + memmap[VIRT_VIRTIO].size, | ||
104 | + VIRTIO_IRQ, 0, VIRTIO_COUNT); | ||
105 | + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ); | ||
106 | + } else if (socket_count == 2) { | ||
107 | + virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, | ||
108 | + memmap[VIRT_VIRTIO].size, | ||
109 | + VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0, | ||
110 | + VIRTIO_COUNT); | ||
111 | + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES); | ||
112 | + } else { | ||
113 | + virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, | ||
114 | + memmap[VIRT_VIRTIO].size, | ||
115 | + VIRTIO_IRQ + VIRT_IRQCHIP_NUM_SOURCES, 0, | ||
116 | + VIRTIO_COUNT); | ||
117 | + acpi_dsdt_add_gpex_host(scope, PCIE_IRQ + VIRT_IRQCHIP_NUM_SOURCES * 2); | ||
118 | + } | ||
119 | + | ||
120 | aml_append(dsdt, scope); | ||
121 | |||
122 | /* copy AML table into ACPI tables blob and patch header there */ | ||
123 | @@ -XXX,XX +XXX,XX @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables) | ||
124 | acpi_add_table(table_offsets, tables_blob); | ||
125 | build_rhct(tables_blob, tables->linker, s); | ||
126 | |||
127 | + acpi_add_table(table_offsets, tables_blob); | ||
128 | + { | ||
129 | + AcpiMcfgInfo mcfg = { | ||
130 | + .base = s->memmap[VIRT_PCIE_MMIO].base, | ||
131 | + .size = s->memmap[VIRT_PCIE_MMIO].size, | ||
132 | + }; | ||
133 | + build_mcfg(tables_blob, tables->linker, &mcfg, s->oem_id, | ||
134 | + s->oem_table_id); | ||
135 | + } | ||
136 | + | ||
137 | /* XSDT is pointed to by RSDP */ | ||
138 | xsdt = tables_blob->len; | ||
139 | build_xsdt(tables_blob, tables->linker, table_offsets, s->oem_id, | ||
140 | diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig | ||
141 | index XXXXXXX..XXXXXXX 100644 | ||
142 | --- a/hw/riscv/Kconfig | ||
143 | +++ b/hw/riscv/Kconfig | ||
144 | @@ -XXX,XX +XXX,XX @@ config RISCV_VIRT | ||
145 | select FW_CFG_DMA | ||
146 | select PLATFORM_BUS | ||
147 | select ACPI | ||
148 | + select ACPI_PCI | ||
149 | |||
150 | config SHAKTI_C | ||
151 | bool | ||
152 | -- | ||
153 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Sunil V L <sunilvl@ventanamicro.com> | ||
2 | 1 | ||
3 | Add PLIC structures for each socket in the MADT when system is | ||
4 | configured with PLIC as the external interrupt controller. | ||
5 | |||
6 | Signed-off-by: Haibo Xu <haibo1.xu@intel.com> | ||
7 | Signed-off-by: Sunil V L <sunilvl@ventanamicro.com> | ||
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
9 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
10 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Acked-by: Michael S. Tsirkin <mst@redhat.com> | ||
12 | Message-ID: <20231218150247.466427-14-sunilvl@ventanamicro.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | hw/riscv/virt-acpi-build.c | 29 +++++++++++++++++++++++++++++ | ||
16 | 1 file changed, 29 insertions(+) | ||
17 | |||
18 | diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/hw/riscv/virt-acpi-build.c | ||
21 | +++ b/hw/riscv/virt-acpi-build.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static void riscv_acpi_madt_add_rintc(uint32_t uid, | ||
23 | arch_ids->cpus[uid].props.node_id, | ||
24 | local_cpu_id), | ||
25 | 4); | ||
26 | + } else if (s->aia_type == VIRT_AIA_TYPE_NONE) { | ||
27 | + build_append_int_noprefix(entry, | ||
28 | + ACPI_BUILD_INTC_ID( | ||
29 | + arch_ids->cpus[uid].props.node_id, | ||
30 | + 2 * local_cpu_id + 1), | ||
31 | + 4); | ||
32 | } else { | ||
33 | build_append_int_noprefix(entry, 0, 4); | ||
34 | } | ||
35 | @@ -XXX,XX +XXX,XX @@ static void build_madt(GArray *table_data, | ||
36 | build_append_int_noprefix(table_data, | ||
37 | s->memmap[VIRT_APLIC_S].size, 4); | ||
38 | } | ||
39 | + } else { | ||
40 | + /* PLICs */ | ||
41 | + for (socket = 0; socket < riscv_socket_count(ms); socket++) { | ||
42 | + aplic_addr = s->memmap[VIRT_PLIC].base + | ||
43 | + s->memmap[VIRT_PLIC].size * socket; | ||
44 | + gsi_base = VIRT_IRQCHIP_NUM_SOURCES * socket; | ||
45 | + build_append_int_noprefix(table_data, 0x1B, 1); /* Type */ | ||
46 | + build_append_int_noprefix(table_data, 36, 1); /* Length */ | ||
47 | + build_append_int_noprefix(table_data, 1, 1); /* Version */ | ||
48 | + build_append_int_noprefix(table_data, socket, 1); /* PLIC ID */ | ||
49 | + build_append_int_noprefix(table_data, 0, 8); /* Hardware ID */ | ||
50 | + /* Total External Interrupt Sources Supported */ | ||
51 | + build_append_int_noprefix(table_data, | ||
52 | + VIRT_IRQCHIP_NUM_SOURCES - 1, 2); | ||
53 | + build_append_int_noprefix(table_data, 0, 2); /* Max Priority */ | ||
54 | + build_append_int_noprefix(table_data, 0, 4); /* Flags */ | ||
55 | + /* PLIC Size */ | ||
56 | + build_append_int_noprefix(table_data, s->memmap[VIRT_PLIC].size, 4); | ||
57 | + /* PLIC Address */ | ||
58 | + build_append_int_noprefix(table_data, aplic_addr, 8); | ||
59 | + /* Global System Interrupt Vector Base */ | ||
60 | + build_append_int_noprefix(table_data, gsi_base, 4); | ||
61 | + } | ||
62 | } | ||
63 | |||
64 | acpi_table_end(linker, &table); | ||
65 | -- | ||
66 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Yong-Xuan Wang <yongxuan.wang@sifive.com> | ||
2 | 1 | ||
3 | The interrupts-extended property of PLIC only has 2 * hart number | ||
4 | fields when KVM enabled, copy 4 * hart number fields to fdt will | ||
5 | expose some uninitialized value. | ||
6 | |||
7 | In this patch, I also refactor the code about the setting of | ||
8 | interrupts-extended property of PLIC for improved readability. | ||
9 | |||
10 | Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com> | ||
11 | Reviewed-by: Jim Shu <jim.shu@sifive.com> | ||
12 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
13 | Message-ID: <20231218090543.22353-1-yongxuan.wang@sifive.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | hw/riscv/virt.c | 47 +++++++++++++++++++++++++++-------------------- | ||
17 | 1 file changed, 27 insertions(+), 20 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 @@ static void create_fdt_socket_plic(RISCVVirtState *s, | ||
24 | "sifive,plic-1.0.0", "riscv,plic0" | ||
25 | }; | ||
26 | |||
27 | - if (kvm_enabled()) { | ||
28 | - plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); | ||
29 | - } else { | ||
30 | - plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4); | ||
31 | - } | ||
32 | - | ||
33 | - for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { | ||
34 | - if (kvm_enabled()) { | ||
35 | - plic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
36 | - plic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT); | ||
37 | - } else { | ||
38 | - plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
39 | - plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT); | ||
40 | - plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]); | ||
41 | - plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT); | ||
42 | - } | ||
43 | - } | ||
44 | - | ||
45 | plic_phandles[socket] = (*phandle)++; | ||
46 | plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket); | ||
47 | plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr); | ||
48 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s, | ||
49 | (char **)&plic_compat, | ||
50 | ARRAY_SIZE(plic_compat)); | ||
51 | qemu_fdt_setprop(ms->fdt, plic_name, "interrupt-controller", NULL, 0); | ||
52 | - qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended", | ||
53 | - plic_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4); | ||
54 | + | ||
55 | + if (kvm_enabled()) { | ||
56 | + plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2); | ||
57 | + | ||
58 | + for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { | ||
59 | + plic_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
60 | + plic_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_S_EXT); | ||
61 | + } | ||
62 | + | ||
63 | + qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended", | ||
64 | + plic_cells, | ||
65 | + s->soc[socket].num_harts * sizeof(uint32_t) * 2); | ||
66 | + } else { | ||
67 | + plic_cells = g_new0(uint32_t, s->soc[socket].num_harts * 4); | ||
68 | + | ||
69 | + for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) { | ||
70 | + plic_cells[cpu * 4 + 0] = cpu_to_be32(intc_phandles[cpu]); | ||
71 | + plic_cells[cpu * 4 + 1] = cpu_to_be32(IRQ_M_EXT); | ||
72 | + plic_cells[cpu * 4 + 2] = cpu_to_be32(intc_phandles[cpu]); | ||
73 | + plic_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_S_EXT); | ||
74 | + } | ||
75 | + | ||
76 | + qemu_fdt_setprop(ms->fdt, plic_name, "interrupts-extended", | ||
77 | + plic_cells, | ||
78 | + s->soc[socket].num_harts * sizeof(uint32_t) * 4); | ||
79 | + } | ||
80 | + | ||
81 | qemu_fdt_setprop_cells(ms->fdt, plic_name, "reg", | ||
82 | 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size); | ||
83 | qemu_fdt_setprop_cell(ms->fdt, plic_name, "riscv,ndev", | ||
84 | -- | ||
85 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> | ||
2 | 1 | ||
3 | Since QEMU v8.0.0 the RISC-V virt machine has a switch to disable ACPI | ||
4 | table generation. Add it to the documentation. | ||
5 | |||
6 | Fixes: 168b8c29cedb ("hw/riscv/virt: Add a switch to disable ACPI") | ||
7 | Signed-off-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com> | ||
8 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
9 | Reviewed-by: Sunil V L <sunilvl@ventanamicro.com> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Message-ID: <20231220193436.25909-1-heinrich.schuchardt@canonical.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | docs/system/riscv/virt.rst | 5 +++++ | ||
15 | 1 file changed, 5 insertions(+) | ||
16 | |||
17 | diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/docs/system/riscv/virt.rst | ||
20 | +++ b/docs/system/riscv/virt.rst | ||
21 | @@ -XXX,XX +XXX,XX @@ The following machine-specific options are supported: | ||
22 | SiFive CLINT. When not specified, this option is assumed to be "off". | ||
23 | This option is restricted to the TCG accelerator. | ||
24 | |||
25 | +- acpi=[on|off|auto] | ||
26 | + | ||
27 | + When this option is "on" (which is the default), ACPI tables are generated and | ||
28 | + exposed as firmware tables etc/acpi/rsdp and etc/acpi/tables. | ||
29 | + | ||
30 | - aia=[none|aplic|aplic-imsic] | ||
31 | |||
32 | This option allows selecting interrupt controller defined by the AIA | ||
33 | -- | ||
34 | 2.43.0 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | We have two instances of the setting/clearing a MISA bit from | 3 | Commit 68c9e54bea handled a situation where a warning was being shown |
4 | env->misa_ext and env->misa_ext_mask pattern. And the next patch will | 4 | when using the 'sifive_e' cpu when disabling the named extension zic64b. |
5 | end up adding one more. | 5 | It makes little sense to show user warnings for named extensions that |
6 | users can't control, and the solution taken was to disable zic64b | ||
7 | manually in riscv_cpu_update_named_features(). | ||
6 | 8 | ||
7 | Create a helper to avoid code repetition. | 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. | ||
8 | 16 | ||
9 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 17 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 18 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
11 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | 19 | Message-ID: <20241113171755.978109-2-dbarboza@ventanamicro.com> |
12 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
13 | Message-ID: <20231218125334.37184-13-dbarboza@ventanamicro.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 20 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
15 | --- | 21 | --- |
16 | target/riscv/tcg/tcg-cpu.c | 32 ++++++++++++++++++-------------- | 22 | target/riscv/tcg/tcg-cpu.c | 13 ++++++++++--- |
17 | 1 file changed, 18 insertions(+), 14 deletions(-) | 23 | 1 file changed, 10 insertions(+), 3 deletions(-) |
18 | 24 | ||
19 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 25 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c |
20 | index XXXXXXX..XXXXXXX 100644 | 26 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/riscv/tcg/tcg-cpu.c | 27 | --- a/target/riscv/tcg/tcg-cpu.c |
22 | +++ b/target/riscv/tcg/tcg-cpu.c | 28 | +++ b/target/riscv/tcg/tcg-cpu.c |
23 | @@ -XXX,XX +XXX,XX @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset) | 29 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_disable_priv_spec_isa_exts(RISCVCPU *cpu) |
24 | GUINT_TO_POINTER(ext_offset)); | 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; | ||
25 | } | 55 | } |
26 | 56 | ||
27 | +static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit, | 57 | static void riscv_cpu_validate_g(RISCVCPU *cpu) |
28 | + bool enabled) | ||
29 | +{ | ||
30 | + CPURISCVState *env = &cpu->env; | ||
31 | + | ||
32 | + if (enabled) { | ||
33 | + env->misa_ext |= bit; | ||
34 | + env->misa_ext_mask |= bit; | ||
35 | + } else { | ||
36 | + env->misa_ext &= ~bit; | ||
37 | + env->misa_ext_mask &= ~bit; | ||
38 | + } | ||
39 | +} | ||
40 | + | ||
41 | static void riscv_cpu_synchronize_from_tb(CPUState *cs, | ||
42 | const TranslationBlock *tb) | ||
43 | { | ||
44 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_misa_ext_cfg(Object *obj, Visitor *v, const char *name, | ||
45 | */ | ||
46 | env->priv_ver = PRIV_VERSION_1_12_0; | ||
47 | } | ||
48 | - | ||
49 | - env->misa_ext |= misa_bit; | ||
50 | - env->misa_ext_mask |= misa_bit; | ||
51 | - } else { | ||
52 | - env->misa_ext &= ~misa_bit; | ||
53 | - env->misa_ext_mask &= ~misa_bit; | ||
54 | } | ||
55 | + | ||
56 | + riscv_cpu_write_misa_bit(cpu, misa_bit, value); | ||
57 | } | ||
58 | |||
59 | static void cpu_get_misa_ext_cfg(Object *obj, Visitor *v, const char *name, | ||
60 | @@ -XXX,XX +XXX,XX @@ static const RISCVCPUMisaExtConfig misa_ext_cfgs[] = { | ||
61 | */ | ||
62 | static void riscv_cpu_add_misa_properties(Object *cpu_obj) | ||
63 | { | ||
64 | - CPURISCVState *env = &RISCV_CPU(cpu_obj)->env; | ||
65 | bool use_def_vals = riscv_cpu_is_generic(cpu_obj); | ||
66 | int i; | ||
67 | |||
68 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_add_misa_properties(Object *cpu_obj) | ||
69 | NULL, (void *)misa_cfg); | ||
70 | object_property_set_description(cpu_obj, name, desc); | ||
71 | if (use_def_vals) { | ||
72 | - if (misa_cfg->enabled) { | ||
73 | - env->misa_ext |= bit; | ||
74 | - env->misa_ext_mask |= bit; | ||
75 | - } else { | ||
76 | - env->misa_ext &= ~bit; | ||
77 | - env->misa_ext_mask &= ~bit; | ||
78 | - } | ||
79 | + riscv_cpu_write_misa_bit(RISCV_CPU(cpu_obj), bit, | ||
80 | + misa_cfg->enabled); | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | -- | 58 | -- |
85 | 2.43.0 | 59 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
---|---|---|---|
2 | 2 | ||
3 | 'svade' is a RVA22S64 profile requirement, a profile we're going to add | 3 | ssstateen is defined in RVA22 as: |
4 | shortly. It is a named feature (i.e. not a formal extension, not defined | ||
5 | in riscv,isa DT at this moment) defined in [1] as: | ||
6 | 4 | ||
7 | "Page-fault exceptions are raised when a page is accessed when A bit is | 5 | "Supervisor-mode view of the state-enable extension. The supervisor-mode |
8 | clear, or written when D bit is clear.". | 6 | (sstateen0-3) and hypervisor-mode (hstateen0-3) state-enable registers |
7 | must be provided." | ||
9 | 8 | ||
10 | As far as the spec goes, 'svade' is one of the two distinct modes of | 9 | Add ssstateen as a named feature that is available if we also have |
11 | handling PTE_A and PTE_D. The other way, i.e. update PTE_A/PTE_D when | 10 | smstateen. |
12 | they're cleared, is defined by the 'svadu' extension. Checking | ||
13 | cpu_helper.c, get_physical_address(), we can verify that QEMU is | ||
14 | compliant with that: we will update PTE_A/PTE_D if 'svadu' is enabled, | ||
15 | or throw a page-fault exception if 'svadu' isn't enabled. | ||
16 | |||
17 | So, as far as we're concerned, 'svade' translates to 'svadu must be | ||
18 | disabled'. | ||
19 | |||
20 | We'll implement it like 'zic64b': an internal flag that profiles can | ||
21 | enable. The flag will not be exposed to users. | ||
22 | |||
23 | [1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc | ||
24 | 11 | ||
25 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 12 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
13 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
26 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | 14 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> |
27 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Message-ID: <20241113171755.978109-3-dbarboza@ventanamicro.com> |
28 | Message-ID: <20231218125334.37184-20-dbarboza@ventanamicro.com> | ||
29 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 16 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
30 | --- | 17 | --- |
31 | target/riscv/cpu_cfg.h | 1 + | 18 | target/riscv/cpu_cfg.h | 1 + |
32 | target/riscv/cpu.c | 1 + | 19 | target/riscv/cpu.c | 2 ++ |
33 | target/riscv/tcg/tcg-cpu.c | 5 +++++ | 20 | target/riscv/tcg/tcg-cpu.c | 9 ++++++++- |
34 | 3 files changed, 7 insertions(+) | 21 | 3 files changed, 11 insertions(+), 1 deletion(-) |
35 | 22 | ||
36 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h | 23 | diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h |
37 | index XXXXXXX..XXXXXXX 100644 | 24 | index XXXXXXX..XXXXXXX 100644 |
38 | --- a/target/riscv/cpu_cfg.h | 25 | --- a/target/riscv/cpu_cfg.h |
39 | +++ b/target/riscv/cpu_cfg.h | 26 | +++ b/target/riscv/cpu_cfg.h |
40 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | 27 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { |
41 | bool ext_smepmp; | 28 | /* Named features */ |
42 | bool rvv_ta_all_1s; | 29 | bool ext_svade; |
43 | bool rvv_ma_all_1s; | 30 | bool ext_zic64b; |
44 | + bool svade; | 31 | + bool ext_ssstateen; |
45 | bool zic64b; | 32 | |
46 | 33 | /* | |
47 | uint32_t mvendorid; | 34 | * Always 'true' booleans for named features |
48 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 35 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
49 | index XXXXXXX..XXXXXXX 100644 | 36 | index XXXXXXX..XXXXXXX 100644 |
50 | --- a/target/riscv/cpu.c | 37 | --- a/target/riscv/cpu.c |
51 | +++ b/target/riscv/cpu.c | 38 | +++ b/target/riscv/cpu.c |
39 | @@ -XXX,XX +XXX,XX @@ const RISCVIsaExtData isa_edata_arr[] = { | ||
40 | ISA_EXT_DATA_ENTRY(ssccptr, PRIV_VERSION_1_11_0, has_priv_1_11), | ||
41 | ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf), | ||
42 | ISA_EXT_DATA_ENTRY(sscounterenw, PRIV_VERSION_1_12_0, has_priv_1_12), | ||
43 | + ISA_EXT_DATA_ENTRY(ssstateen, PRIV_VERSION_1_12_0, ext_ssstateen), | ||
44 | ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc), | ||
45 | ISA_EXT_DATA_ENTRY(sstvala, PRIV_VERSION_1_12_0, has_priv_1_12), | ||
46 | ISA_EXT_DATA_ENTRY(sstvecd, PRIV_VERSION_1_12_0, has_priv_1_12), | ||
52 | @@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { | 47 | @@ -XXX,XX +XXX,XX @@ const RISCVCPUMultiExtConfig riscv_cpu_experimental_exts[] = { |
48 | */ | ||
49 | const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = { | ||
50 | MULTI_EXT_CFG_BOOL("zic64b", ext_zic64b, true), | ||
51 | + MULTI_EXT_CFG_BOOL("ssstateen", ext_ssstateen, true), | ||
52 | |||
53 | DEFINE_PROP_END_OF_LIST(), | ||
53 | }; | 54 | }; |
54 | |||
55 | const RISCVCPUMultiExtConfig riscv_cpu_named_features[] = { | ||
56 | + MULTI_EXT_CFG_BOOL("svade", svade, true), | ||
57 | MULTI_EXT_CFG_BOOL("zic64b", zic64b, true), | ||
58 | |||
59 | DEFINE_PROP_END_OF_LIST(), | ||
60 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | 55 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c |
61 | index XXXXXXX..XXXXXXX 100644 | 56 | index XXXXXXX..XXXXXXX 100644 |
62 | --- a/target/riscv/tcg/tcg-cpu.c | 57 | --- a/target/riscv/tcg/tcg-cpu.c |
63 | +++ b/target/riscv/tcg/tcg-cpu.c | 58 | +++ b/target/riscv/tcg/tcg-cpu.c |
64 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_enable_named_feat(RISCVCPU *cpu, uint32_t feat_offset) | 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; | ||
65 | cpu->cfg.cbop_blocksize = 64; | 67 | cpu->cfg.cbop_blocksize = 64; |
66 | cpu->cfg.cboz_blocksize = 64; | 68 | cpu->cfg.cboz_blocksize = 64; |
67 | break; | ||
68 | + case CPU_CFG_OFFSET(svade): | ||
69 | + cpu->cfg.ext_svadu = false; | ||
70 | + break; | 69 | + break; |
71 | default: | 70 | + case CPU_CFG_OFFSET(ext_ssstateen): |
72 | g_assert_not_reached(); | 71 | + cpu->cfg.ext_smstateen = true; |
72 | + break; | ||
73 | } | 73 | } |
74 | } | ||
75 | |||
74 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu) | 76 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu) |
75 | cpu->cfg.zic64b = cpu->cfg.cbom_blocksize == 64 && | 77 | cpu->cfg.ext_zic64b = cpu->cfg.cbom_blocksize == 64 && |
76 | cpu->cfg.cbop_blocksize == 64 && | 78 | cpu->cfg.cbop_blocksize == 64 && |
77 | cpu->cfg.cboz_blocksize == 64; | 79 | cpu->cfg.cboz_blocksize == 64; |
78 | + | 80 | + |
79 | + cpu->cfg.svade = !cpu->cfg.ext_svadu; | 81 | + cpu->cfg.ext_ssstateen = cpu->cfg.ext_smstateen; |
80 | } | 82 | } |
81 | 83 | ||
82 | static void riscv_cpu_validate_g(RISCVCPU *cpu) | 84 | static void riscv_cpu_validate_g(RISCVCPU *cpu) |
83 | -- | 85 | -- |
84 | 2.43.0 | 86 | 2.47.1 | diff view generated by jsdifflib |
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | 1 | From: MollyChen <xiaoou@iscas.ac.cn> |
---|---|---|---|
2 | 2 | ||
3 | We don't have any form of a 'bare bones' CPU. rv64, our default CPUs, | 3 | Add a CPU entry for the RV64 XiangShan NANHU CPU which |
4 | comes with a lot of defaults. This is fine for most regular uses but | 4 | supports single-core and dual-core configurations. More |
5 | it's not suitable when more control of what is actually loaded in the | 5 | details can be found at |
6 | CPU is required. | 6 | https://docs.xiangshan.cc/zh-cn/latest/integration/overview |
7 | 7 | ||
8 | A bare-bones CPU would be annoying to deal with if not by profile | 8 | Signed-off-by: MollyChen <xiaoou@iscas.ac.cn> |
9 | support, a way to load a multitude of extensions with a single flag. | 9 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Profile support is going to be implemented shortly, so let's add a CPU | 10 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> |
11 | for it. | 11 | Message-ID: <20241205073622.46052-1-xiaoou@iscas.ac.cn> |
12 | 12 | [ Changes by AF | |
13 | The new 'rv64i' CPU will have only RVI loaded. It is inspired in the | 13 | - Fixup code formatting |
14 | profile specification that dictates, for RVA22U64 [1]: | 14 | ] |
15 | |||
16 | "RVA22U64 Mandatory Base | ||
17 | RV64I is the mandatory base ISA for RVA22U64" | ||
18 | |||
19 | And so it seems that RV64I is the mandatory base ISA for all profiles | ||
20 | listed in [1], making it an ideal CPU to use with profile support. | ||
21 | |||
22 | rv64i is a CPU of type TYPE_RISCV_BARE_CPU. It has a mix of features | ||
23 | from pre-existent CPUs: | ||
24 | |||
25 | - it allows extensions to be enabled, like generic CPUs; | ||
26 | - it will not inherit extension defaults, like vendor CPUs. | ||
27 | |||
28 | This is the minimum extension set to boot OpenSBI and buildroot using | ||
29 | rv64i: | ||
30 | |||
31 | ./build/qemu-system-riscv64 -nographic -M virt \ | ||
32 | -cpu rv64i,sv39=true,g=true,c=true,s=true,u=true | ||
33 | |||
34 | Our minimal riscv,isa in this case will be: | ||
35 | |||
36 | # cat /proc/device-tree/cpus/cpu@0/riscv,isa | ||
37 | rv64imafdc_zicntr_zicsr_zifencei_zihpm_zca_zcd# | ||
38 | |||
39 | [1] https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc | ||
40 | |||
41 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
42 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
43 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
44 | Message-ID: <20231218125334.37184-5-dbarboza@ventanamicro.com> | ||
45 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
46 | --- | 16 | --- |
47 | target/riscv/cpu-qom.h | 2 ++ | 17 | target/riscv/cpu-qom.h | 1 + |
48 | target/riscv/cpu.c | 46 ++++++++++++++++++++++++++++++++++++++++++ | 18 | target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++ |
49 | 2 files changed, 48 insertions(+) | 19 | 2 files changed, 31 insertions(+) |
50 | 20 | ||
51 | diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h | 21 | diff --git a/target/riscv/cpu-qom.h b/target/riscv/cpu-qom.h |
52 | index XXXXXXX..XXXXXXX 100644 | 22 | index XXXXXXX..XXXXXXX 100644 |
53 | --- a/target/riscv/cpu-qom.h | 23 | --- a/target/riscv/cpu-qom.h |
54 | +++ b/target/riscv/cpu-qom.h | 24 | +++ b/target/riscv/cpu-qom.h |
55 | @@ -XXX,XX +XXX,XX @@ | 25 | @@ -XXX,XX +XXX,XX @@ |
56 | #define TYPE_RISCV_CPU "riscv-cpu" | 26 | #define TYPE_RISCV_CPU_THEAD_C906 RISCV_CPU_TYPE_NAME("thead-c906") |
57 | #define TYPE_RISCV_DYNAMIC_CPU "riscv-dynamic-cpu" | 27 | #define TYPE_RISCV_CPU_VEYRON_V1 RISCV_CPU_TYPE_NAME("veyron-v1") |
58 | #define TYPE_RISCV_VENDOR_CPU "riscv-vendor-cpu" | 28 | #define TYPE_RISCV_CPU_TT_ASCALON RISCV_CPU_TYPE_NAME("tt-ascalon") |
59 | +#define TYPE_RISCV_BARE_CPU "riscv-bare-cpu" | 29 | +#define TYPE_RISCV_CPU_XIANGSHAN_NANHU RISCV_CPU_TYPE_NAME("xiangshan-nanhu") |
60 | 30 | #define TYPE_RISCV_CPU_HOST RISCV_CPU_TYPE_NAME("host") | |
61 | #define RISCV_CPU_TYPE_SUFFIX "-" TYPE_RISCV_CPU | 31 | |
62 | #define RISCV_CPU_TYPE_NAME(name) (name RISCV_CPU_TYPE_SUFFIX) | 32 | OBJECT_DECLARE_CPU_TYPE(RISCVCPU, RISCVCPUClass, RISCV_CPU) |
63 | @@ -XXX,XX +XXX,XX @@ | ||
64 | #define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32") | ||
65 | #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64") | ||
66 | #define TYPE_RISCV_CPU_BASE128 RISCV_CPU_TYPE_NAME("x-rv128") | ||
67 | +#define TYPE_RISCV_CPU_RV64I RISCV_CPU_TYPE_NAME("rv64i") | ||
68 | #define TYPE_RISCV_CPU_IBEX RISCV_CPU_TYPE_NAME("lowrisc-ibex") | ||
69 | #define TYPE_RISCV_CPU_SHAKTI_C RISCV_CPU_TYPE_NAME("shakti-c") | ||
70 | #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31") | ||
71 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 33 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
72 | index XXXXXXX..XXXXXXX 100644 | 34 | index XXXXXXX..XXXXXXX 100644 |
73 | --- a/target/riscv/cpu.c | 35 | --- a/target/riscv/cpu.c |
74 | +++ b/target/riscv/cpu.c | 36 | +++ b/target/riscv/cpu.c |
75 | @@ -XXX,XX +XXX,XX @@ static void set_satp_mode_max_supported(RISCVCPU *cpu, | 37 | @@ -XXX,XX +XXX,XX @@ static void rv64_tt_ascalon_cpu_init(Object *obj) |
76 | /* Set the satp mode to the max supported */ | ||
77 | static void set_satp_mode_default_map(RISCVCPU *cpu) | ||
78 | { | ||
79 | + /* | ||
80 | + * Bare CPUs do not default to the max available. | ||
81 | + * Users must set a valid satp_mode in the command | ||
82 | + * line. | ||
83 | + */ | ||
84 | + if (object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_BARE_CPU) != NULL) { | ||
85 | + warn_report("No satp mode set. Defaulting to 'bare'"); | ||
86 | + cpu->cfg.satp_mode.map = (1 << VM_1_10_MBARE); | ||
87 | + return; | ||
88 | + } | ||
89 | + | ||
90 | cpu->cfg.satp_mode.map = cpu->cfg.satp_mode.supported; | ||
91 | } | ||
92 | #endif | ||
93 | @@ -XXX,XX +XXX,XX @@ static void rv128_base_cpu_init(Object *obj) | ||
94 | set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV57); | ||
95 | #endif | 38 | #endif |
96 | } | 39 | } |
97 | + | 40 | |
98 | +static void rv64i_bare_cpu_init(Object *obj) | 41 | +static void rv64_xiangshan_nanhu_cpu_init(Object *obj) |
99 | +{ | 42 | +{ |
100 | + CPURISCVState *env = &RISCV_CPU(obj)->env; | 43 | + CPURISCVState *env = &RISCV_CPU(obj)->env; |
101 | + riscv_cpu_set_misa(env, MXL_RV64, RVI); | 44 | + RISCVCPU *cpu = RISCV_CPU(obj); |
102 | + | 45 | + |
103 | + /* Remove the defaults from the parent class */ | 46 | + riscv_cpu_set_misa_ext(env, RVG | RVC | RVB | RVS | RVU); |
104 | + RISCV_CPU(obj)->cfg.ext_zicntr = false; | 47 | + env->priv_ver = PRIV_VERSION_1_12_0; |
105 | + RISCV_CPU(obj)->cfg.ext_zihpm = false; | ||
106 | + | 48 | + |
107 | + /* Set to QEMU's first supported priv version */ | 49 | + /* Enable ISA extensions */ |
108 | + env->priv_ver = PRIV_VERSION_1_10_0; | 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; | ||
109 | + | 60 | + |
110 | + /* | 61 | + cpu->cfg.mmu = true; |
111 | + * Support all available satp_mode settings. The default | 62 | + cpu->cfg.pmp = true; |
112 | + * value will be set to MBARE if the user doesn't set | 63 | + |
113 | + * satp_mode manually (see set_satp_mode_default()). | ||
114 | + */ | ||
115 | +#ifndef CONFIG_USER_ONLY | 64 | +#ifndef CONFIG_USER_ONLY |
116 | + set_satp_mode_max_supported(RISCV_CPU(obj), VM_1_10_SV64); | 65 | + set_satp_mode_max_supported(cpu, VM_1_10_SV39); |
117 | +#endif | 66 | +#endif |
118 | +} | 67 | +} |
119 | #else | 68 | + |
120 | static void rv32_base_cpu_init(Object *obj) | 69 | #ifdef CONFIG_TCG |
70 | static void rv128_base_cpu_init(Object *obj) | ||
121 | { | 71 | { |
122 | @@ -XXX,XX +XXX,XX @@ char *riscv_isa_string(RISCVCPU *cpu) | ||
123 | .instance_init = initfn \ | ||
124 | } | ||
125 | |||
126 | +#define DEFINE_BARE_CPU(type_name, initfn) \ | ||
127 | + { \ | ||
128 | + .name = type_name, \ | ||
129 | + .parent = TYPE_RISCV_BARE_CPU, \ | ||
130 | + .instance_init = initfn \ | ||
131 | + } | ||
132 | + | ||
133 | static const TypeInfo riscv_cpu_type_infos[] = { | ||
134 | { | ||
135 | .name = TYPE_RISCV_CPU, | ||
136 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { | 72 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { |
137 | .parent = TYPE_RISCV_CPU, | 73 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, MXL_RV64, rv64_thead_c906_cpu_init), |
138 | .abstract = true, | 74 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_TT_ASCALON, MXL_RV64, rv64_tt_ascalon_cpu_init), |
139 | }, | 75 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, MXL_RV64, rv64_veyron_v1_cpu_init), |
140 | + { | 76 | + DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_XIANGSHAN_NANHU, |
141 | + .name = TYPE_RISCV_BARE_CPU, | 77 | + MXL_RV64, rv64_xiangshan_nanhu_cpu_init), |
142 | + .parent = TYPE_RISCV_CPU, | 78 | #ifdef CONFIG_TCG |
143 | + .abstract = true, | 79 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, MXL_RV128, rv128_base_cpu_init), |
144 | + }, | 80 | #endif /* CONFIG_TCG */ |
145 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init), | ||
146 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_MAX, riscv_max_cpu_init), | ||
147 | #if defined(TARGET_RISCV32) | ||
148 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo riscv_cpu_type_infos[] = { | ||
149 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_THEAD_C906, rv64_thead_c906_cpu_init), | ||
150 | DEFINE_VENDOR_CPU(TYPE_RISCV_CPU_VEYRON_V1, rv64_veyron_v1_cpu_init), | ||
151 | DEFINE_DYNAMIC_CPU(TYPE_RISCV_CPU_BASE128, rv128_base_cpu_init), | ||
152 | + DEFINE_BARE_CPU(TYPE_RISCV_CPU_RV64I, rv64i_bare_cpu_init), | ||
153 | #endif | ||
154 | }; | ||
155 | |||
156 | -- | 81 | -- |
157 | 2.43.0 | 82 | 2.47.1 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | The profile support is handling multi-letter extensions only. Let's add | ||
4 | support for MISA bits as well. | ||
5 | |||
6 | We'll go through every known MISA bit. If the profile doesn't declare | ||
7 | the bit as mandatory, ignore it. Otherwise, set the bit in env->misa_ext | ||
8 | and env->misa_ext_mask. | ||
9 | |||
10 | Now that we're setting profile MISA bits, one can use the rv64i CPU to boot | ||
11 | Linux using the following options: | ||
12 | |||
13 | -cpu rv64i,rva22u64=true,rv39=true,s=true,zifencei=true | ||
14 | |||
15 | In the near future, when rva22s64 (where, 's', 'zifencei' and sv39 are | ||
16 | mandatory), is implemented, rv64i will be able to boot Linux loading | ||
17 | rva22s64 and no additional flags. | ||
18 | |||
19 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
20 | Reviewed-by: LIU Zhiwei <zhiwei_liu@linux.alibaba.com> | ||
21 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
22 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
23 | Message-ID: <20231218125334.37184-14-dbarboza@ventanamicro.com> | ||
24 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
25 | --- | ||
26 | target/riscv/tcg/tcg-cpu.c | 21 +++++++++++++++++++++ | ||
27 | 1 file changed, 21 insertions(+) | ||
28 | |||
29 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
30 | index XXXXXXX..XXXXXXX 100644 | ||
31 | --- a/target/riscv/tcg/tcg-cpu.c | ||
32 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
33 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name, | ||
34 | profile->user_set = true; | ||
35 | profile->enabled = value; | ||
36 | |||
37 | + for (i = 0; misa_bits[i] != 0; i++) { | ||
38 | + uint32_t bit = misa_bits[i]; | ||
39 | + | ||
40 | + if (!(profile->misa_ext & bit)) { | ||
41 | + continue; | ||
42 | + } | ||
43 | + | ||
44 | + if (bit == RVI && !profile->enabled) { | ||
45 | + /* | ||
46 | + * Disabling profiles will not disable the base | ||
47 | + * ISA RV64I. | ||
48 | + */ | ||
49 | + continue; | ||
50 | + } | ||
51 | + | ||
52 | + g_hash_table_insert(misa_ext_user_opts, | ||
53 | + GUINT_TO_POINTER(bit), | ||
54 | + (gpointer)value); | ||
55 | + riscv_cpu_write_misa_bit(cpu, bit, profile->enabled); | ||
56 | + } | ||
57 | + | ||
58 | for (i = 0; profile->ext_offsets[i] != RISCV_PROFILE_EXT_LIST_END; i++) { | ||
59 | ext_offset = profile->ext_offsets[i]; | ||
60 | |||
61 | -- | ||
62 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | RVG behaves like a profile: a single flag enables a set of bits. Right | ||
4 | now we're considering user choice when handling RVG and zicsr/zifencei | ||
5 | and ignoring user choice on MISA bits. | ||
6 | |||
7 | We'll add user warnings for profiles when the user disables its | ||
8 | mandatory extensions in the next patch. We'll do the same thing with RVG | ||
9 | now to keep consistency between RVG and profile handling. | ||
10 | |||
11 | First and foremost, create a new RVG only helper to avoid clogging | ||
12 | riscv_cpu_validate_set_extensions(). We do not want to annoy users with | ||
13 | RVG warnings like we did in the past (see 9b9741c38f), thus we'll only | ||
14 | warn if RVG was user set and the user disabled a RVG extension in the | ||
15 | command line. | ||
16 | |||
17 | For every RVG MISA bit (IMAFD), zicsr and zifencei, the logic then | ||
18 | becomes: | ||
19 | |||
20 | - if enabled, do nothing; | ||
21 | - if disabled and not user set, enable it; | ||
22 | - if disabled and user set, throw a warning that it's a RVG mandatory | ||
23 | extension. | ||
24 | |||
25 | This same logic will be used for profiles in the next patch. | ||
26 | |||
27 | Note that this is a behavior change, where we would error out if the | ||
28 | user disabled either zicsr or zifencei. As long as users are explicitly | ||
29 | disabling things in the command line we'll let them have a go at it, at | ||
30 | least in this step. We'll error out later in the validation if needed. | ||
31 | |||
32 | Other notable changes from the previous RVG code: | ||
33 | |||
34 | - use riscv_cpu_write_misa_bit() instead of manually updating both | ||
35 | env->misa_ext and env->misa_ext_mask; | ||
36 | |||
37 | - set zicsr and zifencei directly. We're already checking if they | ||
38 | were user set and priv version will never fail for these | ||
39 | extensions, making cpu_cfg_ext_auto_update() redundant. | ||
40 | |||
41 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
42 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
43 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
44 | Message-ID: <20231218125334.37184-16-dbarboza@ventanamicro.com> | ||
45 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
46 | --- | ||
47 | target/riscv/tcg/tcg-cpu.c | 73 +++++++++++++++++++++++++------------- | ||
48 | 1 file changed, 48 insertions(+), 25 deletions(-) | ||
49 | |||
50 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/target/riscv/tcg/tcg-cpu.c | ||
53 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
54 | @@ -XXX,XX +XXX,XX @@ static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset) | ||
55 | GUINT_TO_POINTER(ext_offset)); | ||
56 | } | ||
57 | |||
58 | +static bool cpu_misa_ext_is_user_set(uint32_t misa_bit) | ||
59 | +{ | ||
60 | + return g_hash_table_contains(misa_ext_user_opts, | ||
61 | + GUINT_TO_POINTER(misa_bit)); | ||
62 | +} | ||
63 | + | ||
64 | static void cpu_cfg_ext_add_user_opt(uint32_t ext_offset, bool value) | ||
65 | { | ||
66 | g_hash_table_insert(multi_ext_user_opts, GUINT_TO_POINTER(ext_offset), | ||
67 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_update_named_features(RISCVCPU *cpu) | ||
68 | cpu->cfg.cboz_blocksize == 64; | ||
69 | } | ||
70 | |||
71 | +static void riscv_cpu_validate_g(RISCVCPU *cpu) | ||
72 | +{ | ||
73 | + const char *warn_msg = "RVG mandates disabled extension %s"; | ||
74 | + uint32_t g_misa_bits[] = {RVI, RVM, RVA, RVF, RVD}; | ||
75 | + bool send_warn = cpu_misa_ext_is_user_set(RVG); | ||
76 | + | ||
77 | + for (int i = 0; i < ARRAY_SIZE(g_misa_bits); i++) { | ||
78 | + uint32_t bit = g_misa_bits[i]; | ||
79 | + | ||
80 | + if (riscv_has_ext(&cpu->env, bit)) { | ||
81 | + continue; | ||
82 | + } | ||
83 | + | ||
84 | + if (!cpu_misa_ext_is_user_set(bit)) { | ||
85 | + riscv_cpu_write_misa_bit(cpu, bit, true); | ||
86 | + continue; | ||
87 | + } | ||
88 | + | ||
89 | + if (send_warn) { | ||
90 | + warn_report(warn_msg, riscv_get_misa_ext_name(bit)); | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + if (!cpu->cfg.ext_zicsr) { | ||
95 | + if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr))) { | ||
96 | + cpu->cfg.ext_zicsr = true; | ||
97 | + } else if (send_warn) { | ||
98 | + warn_report(warn_msg, "zicsr"); | ||
99 | + } | ||
100 | + } | ||
101 | + | ||
102 | + if (!cpu->cfg.ext_zifencei) { | ||
103 | + if (!cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei))) { | ||
104 | + cpu->cfg.ext_zifencei = true; | ||
105 | + } else if (send_warn) { | ||
106 | + warn_report(warn_msg, "zifencei"); | ||
107 | + } | ||
108 | + } | ||
109 | +} | ||
110 | + | ||
111 | /* | ||
112 | * Check consistency between chosen extensions while setting | ||
113 | * cpu->cfg accordingly. | ||
114 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
115 | CPURISCVState *env = &cpu->env; | ||
116 | Error *local_err = NULL; | ||
117 | |||
118 | - /* Do some ISA extension error checking */ | ||
119 | - if (riscv_has_ext(env, RVG) && | ||
120 | - !(riscv_has_ext(env, RVI) && riscv_has_ext(env, RVM) && | ||
121 | - riscv_has_ext(env, RVA) && riscv_has_ext(env, RVF) && | ||
122 | - riscv_has_ext(env, RVD) && | ||
123 | - cpu->cfg.ext_zicsr && cpu->cfg.ext_zifencei)) { | ||
124 | - | ||
125 | - if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zicsr)) && | ||
126 | - !cpu->cfg.ext_zicsr) { | ||
127 | - error_setg(errp, "RVG requires Zicsr but user set Zicsr to false"); | ||
128 | - return; | ||
129 | - } | ||
130 | - | ||
131 | - if (cpu_cfg_ext_is_user_set(CPU_CFG_OFFSET(ext_zifencei)) && | ||
132 | - !cpu->cfg.ext_zifencei) { | ||
133 | - error_setg(errp, "RVG requires Zifencei but user set " | ||
134 | - "Zifencei to false"); | ||
135 | - return; | ||
136 | - } | ||
137 | - | ||
138 | - cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zicsr), true); | ||
139 | - cpu_cfg_ext_auto_update(cpu, CPU_CFG_OFFSET(ext_zifencei), true); | ||
140 | - | ||
141 | - env->misa_ext |= RVI | RVM | RVA | RVF | RVD; | ||
142 | - env->misa_ext_mask |= RVI | RVM | RVA | RVF | RVD; | ||
143 | + if (riscv_has_ext(env, RVG)) { | ||
144 | + riscv_cpu_validate_g(cpu); | ||
145 | } | ||
146 | |||
147 | if (riscv_has_ext(env, RVI) && riscv_has_ext(env, RVE)) { | ||
148 | -- | ||
149 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | Expose all profile flags for all CPUs when executing | ||
4 | query-cpu-model-expansion. This will allow callers to quickly determine | ||
5 | if a certain profile is implemented by a given CPU. This includes vendor | ||
6 | CPUs - the fact that they don't have profile user flags doesn't mean | ||
7 | that they don't implement the profile. | ||
8 | |||
9 | After this change it's possible to quickly determine if our stock CPUs | ||
10 | implement the existing rva22u64 profile. Here's a few examples: | ||
11 | |||
12 | $ ./build/qemu-system-riscv64 -S -M virt -display none | ||
13 | -qmp tcp:localhost:1234,server,wait=off | ||
14 | |||
15 | $ ./scripts/qmp/qmp-shell localhost:1234 | ||
16 | Welcome to the QMP low-level shell! | ||
17 | Connected to QEMU 8.1.50 | ||
18 | |||
19 | - As expected, the 'max' CPU implements the rva22u64 profile. | ||
20 | |||
21 | (QEMU) query-cpu-model-expansion type=full model={"name":"max"} | ||
22 | {"return": {"model": | ||
23 | {"name": "rv64", "props": {... "rva22u64": true, ...}}}} | ||
24 | |||
25 | - rv64 is missing "zba", "zbb", "zbs", "zkt" and "zfhmin": | ||
26 | |||
27 | query-cpu-model-expansion type=full model={"name":"rv64"} | ||
28 | {"return": {"model": | ||
29 | {"name": "rv64", "props": {... "rva22u64": false, ...}}}} | ||
30 | |||
31 | query-cpu-model-expansion type=full model={"name":"rv64", | ||
32 | "props":{"zba":true,"zbb":true,"zbs":true,"zkt":true,"zfhmin":true}} | ||
33 | {"return": {"model": | ||
34 | {"name": "rv64", "props": {... "rva22u64": true, ...}}}} | ||
35 | |||
36 | We have no vendor CPUs that supports rva22u64 (veyron-v1 is the closest | ||
37 | - it is missing just 'zkt'). | ||
38 | |||
39 | In short, aside from the 'max' CPU, we have no CPUs that supports | ||
40 | rva22u64 by default. | ||
41 | |||
42 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
43 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
44 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
45 | Message-ID: <20231218125334.37184-18-dbarboza@ventanamicro.com> | ||
46 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
47 | --- | ||
48 | target/riscv/riscv-qmp-cmds.c | 14 ++++++++++++++ | ||
49 | 1 file changed, 14 insertions(+) | ||
50 | |||
51 | diff --git a/target/riscv/riscv-qmp-cmds.c b/target/riscv/riscv-qmp-cmds.c | ||
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/target/riscv/riscv-qmp-cmds.c | ||
54 | +++ b/target/riscv/riscv-qmp-cmds.c | ||
55 | @@ -XXX,XX +XXX,XX @@ static void riscv_obj_add_named_feats_qdict(Object *obj, QDict *qdict_out) | ||
56 | } | ||
57 | } | ||
58 | |||
59 | +static void riscv_obj_add_profiles_qdict(Object *obj, QDict *qdict_out) | ||
60 | +{ | ||
61 | + RISCVCPUProfile *profile; | ||
62 | + QObject *value; | ||
63 | + | ||
64 | + for (int i = 0; riscv_profiles[i] != NULL; i++) { | ||
65 | + profile = riscv_profiles[i]; | ||
66 | + value = QOBJECT(qbool_from_bool(profile->enabled)); | ||
67 | + | ||
68 | + qdict_put_obj(qdict_out, profile->name, value); | ||
69 | + } | ||
70 | +} | ||
71 | + | ||
72 | static void riscv_cpuobj_validate_qdict_in(Object *obj, QObject *props, | ||
73 | const QDict *qdict_in, | ||
74 | Error **errp) | ||
75 | @@ -XXX,XX +XXX,XX @@ CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type, | ||
76 | riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_experimental_exts); | ||
77 | riscv_obj_add_multiext_props(obj, qdict_out, riscv_cpu_vendor_exts); | ||
78 | riscv_obj_add_named_feats_qdict(obj, qdict_out); | ||
79 | + riscv_obj_add_profiles_qdict(obj, qdict_out); | ||
80 | |||
81 | /* Add our CPU boolean options too */ | ||
82 | riscv_obj_add_qdict_prop(obj, qdict_out, "mmu"); | ||
83 | -- | ||
84 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | Some profiles, like RVA22S64, has a priv_spec requirement. | ||
4 | |||
5 | Make this requirement explicit for all profiles. We'll validate this | ||
6 | requirement finalize() time and, in case the user chooses an | ||
7 | incompatible priv_spec while activating a profile, a warning will be | ||
8 | shown. | ||
9 | |||
10 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
11 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | Message-ID: <20231218125334.37184-21-dbarboza@ventanamicro.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | --- | ||
16 | target/riscv/cpu.h | 2 ++ | ||
17 | target/riscv/cpu.c | 1 + | ||
18 | target/riscv/tcg/tcg-cpu.c | 31 +++++++++++++++++++++++++++++++ | ||
19 | 3 files changed, 34 insertions(+) | ||
20 | |||
21 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
22 | index XXXXXXX..XXXXXXX 100644 | ||
23 | --- a/target/riscv/cpu.h | ||
24 | +++ b/target/riscv/cpu.h | ||
25 | @@ -XXX,XX +XXX,XX @@ typedef struct riscv_cpu_profile { | ||
26 | uint32_t misa_ext; | ||
27 | bool enabled; | ||
28 | bool user_set; | ||
29 | + int priv_spec; | ||
30 | const int32_t ext_offsets[]; | ||
31 | } RISCVCPUProfile; | ||
32 | |||
33 | #define RISCV_PROFILE_EXT_LIST_END -1 | ||
34 | +#define RISCV_PROFILE_ATTR_UNUSED -1 | ||
35 | |||
36 | extern RISCVCPUProfile *riscv_profiles[]; | ||
37 | |||
38 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
39 | index XXXXXXX..XXXXXXX 100644 | ||
40 | --- a/target/riscv/cpu.c | ||
41 | +++ b/target/riscv/cpu.c | ||
42 | @@ -XXX,XX +XXX,XX @@ Property riscv_cpu_options[] = { | ||
43 | static RISCVCPUProfile RVA22U64 = { | ||
44 | .name = "rva22u64", | ||
45 | .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU, | ||
46 | + .priv_spec = RISCV_PROFILE_ATTR_UNUSED, | ||
47 | .ext_offsets = { | ||
48 | CPU_CFG_OFFSET(ext_zicsr), CPU_CFG_OFFSET(ext_zihintpause), | ||
49 | CPU_CFG_OFFSET(ext_zba), CPU_CFG_OFFSET(ext_zbb), | ||
50 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
51 | index XXXXXXX..XXXXXXX 100644 | ||
52 | --- a/target/riscv/tcg/tcg-cpu.c | ||
53 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
54 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_write_misa_bit(RISCVCPU *cpu, uint32_t bit, | ||
55 | } | ||
56 | } | ||
57 | |||
58 | +static const char *cpu_priv_ver_to_str(int priv_ver) | ||
59 | +{ | ||
60 | + switch (priv_ver) { | ||
61 | + case PRIV_VERSION_1_10_0: | ||
62 | + return "v1.10.0"; | ||
63 | + case PRIV_VERSION_1_11_0: | ||
64 | + return "v1.11.0"; | ||
65 | + case PRIV_VERSION_1_12_0: | ||
66 | + return "v1.12.0"; | ||
67 | + } | ||
68 | + | ||
69 | + g_assert_not_reached(); | ||
70 | +} | ||
71 | + | ||
72 | static void riscv_cpu_synchronize_from_tb(CPUState *cs, | ||
73 | const TranslationBlock *tb) | ||
74 | { | ||
75 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_validate_set_extensions(RISCVCPU *cpu, Error **errp) | ||
76 | static void riscv_cpu_validate_profile(RISCVCPU *cpu, | ||
77 | RISCVCPUProfile *profile) | ||
78 | { | ||
79 | + CPURISCVState *env = &cpu->env; | ||
80 | const char *warn_msg = "Profile %s mandates disabled extension %s"; | ||
81 | bool send_warn = profile->user_set && profile->enabled; | ||
82 | bool profile_impl = true; | ||
83 | int i; | ||
84 | |||
85 | + if (profile->priv_spec != RISCV_PROFILE_ATTR_UNUSED && | ||
86 | + profile->priv_spec != env->priv_ver) { | ||
87 | + profile_impl = false; | ||
88 | + | ||
89 | + if (send_warn) { | ||
90 | + warn_report("Profile %s requires priv spec %s, " | ||
91 | + "but priv ver %s was set", profile->name, | ||
92 | + cpu_priv_ver_to_str(profile->priv_spec), | ||
93 | + cpu_priv_ver_to_str(env->priv_ver)); | ||
94 | + } | ||
95 | + } | ||
96 | + | ||
97 | for (i = 0; misa_bits[i] != 0; i++) { | ||
98 | uint32_t bit = misa_bits[i]; | ||
99 | |||
100 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name, | ||
101 | profile->user_set = true; | ||
102 | profile->enabled = value; | ||
103 | |||
104 | + if (profile->enabled) { | ||
105 | + cpu->env.priv_ver = profile->priv_spec; | ||
106 | + } | ||
107 | + | ||
108 | for (i = 0; misa_bits[i] != 0; i++) { | ||
109 | uint32_t bit = misa_bits[i]; | ||
110 | |||
111 | -- | ||
112 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | Profiles will need to validate satp_mode during their own finalize | ||
4 | methods. This will occur inside riscv_tcg_cpu_finalize_features() for | ||
5 | TCG. Given that satp_mode does not have any pre-req from the accelerator | ||
6 | finalize() method, it's safe to finalize it earlier. | ||
7 | |||
8 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
9 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Message-ID: <20231218125334.37184-22-dbarboza@ventanamicro.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/cpu.c | 16 ++++++++-------- | ||
15 | 1 file changed, 8 insertions(+), 8 deletions(-) | ||
16 | |||
17 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
18 | index XXXXXXX..XXXXXXX 100644 | ||
19 | --- a/target/riscv/cpu.c | ||
20 | +++ b/target/riscv/cpu.c | ||
21 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp) | ||
22 | { | ||
23 | Error *local_err = NULL; | ||
24 | |||
25 | +#ifndef CONFIG_USER_ONLY | ||
26 | + riscv_cpu_satp_mode_finalize(cpu, &local_err); | ||
27 | + if (local_err != NULL) { | ||
28 | + error_propagate(errp, local_err); | ||
29 | + return; | ||
30 | + } | ||
31 | +#endif | ||
32 | + | ||
33 | /* | ||
34 | * KVM accel does not have a specialized finalize() | ||
35 | * callback because its extensions are validated | ||
36 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_finalize_features(RISCVCPU *cpu, Error **errp) | ||
37 | return; | ||
38 | } | ||
39 | } | ||
40 | - | ||
41 | -#ifndef CONFIG_USER_ONLY | ||
42 | - riscv_cpu_satp_mode_finalize(cpu, &local_err); | ||
43 | - if (local_err != NULL) { | ||
44 | - error_propagate(errp, local_err); | ||
45 | - return; | ||
46 | - } | ||
47 | -#endif | ||
48 | } | ||
49 | |||
50 | static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
51 | -- | ||
52 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
2 | 1 | ||
3 | Certain S-mode profiles, like RVA22S64 and RVA23S64, mandate all the | ||
4 | mandatory extensions of their respective U-mode profiles. RVA22S64 | ||
5 | includes all mandatory extensions of RVA22U64, and the same happens with | ||
6 | RVA23 profiles. | ||
7 | |||
8 | Add a 'parent' field to allow profiles to enable other profiles. This | ||
9 | will allow us to describe S-mode profiles by specifying their parent | ||
10 | U-mode profile, then adding just the S-mode specific extensions. | ||
11 | |||
12 | We're naming the field 'parent' to consider the possibility of other | ||
13 | uses (e.g. a s-mode profile including a previous s-mode profile) in the | ||
14 | future. | ||
15 | |||
16 | Suggested-by: Andrew Jones <ajones@ventanamicro.com> | ||
17 | Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
18 | Reviewed-by: Andrew Jones <ajones@ventanamicro.com> | ||
19 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
20 | Message-ID: <20231218125334.37184-25-dbarboza@ventanamicro.com> | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | --- | ||
23 | target/riscv/cpu.h | 1 + | ||
24 | target/riscv/cpu.c | 1 + | ||
25 | target/riscv/tcg/tcg-cpu.c | 14 +++++++++++++- | ||
26 | 3 files changed, 15 insertions(+), 1 deletion(-) | ||
27 | |||
28 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/target/riscv/cpu.h | ||
31 | +++ b/target/riscv/cpu.h | ||
32 | @@ -XXX,XX +XXX,XX @@ const char *riscv_get_misa_ext_description(uint32_t bit); | ||
33 | #define CPU_CFG_OFFSET(_prop) offsetof(struct RISCVCPUConfig, _prop) | ||
34 | |||
35 | typedef struct riscv_cpu_profile { | ||
36 | + struct riscv_cpu_profile *parent; | ||
37 | const char *name; | ||
38 | uint32_t misa_ext; | ||
39 | bool enabled; | ||
40 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
41 | index XXXXXXX..XXXXXXX 100644 | ||
42 | --- a/target/riscv/cpu.c | ||
43 | +++ b/target/riscv/cpu.c | ||
44 | @@ -XXX,XX +XXX,XX @@ Property riscv_cpu_options[] = { | ||
45 | * having a cfg offset) at this moment. | ||
46 | */ | ||
47 | static RISCVCPUProfile RVA22U64 = { | ||
48 | + .parent = NULL, | ||
49 | .name = "rva22u64", | ||
50 | .misa_ext = RVI | RVM | RVA | RVF | RVD | RVC | RVU, | ||
51 | .priv_spec = RISCV_PROFILE_ATTR_UNUSED, | ||
52 | diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c | ||
53 | index XXXXXXX..XXXXXXX 100644 | ||
54 | --- a/target/riscv/tcg/tcg-cpu.c | ||
55 | +++ b/target/riscv/tcg/tcg-cpu.c | ||
56 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_profile(RISCVCPU *cpu, | ||
57 | CPURISCVState *env = &cpu->env; | ||
58 | const char *warn_msg = "Profile %s mandates disabled extension %s"; | ||
59 | bool send_warn = profile->user_set && profile->enabled; | ||
60 | - bool profile_impl = true; | ||
61 | + bool parent_enabled, profile_impl = true; | ||
62 | int i; | ||
63 | |||
64 | #ifndef CONFIG_USER_ONLY | ||
65 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_validate_profile(RISCVCPU *cpu, | ||
66 | } | ||
67 | |||
68 | profile->enabled = profile_impl; | ||
69 | + | ||
70 | + if (profile->parent != NULL) { | ||
71 | + parent_enabled = object_property_get_bool(OBJECT(cpu), | ||
72 | + profile->parent->name, | ||
73 | + NULL); | ||
74 | + profile->enabled = profile->enabled && parent_enabled; | ||
75 | + } | ||
76 | } | ||
77 | |||
78 | static void riscv_cpu_validate_profiles(RISCVCPU *cpu) | ||
79 | @@ -XXX,XX +XXX,XX @@ static void cpu_set_profile(Object *obj, Visitor *v, const char *name, | ||
80 | profile->user_set = true; | ||
81 | profile->enabled = value; | ||
82 | |||
83 | + if (profile->parent != NULL) { | ||
84 | + object_property_set_bool(obj, profile->parent->name, | ||
85 | + profile->enabled, NULL); | ||
86 | + } | ||
87 | + | ||
88 | if (profile->enabled) { | ||
89 | cpu->env.priv_ver = profile->priv_spec; | ||
90 | } | ||
91 | -- | ||
92 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Bin Meng <bmeng@tinylab.org> | ||
2 | 1 | ||
3 | Upgrade OpenSBI from v1.3.1 to v1.4 and the pre-built bios images. | ||
4 | |||
5 | The v1.4 release includes the following commits: | ||
6 | |||
7 | 1a398d9 lib: sbi: Add Zicntr as a HART ISA extension | ||
8 | 669089c lib: sbi: Add Zihpm as a HART ISA extension | ||
9 | 72b9c8f lib: sbi: Alphabetically sort HART ISA extensions | ||
10 | 5359fc6 lib: sbi: Rename hart_pmu_get_allowed_bits() function | ||
11 | 976895c lib: sbi: Fix Priv spec version for [m|s]counteren and mcountinhibit CSRs | ||
12 | 6053917 lib: sbi: Fix how print gets flags | ||
13 | 35ef182 lib: sbi: print not fill '0' when left-aligned | ||
14 | 40dac06 lib: sbi: Add '+' flags for print | ||
15 | 458fa74 lib: sbi: Add ' ' '\'' flags for print | ||
16 | 05cbb6e lib: sbi: implifying the parameters of printi | ||
17 | fe08281 lib: sbi: print add 'o' type | ||
18 | c6ee5ae lib: sbi: Fix printi | ||
19 | 3b6fcdd lib: sbi: Simplify prints | ||
20 | cc89fa7 lib: sbi: Fix printc | ||
21 | ff43168 lib: sbi: Fix timing of clearing tbuf | ||
22 | a73982d lib: sbi: Fix missing '\0' when buffer szie equal 1 | ||
23 | ea6533a lib: utils/gpio: Fix RV32 compile error for designware GPIO driver | ||
24 | c3b98c6 include: sbi: Add macro definitions for mseccfg CSR | ||
25 | 1c099c4 lib: sbi: Add functions to manipulate PMP entries | ||
26 | 6c202c5 include: sbi: Add Smepmp specific access flags for PMP entries | ||
27 | cbcfc7b lib: sbi: Add smepmp in hart extensions | ||
28 | d72f5f1 lib: utils: Add detection of Smepmp from ISA string in FDT | ||
29 | 4a42a23 lib: sbi: Grant SU R/W/X permissions to whole memory | ||
30 | f3fdd04 lib: sbi: Change the order of PMP initialization | ||
31 | 5dd8db5 lib: sbi: Add support for Smepmp | ||
32 | 6e44ef6 lib: sbi: Add functions to map/unmap shared memory | ||
33 | 0ad8660 lib: sbi: Map/Unmap debug console shared memory buffers | ||
34 | 057eb10 lib: utils/gpio: Fix RV32 compile error for designware GPIO driver | ||
35 | 0e2111e libfdt: fix SPDX license identifiers | ||
36 | e05a9cf lib: sbi: Update system suspend to spec | ||
37 | 5e20d25 include: sbi: fix CSR define of mseccfg | ||
38 | 44c5151 include: sbi_utils: Remove driver pointer from struct i2c_adapter | ||
39 | 14a35b0 lib: utils/regmap: Add generic regmap access library | ||
40 | 8e97275 lib: utils/regmap: Add simple FDT based regmap framework | ||
41 | f21d8f7 lib: utils/regmap: Add simple FDT based syscon regmap driver | ||
42 | 4a344a9 lib: utils/reset: Add syscon based reboot and poweroff | ||
43 | c2e6027 lib: utils/reset: Remove SiFive Test reset driver | ||
44 | f536e0b gitignore: allow gitignore to ignore most dot file | ||
45 | c744ed7 lib: sbi_pmu: Enable noncontigous hpm event and counters | ||
46 | 6259b2e lib: utils/fdt: Fix fdt_parse_isa_extensions() implementation | ||
47 | f46a564 lib: sbi: Fix typo for finding fixed event counter | ||
48 | 94197a8 fw_base.S: Fix assembler error with clang 16+ | ||
49 | c104c60 lib: sbi: Add support for smcntrpmf | ||
50 | 7aabeee Makefile: Fix grep warning | ||
51 | e7e73aa platform: generic: allwinner: correct mhpmevent count | ||
52 | ee1f83c lib: sbi_pmu: remove mhpm_count field in hart feature | ||
53 | a9cffd6 firmware: payload: test: Change to SBI v2.0 DBCN ecalls | ||
54 | b20bd47 lib: sbi: improve the definition of SBI_IPI_EVENT_MAX | ||
55 | 664692f lib: sbi_pmu: ensure update hpm counter before starting counting | ||
56 | c9a296d platform: generic: allwinner: fix OF process for T-HEAD c9xx pmu | ||
57 | 901d3d7 lib: sbi_pmu: keep overflow interrupt of stopped hpm counter disabled | ||
58 | cacfba3 platform: Allow platforms to specify the size of tlb fifo | ||
59 | 5bd9694 lib: sbi: alloc tlb fifo by sbi_malloc | ||
60 | 130e65d lib: sbi: Implement SET_FS_DIRTY() to make sure the mstatus FS dirty is set | ||
61 | d1e4dff lib: sbi: Introduce HART index in sbi_scratch | ||
62 | e6125c3 lib: sbi: Remove sbi_platform_hart_index/invalid() functions | ||
63 | 296e70d lib: sbi: Extend sbi_hartmask to support both hartid and hartindex | ||
64 | e632cd7 lib: sbi: Use sbi_scratch_last_hartindex() in remote TLB managment | ||
65 | 78c667b lib: sbi: Prefer hartindex over hartid in IPI framework | ||
66 | 22d6ff8 lib: sbi: Remove sbi_scratch_last_hartid() macro | ||
67 | 112daa2 lib: sbi: Maximize the use of HART index in sbi_domain | ||
68 | 9560fb3 include: sbi: Remove sbi_hartmask_for_each_hart() macro | ||
69 | b8fb96e include: sbi_domain: Fix permission test macros | ||
70 | bff27c1 lib: sbi: Factor-out Smepmp configuration as separate function | ||
71 | 5240d31 lib: sbi: Don't clear mseccfg.MML bit in sbi_hart_smepmp_configure() | ||
72 | 2b51a9d lib: sbi: Fix pmp_flags for Smepmp read-only shared region | ||
73 | 73aea28 lib: sbi: Populate M-only Smepmp entries before setting mseccfg.MML | ||
74 | e8bc162 lib: utils/serial: Add shared regions for serial drivers | ||
75 | b7e9d34 lib: utils/regmap: Mark syscon region as shared read-write | ||
76 | 3669153 platform: generic: thead: fix stale TLB entries for th1520/sg2042 | ||
77 | de525ac firmware: Remove ALIGN in .rela.dyn in linker script | ||
78 | 2a6d725 firmware: Remove handling of R_RISCV_{32,64} | ||
79 | 6ed125a Makefile: Add --exclude-libs ALL to avoid .dynsym | ||
80 | e21901d doc: Fix fw_payload.md | ||
81 | a125423 lib: utils/serial: Ensure proper allocation of PMP entries for uart8250 | ||
82 | d36709f lib: utils: timer/ipi: Update memregion flags for PLMT and PLICSW | ||
83 | 8197c2f lib: sbi: fix sbi_domain_get_assigned_hartmask() | ||
84 | 9da30f6 lib: utils/fdt: simplify dt_parse_isa_extensions | ||
85 | 942aca2 lib: utils: Simplify SET_ISA_EXT_MAP() | ||
86 | f831b93 lib: sbi_pmu: check for index overflows | ||
87 | d891cae gpio/starfive: redundant readl() call | ||
88 | e8114c6 docs: platform: update platform_requirements.md | ||
89 | 3632f2b lib: sbi: Add support for mconfigptr | ||
90 | ec0559e lib: sbi_misaligned_ldst: Fix handling of C.SWSP and C.SDSP | ||
91 | cbdd869 include: sbi: Change spec version to 2.0 | ||
92 | 5d0ed1b lib: sbi: simplify sanitize_domain() | ||
93 | c1a6987 platform: generic: thead: move to thead c9xx header to vendor specific postion | ||
94 | 8e941e7 platform: generic: thead: separate implement of T-HEAD c9xx pmu | ||
95 | 492d9b1 platform: generic: thead: separate implement of T-HEAD c9xx errata | ||
96 | 3e21b96 platform: generic: thead: initialize PMU by default in thead generic platform | ||
97 | a140a4e lib: sbi: Correctly limit flushes to a single ASID/VMID | ||
98 | 88ae718 platform: generic: thead: improve tlb flush errata | ||
99 | 52fd64b platform: Uses hart count as the default size of tlb info | ||
100 | 07f2ccd lib: utils/serial: Optimize semihosting_putc implementation | ||
101 | fccdf41 firmware: fw_base.S: Fix boot hart status synchronization | ||
102 | d1e0f7f utils/reset: Remove fdt_reset_thead | ||
103 | 896d2c9 lib: utils/timer: Allow ACLINT MTIMER driver to setup quirks | ||
104 | accafb1 lib: utils/timer: mtimer: add separate T-Head C9xx CLINT mtimer compatible | ||
105 | 98bc25f lib: utils/ipi: mswi: add separate T-Head C9xx CLINT mswi compatible | ||
106 | 5b2f55d lib: sbi: separate the swap operation of domain region | ||
107 | 3b03cdd lib: sbi: Add regions merging when sanitizing domain region | ||
108 | 2bfdb9e platform: generic: Add Sophgo sg2042 platform support | ||
109 | 280f7ae include: sbi: macros for mseccfg.sseed and .useed | ||
110 | efcac33 lib: sbi: Add Zkr in hart extensions | ||
111 | 6e5b0cf lib: sbi: enable seed access in S-mode | ||
112 | 6602e11 lib: sbi: change sbi_hart_features.extensions as an array | ||
113 | 3aaed4f lib: sbi: Make console_puts/console_putc interchangeable | ||
114 | dc0bb19 lib: utils/serial: remove semihosting_putc | ||
115 | 16bb930 lib: sbi: Fix PMP granularity handling in sbi_hart_map_saddr() | ||
116 | 574b9c8 lib: sbi_pmu: avoid buffer overflow | ||
117 | 791704c lib: utils/irqchip: Avoid redundant writes to APLIC CLRIE register | ||
118 | f520256 lib: sbi: Allow relaxed MMIO writes in device ipi_send() callback | ||
119 | b70d628 lib: sbi: Allow relaxed MMIO writes in device ipi_clear() callback | ||
120 | bd74931 lib: ipi: Adjust Andes PLICSW to single-bit-per-hart scheme | ||
121 | 291403f sbi: sbi_pmu: Improve sbi_pmu_init() error handling | ||
122 | 090fa99 lib: sbi: Add XAndesPMU in hart extensions | ||
123 | a48f2cf sbi: sbi_pmu: Add hw_counter_filter_mode() to pmu device | ||
124 | 51ec60c platform: include: andes45: Add PMU related CSR defines | ||
125 | effd89a platform: generic: Introduce pmu_init() platform override | ||
126 | 1b9e743 platform: andes: Add Andes custom PMU support | ||
127 | 2e50c24 platform: andes: Enable Andes PMU for AE350 | ||
128 | 535c661 platform: rzfive: Enable Andes PMU for RZ/Five | ||
129 | 0b3262e lib: utils: fdt_fixup: Allow preserving PMU properties | ||
130 | 009ae4e platform: andes: Factor out is_andes() helper | ||
131 | 0308f93 lib: utils: fdt_pmu: Make the fdt_pmu_evt_select table global variable | ||
132 | e19d419 lib: utils: fdt_pmu: Do not iterate over the fdt_pmu_evt_select table | ||
133 | d162009 docs: pmu: Add Andes PMU node example | ||
134 | 6b9a849 lib: sbi: Remove xchg/cmpxchg implemented via lr/sc | ||
135 | 11bf49b lib: sbi: Fix __atomic_op_bit_ord and comments | ||
136 | 8839869 lib: sbi: Replace __atomic_op_bit_ord with __atomic intrinsics | ||
137 | 07419ec lib: sbi: Prevent redundant sbi_ipi_process | ||
138 | 93da66b lib: sbi_hart: Store PMP granularity as log base 2 | ||
139 | ee72517 lib: sbi_pmu: Add PMU snapshot definitions | ||
140 | 11a0ba5 lib: sbi_pmu: Fix the counter info function | ||
141 | 0696810 firmware: fix section types | ||
142 | a25fc74 lib: sbi_hsm: Put the resume_pending hart in the interruptible hart mask | ||
143 | 87aa306 platform: recalculate heap size to support new tlb entry number | ||
144 | a2e254e lib: sbi: skip wait_for_coldboot when coolboot done | ||
145 | 6112d58 lib: utils/fdt: Allow to use reg-names when parsing ACLINT | ||
146 | 35cba92 lib: sbi_tlb: Check tlb_range_flush_limit only once per request | ||
147 | a894187 lib: sbi_ipi: Do not ignore errors from sbi_ipi_send() | ||
148 | 446fa65 lib: sbi_ipi: Process self-IPIs in sbi_ipi_send() | ||
149 | 2707250 lib: sbi_ipi: Drop unnecessary ipi_process check | ||
150 | 925ce14 lib: sbi: Simplify the initialization of root_hmask in sbi_domain_init | ||
151 | 2c8be56 lib: sbi: Improve the code of privilege mode and extensions detection | ||
152 | 056fe6f lib: sbi: Refactor the code for enable extensions in menvfg CSR | ||
153 | 776770d lib: sbi: Using one array to define the name of extensions | ||
154 | 3daac8f lib: sbi: Detect extensions from the ISA string in DT | ||
155 | 416ceb3 lib: sbi_tlb: Reduce size of struct sbi_tlb_info | ||
156 | 80169b2 platform: generic: Fine tune fw_platform_calculate_heap_size() | ||
157 | cdebae2 lib: utils/irqchip: Add shared MMIO region for PLIC in root domain | ||
158 | 3284bea lib: sbi: Allow ecall handlers to directly update register state | ||
159 | 5a57e8c lib: sbi: Remove the SBI_ETRAP error code | ||
160 | 2b80b92 lib: sbi: Do not enter OpenSBI with mseccfg.MML == 1 | ||
161 | 63e09ad lib: sbi: Fix shift bug in sbi_system_reset | ||
162 | ba29293 lib: utils/timer: mtimer: only use regname for aclint | ||
163 | bbd065d lib: sbi: Detect Zicntr extension only based on traps | ||
164 | a2b255b include: Bump-up version to 1.4 | ||
165 | |||
166 | Signed-off-by: Bin Meng <bmeng@tinylab.org> | ||
167 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
168 | Message-Id: <20240102151153.133896-1-bmeng@tinylab.org> | ||
169 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
170 | --- | ||
171 | .../opensbi-riscv32-generic-fw_dynamic.bin | Bin 135376 -> 267416 bytes | ||
172 | .../opensbi-riscv64-generic-fw_dynamic.bin | Bin 138368 -> 270808 bytes | ||
173 | roms/opensbi | 2 +- | ||
174 | 3 files changed, 1 insertion(+), 1 deletion(-) | ||
175 | |||
176 | diff --git a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin | ||
177 | index XXXXXXX..XXXXXXX 100644 | ||
178 | Binary files a/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv32-generic-fw_dynamic.bin differ | ||
179 | diff --git a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin | ||
180 | index XXXXXXX..XXXXXXX 100644 | ||
181 | Binary files a/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin and b/pc-bios/opensbi-riscv64-generic-fw_dynamic.bin differ | ||
182 | diff --git a/roms/opensbi b/roms/opensbi | ||
183 | index XXXXXXX..XXXXXXX 160000 | ||
184 | --- a/roms/opensbi | ||
185 | +++ b/roms/opensbi | ||
186 | @@ -1 +1 @@ | ||
187 | -Subproject commit 057eb10b6d523540012e6947d5c9f63e95244e94 | ||
188 | +Subproject commit a2b255b88918715173942f2c5e1f97ac9e90c877 | ||
189 | -- | ||
190 | 2.43.0 | diff view generated by jsdifflib |
Deleted patch | |||
---|---|---|---|
1 | From: Ivan Klokov <ivan.klokov@syntacore.com> | ||
2 | 1 | ||
3 | This patch changes behavior on writing RW=01 to pmpcfg with MML=0. | ||
4 | RWX filed is form of collective WARL with the combination of | ||
5 | pmpcfg.RW=01 remains reserved for future standard use. | ||
6 | |||
7 | According to definition of WARL writing the CSR has no other side | ||
8 | effect. But current implementation change architectural state and | ||
9 | change system behavior. After writing we will get unreadable-unwriteble | ||
10 | region regardless on the previous state. | ||
11 | |||
12 | On the other side WARL said that we should read legal value and nothing | ||
13 | says about what we should write. Current behavior change system state | ||
14 | regardless of whether we read this register or not. | ||
15 | |||
16 | Fixes: ac66f2f0 ("target/riscv: pmp: Ignore writes when RW=01") | ||
17 | |||
18 | Signed-off-by: Ivan Klokov <ivan.klokov@syntacore.com> | ||
19 | Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> | ||
20 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
21 | Message-ID: <20231220153205.11072-1-ivan.klokov@syntacore.com> | ||
22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
23 | --- | ||
24 | target/riscv/pmp.c | 2 +- | ||
25 | 1 file changed, 1 insertion(+), 1 deletion(-) | ||
26 | |||
27 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
28 | index XXXXXXX..XXXXXXX 100644 | ||
29 | --- a/target/riscv/pmp.c | ||
30 | +++ b/target/riscv/pmp.c | ||
31 | @@ -XXX,XX +XXX,XX @@ static bool pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val) | ||
32 | /* If !mseccfg.MML then ignore writes with encoding RW=01 */ | ||
33 | if ((val & PMP_WRITE) && !(val & PMP_READ) && | ||
34 | !MSECCFG_MML_ISSET(env)) { | ||
35 | - val &= ~(PMP_WRITE | PMP_READ); | ||
36 | + return false; | ||
37 | } | ||
38 | env->pmp_state.pmp[pmp_index].cfg_reg = val; | ||
39 | pmp_update_rule_addr(env, pmp_index); | ||
40 | -- | ||
41 | 2.43.0 | diff view generated by jsdifflib |