1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Alistair Francis <alistair.francis@wdc.com> |
---|---|---|---|
2 | 2 | ||
3 | The following changes since commit f22833602095b05733bceaddeb20f3edfced3c07: | 3 | The following changes since commit da5006445a92bb7801f54a93452fac63ca2f634c: |
4 | 4 | ||
5 | Merge tag 'pull-target-arm-20220428' of https://git.linaro.org/people/pmaydell/qemu-arm into staging (2022-04-28 08:34:17 -0700) | 5 | Merge tag 'python-pull-request' of https://gitlab.com/jsnow/qemu into staging (2022-04-21 15:16:52 -0700) |
6 | 6 | ||
7 | are available in the Git repository at: | 7 | are available in the Git repository at: |
8 | 8 | ||
9 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220429 | 9 | git@github.com:alistair23/qemu.git tags/pull-riscv-to-apply-20220422-1 |
10 | 10 | ||
11 | for you to fetch changes up to 325b7c4e7582c229d28c47123c3b986ed948eb84: | 11 | for you to fetch changes up to faee5441a038898f64b335dbaecab102ba406552: |
12 | 12 | ||
13 | hw/riscv: Enable TPM backends (2022-04-29 10:48:48 +1000) | 13 | hw/riscv: boot: Support 64bit fdt address. (2022-04-22 10:35:16 +1000) |
14 | 14 | ||
15 | ---------------------------------------------------------------- | 15 | ---------------------------------------------------------------- |
16 | Second RISC-V PR for QEMU 7.1 | 16 | First RISC-V PR for QEMU 7.1 |
17 | 17 | ||
18 | * Improve device tree generation | 18 | * Add support for Ibex SPI to OpenTitan |
19 | * Support configuarable marchid, mvendorid, mipid CSR values | 19 | * Add support for privileged spec version 1.12.0 |
20 | * Add support for the Zbkb, Zbkc, Zbkx, Zknd/Zkne, Zknh, Zksed/Zksh and Zkr extensions | 20 | * Use privileged spec version 1.12.0 for virt machine by default |
21 | * Fix incorrect PTE merge in walk_pte | 21 | * Allow software access to MIP SEIP |
22 | * Add TPM support to the virt board | 22 | * Add initial support for the Sdtrig extension |
23 | * Optimisations for vector extensions | ||
24 | * Improvements to the misa ISA string | ||
25 | * Add isa extenstion strings to the device tree | ||
26 | * Don't allow `-bios` options with KVM machines | ||
27 | * Fix NAPOT range computation overflow | ||
28 | * Fix DT property mmu-type when CPU mmu option is disabled | ||
29 | * Make RISC-V ACLINT mtime MMIO register writable | ||
30 | * Add and enable native debug feature | ||
31 | * Support 64bit fdt address. | ||
23 | 32 | ||
24 | ---------------------------------------------------------------- | 33 | ---------------------------------------------------------------- |
25 | Alistair Francis (6): | 34 | Alistair Francis (2): |
26 | hw/riscv: virt: Add a machine done notifier | 35 | target/riscv: cpu: Fixup indentation |
27 | hw/core: Move the ARM sysbus-fdt to core | 36 | target/riscv: Allow software access to MIP SEIP |
28 | hw/riscv: virt: Create a platform bus | ||
29 | hw/riscv: virt: Add support for generating platform FDT entries | ||
30 | hw/riscv: virt: Add device plug support | ||
31 | hw/riscv: Enable TPM backends | ||
32 | 37 | ||
33 | Bin Meng (2): | 38 | Atish Patra (7): |
34 | hw/riscv: spike: Add '/chosen/stdout-path' in device tree unconditionally | 39 | target/riscv: Define simpler privileged spec version numbering |
35 | hw/riscv: Don't add empty bootargs to device tree | 40 | target/riscv: Add the privileged spec version 1.12.0 |
41 | target/riscv: Introduce privilege version field in the CSR ops. | ||
42 | target/riscv: Add support for mconfigptr | ||
43 | target/riscv: Add *envcfg* CSRs support | ||
44 | target/riscv: Enable privileged spec version 1.12 | ||
45 | target/riscv: Add isa extenstion strings to the device tree | ||
36 | 46 | ||
37 | Frank Chang (1): | 47 | Bin Meng (7): |
38 | target/riscv: Support configuarable marchid, mvendorid, mipid CSR values | 48 | target/riscv: Add initial support for the Sdtrig extension |
49 | target/riscv: debug: Implement debug related TCGCPUOps | ||
50 | target/riscv: cpu: Add a config option for native debug | ||
51 | target/riscv: csr: Hook debug CSR read/write | ||
52 | target/riscv: machine: Add debug state description | ||
53 | target/riscv: cpu: Enable native debug feature | ||
54 | hw/core: tcg-cpu-ops.h: Update comments of debug_check_watchpoint() | ||
55 | |||
56 | Dylan Jhong (1): | ||
57 | hw/riscv: boot: Support 64bit fdt address. | ||
58 | |||
59 | Frank Chang (3): | ||
60 | hw/intc: Add .impl.[min|max]_access_size declaration in RISC-V ACLINT | ||
61 | hw/intc: Support 32/64-bit mtimecmp and mtime accesses in RISC-V ACLINT | ||
62 | hw/intc: Make RISC-V ACLINT mtime MMIO register writable | ||
63 | |||
64 | Jim Shu (1): | ||
65 | hw/intc: riscv_aclint: Add reset function of ACLINT devices | ||
66 | |||
67 | Nicolas Pitre (1): | ||
68 | target/riscv/pmp: fix NAPOT range computation overflow | ||
69 | |||
70 | Niklas Cassel (1): | ||
71 | hw/riscv: virt: fix DT property mmu-type when CPU mmu option is disabled | ||
39 | 72 | ||
40 | Ralf Ramsauer (1): | 73 | Ralf Ramsauer (1): |
41 | target/riscv: Fix incorrect PTE merge in walk_pte | 74 | hw/riscv: virt: Exit if the user provided -bios in combination with KVM |
42 | 75 | ||
43 | Weiwei Li (15): | 76 | Richard Henderson (1): |
44 | target/riscv: rvk: add cfg properties for zbk* and zk* | 77 | target/riscv: Use cpu_loop_exit_restore directly from mmu faults |
45 | target/riscv: rvk: add support for zbkb extension | ||
46 | target/riscv: rvk: add support for zbkc extension | ||
47 | target/riscv: rvk: add support for zbkx extension | ||
48 | crypto: move sm4_sbox from target/arm | ||
49 | target/riscv: rvk: add support for zknd/zkne extension in RV32 | ||
50 | target/riscv: rvk: add support for zkne/zknd extension in RV64 | ||
51 | target/riscv: rvk: add support for sha256 related instructions in zknh extension | ||
52 | target/riscv: rvk: add support for sha512 related instructions for RV32 in zknh extension | ||
53 | target/riscv: rvk: add support for sha512 related instructions for RV64 in zknh extension | ||
54 | target/riscv: rvk: add support for zksed/zksh extension | ||
55 | target/riscv: rvk: add CSR support for Zkr | ||
56 | disas/riscv.c: rvk: add disas support for Zbk* and Zk* instructions | ||
57 | target/riscv: rvk: expose zbk* and zk* properties | ||
58 | target/riscv: add scalar crypto related extenstion strings to isa_string | ||
59 | 78 | ||
60 | docs/system/riscv/virt.rst | 20 ++ | 79 | Tsukasa OI (1): |
61 | include/crypto/sm4.h | 6 + | 80 | target/riscv: misa to ISA string conversion fix |
62 | include/hw/{arm => core}/sysbus-fdt.h | 0 | 81 | |
63 | include/hw/riscv/virt.h | 8 +- | 82 | Weiwei Li (3): |
64 | target/riscv/cpu.h | 17 ++ | 83 | target/riscv: optimize condition assign for scale < 0 |
65 | target/riscv/cpu_bits.h | 9 + | 84 | target/riscv: optimize helper for vmv<nr>r.v |
66 | target/riscv/helper.h | 22 ++ | 85 | target/riscv: fix start byte for vmv<nf>r.v when vstart != 0 |
67 | target/riscv/pmp.h | 8 +- | 86 | |
68 | target/riscv/insn32.decode | 97 ++++++-- | 87 | Wilfred Mallawa (2): |
69 | crypto/sm4.c | 49 ++++ | 88 | hw/ssi: Add Ibex SPI device model |
70 | disas/riscv.c | 173 +++++++++++++- | 89 | riscv: opentitan: Connect opentitan SPI Host |
71 | hw/arm/virt.c | 2 +- | 90 | |
72 | hw/arm/xlnx-versal-virt.c | 1 - | 91 | include/hw/core/tcg-cpu-ops.h | 1 + |
73 | hw/{arm => core}/sysbus-fdt.c | 2 +- | 92 | include/hw/intc/riscv_aclint.h | 1 + |
74 | hw/riscv/microchip_pfsoc.c | 2 +- | 93 | include/hw/riscv/boot.h | 4 +- |
75 | hw/riscv/sifive_u.c | 2 +- | 94 | include/hw/riscv/opentitan.h | 30 +- |
76 | hw/riscv/spike.c | 7 +- | 95 | include/hw/ssi/ibex_spi_host.h | 94 +++++ |
77 | hw/riscv/virt.c | 319 +++++++++++++++++--------- | 96 | target/riscv/cpu.h | 40 ++- |
78 | target/arm/crypto_helper.c | 36 +-- | 97 | target/riscv/cpu_bits.h | 40 +++ |
79 | target/riscv/bitmanip_helper.c | 80 +++++++ | 98 | target/riscv/debug.h | 114 ++++++ |
80 | target/riscv/cpu.c | 58 +++++ | 99 | target/riscv/helper.h | 5 +- |
81 | target/riscv/crypto_helper.c | 302 ++++++++++++++++++++++++ | 100 | hw/intc/riscv_aclint.c | 144 ++++++-- |
82 | target/riscv/csr.c | 118 +++++++++- | 101 | hw/riscv/boot.c | 12 +- |
83 | target/riscv/monitor.c | 11 +- | 102 | hw/riscv/opentitan.c | 36 +- |
84 | target/riscv/op_helper.c | 9 + | 103 | hw/riscv/virt.c | 24 +- |
85 | target/riscv/translate.c | 8 + | 104 | hw/ssi/ibex_spi_host.c | 612 ++++++++++++++++++++++++++++++++ |
86 | target/riscv/insn_trans/trans_rvb.c.inc | 116 ++++++++-- | 105 | target/riscv/cpu.c | 120 ++++++- |
87 | target/riscv/insn_trans/trans_rvk.c.inc | 391 ++++++++++++++++++++++++++++++++ | 106 | target/riscv/cpu_helper.c | 10 +- |
88 | crypto/meson.build | 1 + | 107 | target/riscv/csr.c | 282 +++++++++++++-- |
89 | hw/arm/meson.build | 1 - | 108 | target/riscv/debug.c | 441 +++++++++++++++++++++++ |
90 | hw/core/meson.build | 1 + | 109 | target/riscv/machine.c | 55 +++ |
91 | hw/riscv/Kconfig | 2 + | 110 | target/riscv/pmp.c | 14 +- |
92 | target/riscv/meson.build | 3 +- | 111 | target/riscv/vector_helper.c | 31 +- |
93 | 33 files changed, 1682 insertions(+), 199 deletions(-) | 112 | target/riscv/insn_trans/trans_rvv.c.inc | 25 +- |
94 | create mode 100644 include/crypto/sm4.h | 113 | hw/ssi/meson.build | 1 + |
95 | rename include/hw/{arm => core}/sysbus-fdt.h (100%) | 114 | hw/ssi/trace-events | 7 + |
96 | create mode 100644 crypto/sm4.c | 115 | target/riscv/meson.build | 1 + |
97 | rename hw/{arm => core}/sysbus-fdt.c (99%) | 116 | 25 files changed, 1971 insertions(+), 173 deletions(-) |
98 | create mode 100644 target/riscv/crypto_helper.c | 117 | create mode 100644 include/hw/ssi/ibex_spi_host.h |
99 | create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc | 118 | create mode 100644 target/riscv/debug.h |
119 | create mode 100644 hw/ssi/ibex_spi_host.c | ||
120 | create mode 100644 target/riscv/debug.c | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Wilfred Mallawa <wilfred.mallawa@wdc.com> |
---|---|---|---|
2 | 2 | ||
3 | - share it between target/arm and target/riscv | 3 | Adds the SPI_HOST device model for ibex. The device specification is as per |
4 | [1]. The model has been tested on opentitan with spi_host unit tests | ||
5 | written for TockOS. | ||
4 | 6 | ||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | [1] https://docs.opentitan.org/hw/ip/spi_host/doc/ |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 8 | |
7 | Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> | 9 | Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> |
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 11 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
10 | Message-Id: <20220423023510.30794-6-liweiwei@iscas.ac.cn> | 12 | Message-Id: <20220303045426.511588-1-alistair.francis@opensource.wdc.com> |
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 14 | --- |
13 | include/crypto/sm4.h | 6 +++++ | 15 | include/hw/ssi/ibex_spi_host.h | 94 +++++ |
14 | crypto/sm4.c | 49 ++++++++++++++++++++++++++++++++++++++ | 16 | hw/ssi/ibex_spi_host.c | 612 +++++++++++++++++++++++++++++++++ |
15 | target/arm/crypto_helper.c | 36 +--------------------------- | 17 | hw/ssi/meson.build | 1 + |
16 | crypto/meson.build | 1 + | 18 | hw/ssi/trace-events | 7 + |
17 | 4 files changed, 57 insertions(+), 35 deletions(-) | 19 | 4 files changed, 714 insertions(+) |
18 | create mode 100644 include/crypto/sm4.h | 20 | create mode 100644 include/hw/ssi/ibex_spi_host.h |
19 | create mode 100644 crypto/sm4.c | 21 | create mode 100644 hw/ssi/ibex_spi_host.c |
20 | 22 | ||
21 | diff --git a/include/crypto/sm4.h b/include/crypto/sm4.h | 23 | diff --git a/include/hw/ssi/ibex_spi_host.h b/include/hw/ssi/ibex_spi_host.h |
22 | new file mode 100644 | 24 | new file mode 100644 |
23 | index XXXXXXX..XXXXXXX | 25 | index XXXXXXX..XXXXXXX |
24 | --- /dev/null | 26 | --- /dev/null |
25 | +++ b/include/crypto/sm4.h | 27 | +++ b/include/hw/ssi/ibex_spi_host.h |
26 | @@ -XXX,XX +XXX,XX @@ | 28 | @@ -XXX,XX +XXX,XX @@ |
27 | +#ifndef QEMU_SM4_H | 29 | + |
28 | +#define QEMU_SM4_H | 30 | +/* |
29 | + | 31 | + * QEMU model of the Ibex SPI Controller |
30 | +extern const uint8_t sm4_sbox[256]; | 32 | + * SPEC Reference: https://docs.opentitan.org/hw/ip/spi_host/doc/ |
33 | + * | ||
34 | + * Copyright (C) 2022 Western Digital | ||
35 | + * | ||
36 | + * Permission is hereby granted, free of charge, to any person obtaining a copy | ||
37 | + * of this software and associated documentation files (the "Software"), to deal | ||
38 | + * in the Software without restriction, including without limitation the rights | ||
39 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
40 | + * copies of the Software, and to permit persons to whom the Software is | ||
41 | + * furnished to do so, subject to the following conditions: | ||
42 | + * | ||
43 | + * The above copyright notice and this permission notice shall be included in | ||
44 | + * all copies or substantial portions of the Software. | ||
45 | + * | ||
46 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
47 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
48 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
49 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
50 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
51 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
52 | + * THE SOFTWARE. | ||
53 | + */ | ||
54 | + | ||
55 | +#ifndef IBEX_SPI_HOST_H | ||
56 | +#define IBEX_SPI_HOST_H | ||
57 | + | ||
58 | +#include "hw/sysbus.h" | ||
59 | +#include "hw/hw.h" | ||
60 | +#include "hw/ssi/ssi.h" | ||
61 | +#include "qemu/fifo8.h" | ||
62 | +#include "qom/object.h" | ||
63 | +#include "hw/registerfields.h" | ||
64 | +#include "qemu/timer.h" | ||
65 | + | ||
66 | +#define TYPE_IBEX_SPI_HOST "ibex-spi" | ||
67 | +#define IBEX_SPI_HOST(obj) \ | ||
68 | + OBJECT_CHECK(IbexSPIHostState, (obj), TYPE_IBEX_SPI_HOST) | ||
69 | + | ||
70 | +/* SPI Registers */ | ||
71 | +#define IBEX_SPI_HOST_INTR_STATE (0x00 / 4) /* rw */ | ||
72 | +#define IBEX_SPI_HOST_INTR_ENABLE (0x04 / 4) /* rw */ | ||
73 | +#define IBEX_SPI_HOST_INTR_TEST (0x08 / 4) /* wo */ | ||
74 | +#define IBEX_SPI_HOST_ALERT_TEST (0x0c / 4) /* wo */ | ||
75 | +#define IBEX_SPI_HOST_CONTROL (0x10 / 4) /* rw */ | ||
76 | +#define IBEX_SPI_HOST_STATUS (0x14 / 4) /* ro */ | ||
77 | +#define IBEX_SPI_HOST_CONFIGOPTS (0x18 / 4) /* rw */ | ||
78 | +#define IBEX_SPI_HOST_CSID (0x1c / 4) /* rw */ | ||
79 | +#define IBEX_SPI_HOST_COMMAND (0x20 / 4) /* wo */ | ||
80 | +/* RX/TX Modelled by FIFO */ | ||
81 | +#define IBEX_SPI_HOST_RXDATA (0x24 / 4) | ||
82 | +#define IBEX_SPI_HOST_TXDATA (0x28 / 4) | ||
83 | + | ||
84 | +#define IBEX_SPI_HOST_ERROR_ENABLE (0x2c / 4) /* rw */ | ||
85 | +#define IBEX_SPI_HOST_ERROR_STATUS (0x30 / 4) /* rw */ | ||
86 | +#define IBEX_SPI_HOST_EVENT_ENABLE (0x34 / 4) /* rw */ | ||
87 | + | ||
88 | +/* FIFO Len in Bytes */ | ||
89 | +#define IBEX_SPI_HOST_TXFIFO_LEN 288 | ||
90 | +#define IBEX_SPI_HOST_RXFIFO_LEN 256 | ||
91 | + | ||
92 | +/* Max Register (Based on addr) */ | ||
93 | +#define IBEX_SPI_HOST_MAX_REGS (IBEX_SPI_HOST_EVENT_ENABLE + 1) | ||
94 | + | ||
95 | +/* MISC */ | ||
96 | +#define TX_INTERRUPT_TRIGGER_DELAY_NS 100 | ||
97 | +#define BIDIRECTIONAL_TRANSFER 3 | ||
98 | + | ||
99 | +typedef struct { | ||
100 | + /* <private> */ | ||
101 | + SysBusDevice parent_obj; | ||
102 | + | ||
103 | + /* <public> */ | ||
104 | + MemoryRegion mmio; | ||
105 | + uint32_t regs[IBEX_SPI_HOST_MAX_REGS]; | ||
106 | + /* Multi-reg that sets config opts per CS */ | ||
107 | + uint32_t *config_opts; | ||
108 | + Fifo8 rx_fifo; | ||
109 | + Fifo8 tx_fifo; | ||
110 | + QEMUTimer *fifo_trigger_handle; | ||
111 | + | ||
112 | + qemu_irq event; | ||
113 | + qemu_irq host_err; | ||
114 | + uint32_t num_cs; | ||
115 | + qemu_irq *cs_lines; | ||
116 | + SSIBus *ssi; | ||
117 | + | ||
118 | + /* Used to track the init status, for replicating TXDATA ghost writes */ | ||
119 | + bool init_status; | ||
120 | +} IbexSPIHostState; | ||
31 | + | 121 | + |
32 | +#endif | 122 | +#endif |
33 | diff --git a/crypto/sm4.c b/crypto/sm4.c | 123 | diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c |
34 | new file mode 100644 | 124 | new file mode 100644 |
35 | index XXXXXXX..XXXXXXX | 125 | index XXXXXXX..XXXXXXX |
36 | --- /dev/null | 126 | --- /dev/null |
37 | +++ b/crypto/sm4.c | 127 | +++ b/hw/ssi/ibex_spi_host.c |
38 | @@ -XXX,XX +XXX,XX @@ | 128 | @@ -XXX,XX +XXX,XX @@ |
39 | +/* | 129 | +/* |
40 | + * QEMU crypto sm4 support | 130 | + * QEMU model of the Ibex SPI Controller |
41 | + * | 131 | + * SPEC Reference: https://docs.opentitan.org/hw/ip/spi_host/doc/ |
42 | + * Copyright (C) 2013 - 2018 Linaro Ltd <ard.biesheuvel@linaro.org> | 132 | + * |
43 | + * | 133 | + * Copyright (C) 2022 Western Digital |
44 | + * This library is free software; you can redistribute it and/or | 134 | + * |
45 | + * modify it under the terms of the GNU Lesser General Public | 135 | + * Permission is hereby granted, free of charge, to any person obtaining a copy |
46 | + * License as published by the Free Software Foundation; either | 136 | + * of this software and associated documentation files (the "Software"), to deal |
47 | + * version 2.1 of the License, or (at your option) any later version. | 137 | + * in the Software without restriction, including without limitation the rights |
138 | + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
139 | + * copies of the Software, and to permit persons to whom the Software is | ||
140 | + * furnished to do so, subject to the following conditions: | ||
141 | + * | ||
142 | + * The above copyright notice and this permission notice shall be included in | ||
143 | + * all copies or substantial portions of the Software. | ||
144 | + * | ||
145 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
146 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
147 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
148 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
149 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
150 | + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
151 | + * THE SOFTWARE. | ||
48 | + */ | 152 | + */ |
49 | + | 153 | + |
50 | +#include "qemu/osdep.h" | 154 | +#include "qemu/osdep.h" |
51 | +#include "crypto/sm4.h" | 155 | +#include "qemu/log.h" |
52 | + | 156 | +#include "qemu/module.h" |
53 | +uint8_t const sm4_sbox[] = { | 157 | +#include "hw/ssi/ibex_spi_host.h" |
54 | + 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, | 158 | +#include "hw/irq.h" |
55 | + 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, | 159 | +#include "hw/qdev-properties.h" |
56 | + 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, | 160 | +#include "hw/qdev-properties-system.h" |
57 | + 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, | 161 | +#include "migration/vmstate.h" |
58 | + 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, | 162 | +#include "trace.h" |
59 | + 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, | 163 | + |
60 | + 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, | 164 | +REG32(INTR_STATE, 0x00) |
61 | + 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, | 165 | + FIELD(INTR_STATE, ERROR, 0, 1) |
62 | + 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, | 166 | + FIELD(INTR_STATE, SPI_EVENT, 1, 1) |
63 | + 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, | 167 | +REG32(INTR_ENABLE, 0x04) |
64 | + 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, | 168 | + FIELD(INTR_ENABLE, ERROR, 0, 1) |
65 | + 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, | 169 | + FIELD(INTR_ENABLE, SPI_EVENT, 1, 1) |
66 | + 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, | 170 | +REG32(INTR_TEST, 0x08) |
67 | + 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, | 171 | + FIELD(INTR_TEST, ERROR, 0, 1) |
68 | + 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, | 172 | + FIELD(INTR_TEST, SPI_EVENT, 1, 1) |
69 | + 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, | 173 | +REG32(ALERT_TEST, 0x0c) |
70 | + 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, | 174 | + FIELD(ALERT_TEST, FETAL_TEST, 0, 1) |
71 | + 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, | 175 | +REG32(CONTROL, 0x10) |
72 | + 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, | 176 | + FIELD(CONTROL, RX_WATERMARK, 0, 8) |
73 | + 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, | 177 | + FIELD(CONTROL, TX_WATERMARK, 1, 8) |
74 | + 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, | 178 | + FIELD(CONTROL, OUTPUT_EN, 29, 1) |
75 | + 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, | 179 | + FIELD(CONTROL, SW_RST, 30, 1) |
76 | + 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, | 180 | + FIELD(CONTROL, SPIEN, 31, 1) |
77 | + 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, | 181 | +REG32(STATUS, 0x14) |
78 | + 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, | 182 | + FIELD(STATUS, TXQD, 0, 8) |
79 | + 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, | 183 | + FIELD(STATUS, RXQD, 18, 8) |
80 | + 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, | 184 | + FIELD(STATUS, CMDQD, 16, 3) |
81 | + 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, | 185 | + FIELD(STATUS, RXWM, 20, 1) |
82 | + 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, | 186 | + FIELD(STATUS, BYTEORDER, 22, 1) |
83 | + 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, | 187 | + FIELD(STATUS, RXSTALL, 23, 1) |
84 | + 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, | 188 | + FIELD(STATUS, RXEMPTY, 24, 1) |
85 | + 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, | 189 | + FIELD(STATUS, RXFULL, 25, 1) |
190 | + FIELD(STATUS, TXWM, 26, 1) | ||
191 | + FIELD(STATUS, TXSTALL, 27, 1) | ||
192 | + FIELD(STATUS, TXEMPTY, 28, 1) | ||
193 | + FIELD(STATUS, TXFULL, 29, 1) | ||
194 | + FIELD(STATUS, ACTIVE, 30, 1) | ||
195 | + FIELD(STATUS, READY, 31, 1) | ||
196 | +REG32(CONFIGOPTS, 0x18) | ||
197 | + FIELD(CONFIGOPTS, CLKDIV_0, 0, 16) | ||
198 | + FIELD(CONFIGOPTS, CSNIDLE_0, 16, 4) | ||
199 | + FIELD(CONFIGOPTS, CSNTRAIL_0, 20, 4) | ||
200 | + FIELD(CONFIGOPTS, CSNLEAD_0, 24, 4) | ||
201 | + FIELD(CONFIGOPTS, FULLCYC_0, 29, 1) | ||
202 | + FIELD(CONFIGOPTS, CPHA_0, 30, 1) | ||
203 | + FIELD(CONFIGOPTS, CPOL_0, 31, 1) | ||
204 | +REG32(CSID, 0x1c) | ||
205 | + FIELD(CSID, CSID, 0, 32) | ||
206 | +REG32(COMMAND, 0x20) | ||
207 | + FIELD(COMMAND, LEN, 0, 8) | ||
208 | + FIELD(COMMAND, CSAAT, 9, 1) | ||
209 | + FIELD(COMMAND, SPEED, 10, 2) | ||
210 | + FIELD(COMMAND, DIRECTION, 12, 2) | ||
211 | +REG32(ERROR_ENABLE, 0x2c) | ||
212 | + FIELD(ERROR_ENABLE, CMDBUSY, 0, 1) | ||
213 | + FIELD(ERROR_ENABLE, OVERFLOW, 1, 1) | ||
214 | + FIELD(ERROR_ENABLE, UNDERFLOW, 2, 1) | ||
215 | + FIELD(ERROR_ENABLE, CMDINVAL, 3, 1) | ||
216 | + FIELD(ERROR_ENABLE, CSIDINVAL, 4, 1) | ||
217 | +REG32(ERROR_STATUS, 0x30) | ||
218 | + FIELD(ERROR_STATUS, CMDBUSY, 0, 1) | ||
219 | + FIELD(ERROR_STATUS, OVERFLOW, 1, 1) | ||
220 | + FIELD(ERROR_STATUS, UNDERFLOW, 2, 1) | ||
221 | + FIELD(ERROR_STATUS, CMDINVAL, 3, 1) | ||
222 | + FIELD(ERROR_STATUS, CSIDINVAL, 4, 1) | ||
223 | + FIELD(ERROR_STATUS, ACCESSINVAL, 5, 1) | ||
224 | +REG32(EVENT_ENABLE, 0x30) | ||
225 | + FIELD(EVENT_ENABLE, RXFULL, 0, 1) | ||
226 | + FIELD(EVENT_ENABLE, TXEMPTY, 1, 1) | ||
227 | + FIELD(EVENT_ENABLE, RXWM, 2, 1) | ||
228 | + FIELD(EVENT_ENABLE, TXWM, 3, 1) | ||
229 | + FIELD(EVENT_ENABLE, READY, 4, 1) | ||
230 | + FIELD(EVENT_ENABLE, IDLE, 5, 1) | ||
231 | + | ||
232 | +static inline uint8_t div4_round_up(uint8_t dividend) | ||
233 | +{ | ||
234 | + return (dividend + 3) / 4; | ||
235 | +} | ||
236 | + | ||
237 | +static void ibex_spi_rxfifo_reset(IbexSPIHostState *s) | ||
238 | +{ | ||
239 | + /* Empty the RX FIFO and assert RXEMPTY */ | ||
240 | + fifo8_reset(&s->rx_fifo); | ||
241 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXFULL_MASK; | ||
242 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXEMPTY_MASK; | ||
243 | +} | ||
244 | + | ||
245 | +static void ibex_spi_txfifo_reset(IbexSPIHostState *s) | ||
246 | +{ | ||
247 | + /* Empty the TX FIFO and assert TXEMPTY */ | ||
248 | + fifo8_reset(&s->tx_fifo); | ||
249 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK; | ||
250 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXEMPTY_MASK; | ||
251 | +} | ||
252 | + | ||
253 | +static void ibex_spi_host_reset(DeviceState *dev) | ||
254 | +{ | ||
255 | + IbexSPIHostState *s = IBEX_SPI_HOST(dev); | ||
256 | + trace_ibex_spi_host_reset("Resetting Ibex SPI"); | ||
257 | + | ||
258 | + /* SPI Host Register Reset */ | ||
259 | + s->regs[IBEX_SPI_HOST_INTR_STATE] = 0x00; | ||
260 | + s->regs[IBEX_SPI_HOST_INTR_ENABLE] = 0x00; | ||
261 | + s->regs[IBEX_SPI_HOST_INTR_TEST] = 0x00; | ||
262 | + s->regs[IBEX_SPI_HOST_ALERT_TEST] = 0x00; | ||
263 | + s->regs[IBEX_SPI_HOST_CONTROL] = 0x7f; | ||
264 | + s->regs[IBEX_SPI_HOST_STATUS] = 0x00; | ||
265 | + s->regs[IBEX_SPI_HOST_CONFIGOPTS] = 0x00; | ||
266 | + s->regs[IBEX_SPI_HOST_CSID] = 0x00; | ||
267 | + s->regs[IBEX_SPI_HOST_COMMAND] = 0x00; | ||
268 | + /* RX/TX Modelled by FIFO */ | ||
269 | + s->regs[IBEX_SPI_HOST_RXDATA] = 0x00; | ||
270 | + s->regs[IBEX_SPI_HOST_TXDATA] = 0x00; | ||
271 | + | ||
272 | + s->regs[IBEX_SPI_HOST_ERROR_ENABLE] = 0x1F; | ||
273 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] = 0x00; | ||
274 | + s->regs[IBEX_SPI_HOST_EVENT_ENABLE] = 0x00; | ||
275 | + | ||
276 | + ibex_spi_rxfifo_reset(s); | ||
277 | + ibex_spi_txfifo_reset(s); | ||
278 | + | ||
279 | + s->init_status = true; | ||
280 | + return; | ||
281 | +} | ||
282 | + | ||
283 | +/* | ||
284 | + * Check if we need to trigger an interrupt. | ||
285 | + * The two interrupts lines (host_err and event) can | ||
286 | + * be enabled separately in 'IBEX_SPI_HOST_INTR_ENABLE'. | ||
287 | + * | ||
288 | + * Interrupts are triggered based on the ones | ||
289 | + * enabled in the `IBEX_SPI_HOST_EVENT_ENABLE` and `IBEX_SPI_HOST_ERROR_ENABLE`. | ||
290 | + */ | ||
291 | +static void ibex_spi_host_irq(IbexSPIHostState *s) | ||
292 | +{ | ||
293 | + bool error_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE] | ||
294 | + & R_INTR_ENABLE_ERROR_MASK; | ||
295 | + bool event_en = s->regs[IBEX_SPI_HOST_INTR_ENABLE] | ||
296 | + & R_INTR_ENABLE_SPI_EVENT_MASK; | ||
297 | + bool err_pending = s->regs[IBEX_SPI_HOST_INTR_STATE] | ||
298 | + & R_INTR_STATE_ERROR_MASK; | ||
299 | + bool status_pending = s->regs[IBEX_SPI_HOST_INTR_STATE] | ||
300 | + & R_INTR_STATE_SPI_EVENT_MASK; | ||
301 | + int err_irq = 0, event_irq = 0; | ||
302 | + | ||
303 | + /* Error IRQ enabled and Error IRQ Cleared*/ | ||
304 | + if (error_en && !err_pending) { | ||
305 | + /* Event enabled, Interrupt Test Error */ | ||
306 | + if (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_ERROR_MASK) { | ||
307 | + err_irq = 1; | ||
308 | + } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE] | ||
309 | + & R_ERROR_ENABLE_CMDBUSY_MASK) && | ||
310 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] | ||
311 | + & R_ERROR_STATUS_CMDBUSY_MASK) { | ||
312 | + /* Wrote to COMMAND when not READY */ | ||
313 | + err_irq = 1; | ||
314 | + } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE] | ||
315 | + & R_ERROR_ENABLE_CMDINVAL_MASK) && | ||
316 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] | ||
317 | + & R_ERROR_STATUS_CMDINVAL_MASK) { | ||
318 | + /* Invalid command segment */ | ||
319 | + err_irq = 1; | ||
320 | + } else if ((s->regs[IBEX_SPI_HOST_ERROR_ENABLE] | ||
321 | + & R_ERROR_ENABLE_CSIDINVAL_MASK) && | ||
322 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] | ||
323 | + & R_ERROR_STATUS_CSIDINVAL_MASK) { | ||
324 | + /* Invalid value for CSID */ | ||
325 | + err_irq = 1; | ||
326 | + } | ||
327 | + if (err_irq) { | ||
328 | + s->regs[IBEX_SPI_HOST_INTR_STATE] |= R_INTR_STATE_ERROR_MASK; | ||
329 | + } | ||
330 | + qemu_set_irq(s->host_err, err_irq); | ||
331 | + } | ||
332 | + | ||
333 | + /* Event IRQ Enabled and Event IRQ Cleared */ | ||
334 | + if (event_en && !status_pending) { | ||
335 | + if (s->regs[IBEX_SPI_HOST_INTR_TEST] & R_INTR_TEST_SPI_EVENT_MASK) { | ||
336 | + /* Event enabled, Interrupt Test Event */ | ||
337 | + event_irq = 1; | ||
338 | + } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE] | ||
339 | + & R_EVENT_ENABLE_READY_MASK) && | ||
340 | + (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) { | ||
341 | + /* SPI Host ready for next command */ | ||
342 | + event_irq = 1; | ||
343 | + } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE] | ||
344 | + & R_EVENT_ENABLE_TXEMPTY_MASK) && | ||
345 | + (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_TXEMPTY_MASK)) { | ||
346 | + /* SPI TXEMPTY, TXFIFO drained */ | ||
347 | + event_irq = 1; | ||
348 | + } else if ((s->regs[IBEX_SPI_HOST_EVENT_ENABLE] | ||
349 | + & R_EVENT_ENABLE_RXFULL_MASK) && | ||
350 | + (s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_RXFULL_MASK)) { | ||
351 | + /* SPI RXFULL, RXFIFO full */ | ||
352 | + event_irq = 1; | ||
353 | + } | ||
354 | + if (event_irq) { | ||
355 | + s->regs[IBEX_SPI_HOST_INTR_STATE] |= R_INTR_STATE_SPI_EVENT_MASK; | ||
356 | + } | ||
357 | + qemu_set_irq(s->event, event_irq); | ||
358 | + } | ||
359 | +} | ||
360 | + | ||
361 | +static void ibex_spi_host_transfer(IbexSPIHostState *s) | ||
362 | +{ | ||
363 | + uint32_t rx, tx; | ||
364 | + /* Get num of one byte transfers */ | ||
365 | + uint8_t segment_len = ((s->regs[IBEX_SPI_HOST_COMMAND] & R_COMMAND_LEN_MASK) | ||
366 | + >> R_COMMAND_LEN_SHIFT); | ||
367 | + while (segment_len > 0) { | ||
368 | + if (fifo8_is_empty(&s->tx_fifo)) { | ||
369 | + /* Assert Stall */ | ||
370 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXSTALL_MASK; | ||
371 | + break; | ||
372 | + } else if (fifo8_is_full(&s->rx_fifo)) { | ||
373 | + /* Assert Stall */ | ||
374 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXSTALL_MASK; | ||
375 | + break; | ||
376 | + } else { | ||
377 | + tx = fifo8_pop(&s->tx_fifo); | ||
378 | + } | ||
379 | + | ||
380 | + rx = ssi_transfer(s->ssi, tx); | ||
381 | + | ||
382 | + trace_ibex_spi_host_transfer(tx, rx); | ||
383 | + | ||
384 | + if (!fifo8_is_full(&s->rx_fifo)) { | ||
385 | + fifo8_push(&s->rx_fifo, rx); | ||
386 | + } else { | ||
387 | + /* Assert RXFULL */ | ||
388 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXFULL_MASK; | ||
389 | + } | ||
390 | + --segment_len; | ||
391 | + } | ||
392 | + | ||
393 | + /* Assert Ready */ | ||
394 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK; | ||
395 | + /* Set RXQD */ | ||
396 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXQD_MASK; | ||
397 | + s->regs[IBEX_SPI_HOST_STATUS] |= (R_STATUS_RXQD_MASK | ||
398 | + & div4_round_up(segment_len)); | ||
399 | + /* Set TXQD */ | ||
400 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK; | ||
401 | + s->regs[IBEX_SPI_HOST_STATUS] |= (fifo8_num_used(&s->tx_fifo) / 4) | ||
402 | + & R_STATUS_TXQD_MASK; | ||
403 | + /* Clear TXFULL */ | ||
404 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXFULL_MASK; | ||
405 | + /* Assert TXEMPTY and drop remaining bytes that exceed segment_len */ | ||
406 | + ibex_spi_txfifo_reset(s); | ||
407 | + /* Reset RXEMPTY */ | ||
408 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXEMPTY_MASK; | ||
409 | + | ||
410 | + ibex_spi_host_irq(s); | ||
411 | +} | ||
412 | + | ||
413 | +static uint64_t ibex_spi_host_read(void *opaque, hwaddr addr, | ||
414 | + unsigned int size) | ||
415 | +{ | ||
416 | + IbexSPIHostState *s = opaque; | ||
417 | + uint32_t rc = 0; | ||
418 | + uint8_t rx_byte = 0; | ||
419 | + | ||
420 | + trace_ibex_spi_host_read(addr, size); | ||
421 | + | ||
422 | + /* Match reg index */ | ||
423 | + addr = addr >> 2; | ||
424 | + switch (addr) { | ||
425 | + /* Skipping any W/O registers */ | ||
426 | + case IBEX_SPI_HOST_INTR_STATE...IBEX_SPI_HOST_INTR_ENABLE: | ||
427 | + case IBEX_SPI_HOST_CONTROL...IBEX_SPI_HOST_STATUS: | ||
428 | + rc = s->regs[addr]; | ||
429 | + break; | ||
430 | + case IBEX_SPI_HOST_CSID: | ||
431 | + rc = s->regs[addr]; | ||
432 | + break; | ||
433 | + case IBEX_SPI_HOST_CONFIGOPTS: | ||
434 | + rc = s->config_opts[s->regs[IBEX_SPI_HOST_CSID]]; | ||
435 | + break; | ||
436 | + case IBEX_SPI_HOST_TXDATA: | ||
437 | + rc = s->regs[addr]; | ||
438 | + break; | ||
439 | + case IBEX_SPI_HOST_RXDATA: | ||
440 | + /* Clear RXFULL */ | ||
441 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_RXFULL_MASK; | ||
442 | + | ||
443 | + for (int i = 0; i < 4; ++i) { | ||
444 | + if (fifo8_is_empty(&s->rx_fifo)) { | ||
445 | + /* Assert RXEMPTY, no IRQ */ | ||
446 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_RXEMPTY_MASK; | ||
447 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= | ||
448 | + R_ERROR_STATUS_UNDERFLOW_MASK; | ||
449 | + return rc; | ||
450 | + } | ||
451 | + rx_byte = fifo8_pop(&s->rx_fifo); | ||
452 | + rc |= rx_byte << (i * 8); | ||
453 | + } | ||
454 | + break; | ||
455 | + case IBEX_SPI_HOST_ERROR_ENABLE...IBEX_SPI_HOST_EVENT_ENABLE: | ||
456 | + rc = s->regs[addr]; | ||
457 | + break; | ||
458 | + default: | ||
459 | + qemu_log_mask(LOG_GUEST_ERROR, "Bad offset 0x%" HWADDR_PRIx "\n", | ||
460 | + addr << 2); | ||
461 | + } | ||
462 | + return rc; | ||
463 | +} | ||
464 | + | ||
465 | + | ||
466 | +static void ibex_spi_host_write(void *opaque, hwaddr addr, | ||
467 | + uint64_t val64, unsigned int size) | ||
468 | +{ | ||
469 | + IbexSPIHostState *s = opaque; | ||
470 | + uint32_t val32 = val64; | ||
471 | + uint32_t shift_mask = 0xff; | ||
472 | + uint8_t txqd_len; | ||
473 | + | ||
474 | + trace_ibex_spi_host_write(addr, size, val64); | ||
475 | + | ||
476 | + /* Match reg index */ | ||
477 | + addr = addr >> 2; | ||
478 | + | ||
479 | + switch (addr) { | ||
480 | + /* Skipping any R/O registers */ | ||
481 | + case IBEX_SPI_HOST_INTR_STATE...IBEX_SPI_HOST_INTR_ENABLE: | ||
482 | + s->regs[addr] = val32; | ||
483 | + break; | ||
484 | + case IBEX_SPI_HOST_INTR_TEST: | ||
485 | + s->regs[addr] = val32; | ||
486 | + ibex_spi_host_irq(s); | ||
487 | + break; | ||
488 | + case IBEX_SPI_HOST_ALERT_TEST: | ||
489 | + s->regs[addr] = val32; | ||
490 | + qemu_log_mask(LOG_UNIMP, | ||
491 | + "%s: SPI_ALERT_TEST is not supported\n", __func__); | ||
492 | + break; | ||
493 | + case IBEX_SPI_HOST_CONTROL: | ||
494 | + s->regs[addr] = val32; | ||
495 | + | ||
496 | + if (val32 & R_CONTROL_SW_RST_MASK) { | ||
497 | + ibex_spi_host_reset((DeviceState *)s); | ||
498 | + /* Clear active if any */ | ||
499 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_ACTIVE_MASK; | ||
500 | + } | ||
501 | + | ||
502 | + if (val32 & R_CONTROL_OUTPUT_EN_MASK) { | ||
503 | + qemu_log_mask(LOG_UNIMP, | ||
504 | + "%s: CONTROL_OUTPUT_EN is not supported\n", __func__); | ||
505 | + } | ||
506 | + break; | ||
507 | + case IBEX_SPI_HOST_CONFIGOPTS: | ||
508 | + /* Update the respective config-opts register based on CSIDth index */ | ||
509 | + s->config_opts[s->regs[IBEX_SPI_HOST_CSID]] = val32; | ||
510 | + qemu_log_mask(LOG_UNIMP, | ||
511 | + "%s: CONFIGOPTS Hardware settings not supported\n", | ||
512 | + __func__); | ||
513 | + break; | ||
514 | + case IBEX_SPI_HOST_CSID: | ||
515 | + if (val32 >= s->num_cs) { | ||
516 | + /* CSID exceeds max num_cs */ | ||
517 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= | ||
518 | + R_ERROR_STATUS_CSIDINVAL_MASK; | ||
519 | + ibex_spi_host_irq(s); | ||
520 | + return; | ||
521 | + } | ||
522 | + s->regs[addr] = val32; | ||
523 | + break; | ||
524 | + case IBEX_SPI_HOST_COMMAND: | ||
525 | + s->regs[addr] = val32; | ||
526 | + | ||
527 | + /* STALL, IP not enabled */ | ||
528 | + if (!(s->regs[IBEX_SPI_HOST_CONTROL] & R_CONTROL_SPIEN_MASK)) { | ||
529 | + return; | ||
530 | + } | ||
531 | + | ||
532 | + /* SPI not ready, IRQ Error */ | ||
533 | + if (!(s->regs[IBEX_SPI_HOST_STATUS] & R_STATUS_READY_MASK)) { | ||
534 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= R_ERROR_STATUS_CMDBUSY_MASK; | ||
535 | + ibex_spi_host_irq(s); | ||
536 | + return; | ||
537 | + } | ||
538 | + /* Assert Not Ready */ | ||
539 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_READY_MASK; | ||
540 | + | ||
541 | + if (((val32 & R_COMMAND_DIRECTION_MASK) >> R_COMMAND_DIRECTION_SHIFT) | ||
542 | + != BIDIRECTIONAL_TRANSFER) { | ||
543 | + qemu_log_mask(LOG_UNIMP, | ||
544 | + "%s: Rx Only/Tx Only are not supported\n", __func__); | ||
545 | + } | ||
546 | + | ||
547 | + if (val32 & R_COMMAND_CSAAT_MASK) { | ||
548 | + qemu_log_mask(LOG_UNIMP, | ||
549 | + "%s: CSAAT is not supported\n", __func__); | ||
550 | + } | ||
551 | + if (val32 & R_COMMAND_SPEED_MASK) { | ||
552 | + qemu_log_mask(LOG_UNIMP, | ||
553 | + "%s: SPEED is not supported\n", __func__); | ||
554 | + } | ||
555 | + | ||
556 | + /* Set Transfer Callback */ | ||
557 | + timer_mod(s->fifo_trigger_handle, | ||
558 | + qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + | ||
559 | + (TX_INTERRUPT_TRIGGER_DELAY_NS)); | ||
560 | + | ||
561 | + break; | ||
562 | + case IBEX_SPI_HOST_TXDATA: | ||
563 | + /* | ||
564 | + * This is a hardware `feature` where | ||
565 | + * the first word written TXDATA after init is omitted entirely | ||
566 | + */ | ||
567 | + if (s->init_status) { | ||
568 | + s->init_status = false; | ||
569 | + return; | ||
570 | + } | ||
571 | + | ||
572 | + for (int i = 0; i < 4; ++i) { | ||
573 | + /* Attempting to write when TXFULL */ | ||
574 | + if (fifo8_is_full(&s->tx_fifo)) { | ||
575 | + /* Assert RXEMPTY, no IRQ */ | ||
576 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_TXFULL_MASK; | ||
577 | + s->regs[IBEX_SPI_HOST_ERROR_STATUS] |= | ||
578 | + R_ERROR_STATUS_OVERFLOW_MASK; | ||
579 | + ibex_spi_host_irq(s); | ||
580 | + return; | ||
581 | + } | ||
582 | + /* Byte ordering is set by the IP */ | ||
583 | + if ((s->regs[IBEX_SPI_HOST_STATUS] & | ||
584 | + R_STATUS_BYTEORDER_MASK) == 0) { | ||
585 | + /* LE: LSB transmitted first (default for ibex processor) */ | ||
586 | + shift_mask = 0xff << (i * 8); | ||
587 | + } else { | ||
588 | + /* BE: MSB transmitted first */ | ||
589 | + qemu_log_mask(LOG_UNIMP, | ||
590 | + "%s: Big endian is not supported\n", __func__); | ||
591 | + } | ||
592 | + | ||
593 | + fifo8_push(&s->tx_fifo, (val32 & shift_mask) >> (i * 8)); | ||
594 | + } | ||
595 | + | ||
596 | + /* Reset TXEMPTY */ | ||
597 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXEMPTY_MASK; | ||
598 | + /* Update TXQD */ | ||
599 | + txqd_len = (s->regs[IBEX_SPI_HOST_STATUS] & | ||
600 | + R_STATUS_TXQD_MASK) >> R_STATUS_TXQD_SHIFT; | ||
601 | + /* Partial bytes (size < 4) are padded, in words. */ | ||
602 | + txqd_len += 1; | ||
603 | + s->regs[IBEX_SPI_HOST_STATUS] &= ~R_STATUS_TXQD_MASK; | ||
604 | + s->regs[IBEX_SPI_HOST_STATUS] |= txqd_len; | ||
605 | + /* Assert Ready */ | ||
606 | + s->regs[IBEX_SPI_HOST_STATUS] |= R_STATUS_READY_MASK; | ||
607 | + break; | ||
608 | + case IBEX_SPI_HOST_ERROR_ENABLE: | ||
609 | + s->regs[addr] = val32; | ||
610 | + | ||
611 | + if (val32 & R_ERROR_ENABLE_CMDINVAL_MASK) { | ||
612 | + qemu_log_mask(LOG_UNIMP, | ||
613 | + "%s: Segment Length is not supported\n", __func__); | ||
614 | + } | ||
615 | + break; | ||
616 | + case IBEX_SPI_HOST_ERROR_STATUS: | ||
617 | + /* | ||
618 | + * Indicates that any errors that have occurred. | ||
619 | + * When an error occurs, the corresponding bit must be cleared | ||
620 | + * here before issuing any further commands | ||
621 | + */ | ||
622 | + s->regs[addr] = val32; | ||
623 | + break; | ||
624 | + case IBEX_SPI_HOST_EVENT_ENABLE: | ||
625 | + /* Controls which classes of SPI events raise an interrupt. */ | ||
626 | + s->regs[addr] = val32; | ||
627 | + | ||
628 | + if (val32 & R_EVENT_ENABLE_RXWM_MASK) { | ||
629 | + qemu_log_mask(LOG_UNIMP, | ||
630 | + "%s: RXWM is not supported\n", __func__); | ||
631 | + } | ||
632 | + if (val32 & R_EVENT_ENABLE_TXWM_MASK) { | ||
633 | + qemu_log_mask(LOG_UNIMP, | ||
634 | + "%s: TXWM is not supported\n", __func__); | ||
635 | + } | ||
636 | + | ||
637 | + if (val32 & R_EVENT_ENABLE_IDLE_MASK) { | ||
638 | + qemu_log_mask(LOG_UNIMP, | ||
639 | + "%s: IDLE is not supported\n", __func__); | ||
640 | + } | ||
641 | + break; | ||
642 | + default: | ||
643 | + qemu_log_mask(LOG_GUEST_ERROR, "Bad offset 0x%" HWADDR_PRIx "\n", | ||
644 | + addr << 2); | ||
645 | + } | ||
646 | +} | ||
647 | + | ||
648 | +static const MemoryRegionOps ibex_spi_ops = { | ||
649 | + .read = ibex_spi_host_read, | ||
650 | + .write = ibex_spi_host_write, | ||
651 | + /* Ibex default LE */ | ||
652 | + .endianness = DEVICE_LITTLE_ENDIAN, | ||
86 | +}; | 653 | +}; |
87 | + | 654 | + |
88 | diff --git a/target/arm/crypto_helper.c b/target/arm/crypto_helper.c | 655 | +static Property ibex_spi_properties[] = { |
656 | + DEFINE_PROP_UINT32("num_cs", IbexSPIHostState, num_cs, 1), | ||
657 | + DEFINE_PROP_END_OF_LIST(), | ||
658 | +}; | ||
659 | + | ||
660 | +static const VMStateDescription vmstate_ibex = { | ||
661 | + .name = TYPE_IBEX_SPI_HOST, | ||
662 | + .version_id = 1, | ||
663 | + .minimum_version_id = 1, | ||
664 | + .fields = (VMStateField[]) { | ||
665 | + VMSTATE_UINT32_ARRAY(regs, IbexSPIHostState, IBEX_SPI_HOST_MAX_REGS), | ||
666 | + VMSTATE_VARRAY_UINT32(config_opts, IbexSPIHostState, | ||
667 | + num_cs, 0, vmstate_info_uint32, uint32_t), | ||
668 | + VMSTATE_FIFO8(rx_fifo, IbexSPIHostState), | ||
669 | + VMSTATE_FIFO8(tx_fifo, IbexSPIHostState), | ||
670 | + VMSTATE_TIMER_PTR(fifo_trigger_handle, IbexSPIHostState), | ||
671 | + VMSTATE_BOOL(init_status, IbexSPIHostState), | ||
672 | + VMSTATE_END_OF_LIST() | ||
673 | + } | ||
674 | +}; | ||
675 | + | ||
676 | +static void fifo_trigger_update(void *opaque) | ||
677 | +{ | ||
678 | + IbexSPIHostState *s = opaque; | ||
679 | + ibex_spi_host_transfer(s); | ||
680 | +} | ||
681 | + | ||
682 | +static void ibex_spi_host_realize(DeviceState *dev, Error **errp) | ||
683 | +{ | ||
684 | + IbexSPIHostState *s = IBEX_SPI_HOST(dev); | ||
685 | + int i; | ||
686 | + | ||
687 | + s->ssi = ssi_create_bus(dev, "ssi"); | ||
688 | + s->cs_lines = g_new0(qemu_irq, s->num_cs); | ||
689 | + | ||
690 | + for (i = 0; i < s->num_cs; ++i) { | ||
691 | + sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cs_lines[i]); | ||
692 | + } | ||
693 | + | ||
694 | + /* Setup CONFIGOPTS Multi-register */ | ||
695 | + s->config_opts = g_new0(uint32_t, s->num_cs); | ||
696 | + | ||
697 | + /* Setup FIFO Interrupt Timer */ | ||
698 | + s->fifo_trigger_handle = timer_new_ns(QEMU_CLOCK_VIRTUAL, | ||
699 | + fifo_trigger_update, s); | ||
700 | + | ||
701 | + /* FIFO sizes as per OT Spec */ | ||
702 | + fifo8_create(&s->tx_fifo, IBEX_SPI_HOST_TXFIFO_LEN); | ||
703 | + fifo8_create(&s->rx_fifo, IBEX_SPI_HOST_RXFIFO_LEN); | ||
704 | +} | ||
705 | + | ||
706 | +static void ibex_spi_host_init(Object *obj) | ||
707 | +{ | ||
708 | + IbexSPIHostState *s = IBEX_SPI_HOST(obj); | ||
709 | + | ||
710 | + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->host_err); | ||
711 | + sysbus_init_irq(SYS_BUS_DEVICE(obj), &s->event); | ||
712 | + | ||
713 | + memory_region_init_io(&s->mmio, obj, &ibex_spi_ops, s, | ||
714 | + TYPE_IBEX_SPI_HOST, 0x1000); | ||
715 | + sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); | ||
716 | +} | ||
717 | + | ||
718 | +static void ibex_spi_host_class_init(ObjectClass *klass, void *data) | ||
719 | +{ | ||
720 | + DeviceClass *dc = DEVICE_CLASS(klass); | ||
721 | + dc->realize = ibex_spi_host_realize; | ||
722 | + dc->reset = ibex_spi_host_reset; | ||
723 | + dc->vmsd = &vmstate_ibex; | ||
724 | + device_class_set_props(dc, ibex_spi_properties); | ||
725 | +} | ||
726 | + | ||
727 | +static const TypeInfo ibex_spi_host_info = { | ||
728 | + .name = TYPE_IBEX_SPI_HOST, | ||
729 | + .parent = TYPE_SYS_BUS_DEVICE, | ||
730 | + .instance_size = sizeof(IbexSPIHostState), | ||
731 | + .instance_init = ibex_spi_host_init, | ||
732 | + .class_init = ibex_spi_host_class_init, | ||
733 | +}; | ||
734 | + | ||
735 | +static void ibex_spi_host_register_types(void) | ||
736 | +{ | ||
737 | + type_register_static(&ibex_spi_host_info); | ||
738 | +} | ||
739 | + | ||
740 | +type_init(ibex_spi_host_register_types) | ||
741 | diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build | ||
89 | index XXXXXXX..XXXXXXX 100644 | 742 | index XXXXXXX..XXXXXXX 100644 |
90 | --- a/target/arm/crypto_helper.c | 743 | --- a/hw/ssi/meson.build |
91 | +++ b/target/arm/crypto_helper.c | 744 | +++ b/hw/ssi/meson.build |
92 | @@ -XXX,XX +XXX,XX @@ | 745 | @@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_XILINX_SPIPS', if_true: files('xilinx_spips.c')) |
93 | #include "exec/helper-proto.h" | 746 | softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-ospi.c')) |
94 | #include "tcg/tcg-gvec-desc.h" | 747 | softmmu_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c')) |
95 | #include "crypto/aes.h" | 748 | softmmu_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_spi.c')) |
96 | +#include "crypto/sm4.h" | 749 | +softmmu_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c')) |
97 | #include "vec_internal.h" | 750 | diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events |
98 | |||
99 | union CRYPTO_STATE { | ||
100 | @@ -XXX,XX +XXX,XX @@ DO_SM3TT(crypto_sm3tt2b, 3) | ||
101 | |||
102 | #undef DO_SM3TT | ||
103 | |||
104 | -static uint8_t const sm4_sbox[] = { | ||
105 | - 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, | ||
106 | - 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, | ||
107 | - 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, | ||
108 | - 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, | ||
109 | - 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, | ||
110 | - 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, | ||
111 | - 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, | ||
112 | - 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, | ||
113 | - 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, | ||
114 | - 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, | ||
115 | - 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, | ||
116 | - 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, | ||
117 | - 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, | ||
118 | - 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, | ||
119 | - 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, | ||
120 | - 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, | ||
121 | - 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, | ||
122 | - 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, | ||
123 | - 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, | ||
124 | - 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, | ||
125 | - 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, | ||
126 | - 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, | ||
127 | - 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, | ||
128 | - 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, | ||
129 | - 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, | ||
130 | - 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, | ||
131 | - 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, | ||
132 | - 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, | ||
133 | - 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, | ||
134 | - 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, | ||
135 | - 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, | ||
136 | - 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, | ||
137 | -}; | ||
138 | - | ||
139 | static void do_crypto_sm4e(uint64_t *rd, uint64_t *rn, uint64_t *rm) | ||
140 | { | ||
141 | union CRYPTO_STATE d = { .l = { rn[0], rn[1] } }; | ||
142 | diff --git a/crypto/meson.build b/crypto/meson.build | ||
143 | index XXXXXXX..XXXXXXX 100644 | 751 | index XXXXXXX..XXXXXXX 100644 |
144 | --- a/crypto/meson.build | 752 | --- a/hw/ssi/trace-events |
145 | +++ b/crypto/meson.build | 753 | +++ b/hw/ssi/trace-events |
146 | @@ -XXX,XX +XXX,XX @@ if have_afalg | 754 | @@ -XXX,XX +XXX,XX @@ npcm7xx_fiu_ctrl_read(const char *id, uint64_t addr, uint32_t data) "%s offset: |
147 | endif | 755 | npcm7xx_fiu_ctrl_write(const char *id, uint64_t addr, uint32_t data) "%s offset: 0x%04" PRIx64 " value: 0x%08" PRIx32 |
148 | crypto_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c')) | 756 | npcm7xx_fiu_flash_read(const char *id, int cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64 |
149 | 757 | npcm7xx_fiu_flash_write(const char *id, unsigned cs, uint64_t addr, unsigned int size, uint64_t value) "%s[%d] offset: 0x%08" PRIx64 " size: %u value: 0x%" PRIx64 | |
150 | +util_ss.add(files('sm4.c')) | 758 | + |
151 | util_ss.add(files('aes.c')) | 759 | +# ibex_spi_host.c |
152 | util_ss.add(files('init.c')) | 760 | + |
153 | if gnutls.found() | 761 | +ibex_spi_host_reset(const char *msg) "%s" |
762 | +ibex_spi_host_transfer(uint32_t tx_data, uint32_t rx_data) "tx_data: 0x%" PRIx32 " rx_data: @0x%" PRIx32 | ||
763 | +ibex_spi_host_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64 | ||
764 | +ibex_spi_host_read(uint64_t addr, uint32_t size) "@0x%" PRIx64 " size %u:" | ||
154 | -- | 765 | -- |
155 | 2.35.1 | 766 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Wilfred Mallawa <wilfred.mallawa@wdc.com> |
---|---|---|---|
2 | 2 | ||
3 | Create a platform bus to allow dynamic devices to be connected. This is | 3 | Connect spi host[1/0] to opentitan. |
4 | based on the ARM implementation. | ||
5 | 4 | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 5 | Signed-off-by: Wilfred Mallawa <wilfred.mallawa@wdc.com> |
7 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | 6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 7 | Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> |
9 | Message-Id: <20220427234146.1130752-4-alistair.francis@opensource.wdc.com> | 8 | Message-Id: <20220303045426.511588-2-alistair.francis@opensource.wdc.com> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 10 | --- |
12 | include/hw/riscv/virt.h | 7 ++++- | 11 | include/hw/riscv/opentitan.h | 30 +++++++++++++++++++++--------- |
13 | hw/riscv/virt.c | 68 +++++++++++++++++++++++++++++------------ | 12 | hw/riscv/opentitan.c | 36 ++++++++++++++++++++++++++++++++---- |
14 | hw/riscv/Kconfig | 1 + | 13 | 2 files changed, 53 insertions(+), 13 deletions(-) |
15 | 3 files changed, 56 insertions(+), 20 deletions(-) | ||
16 | 14 | ||
17 | diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h | 15 | diff --git a/include/hw/riscv/opentitan.h b/include/hw/riscv/opentitan.h |
18 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/include/hw/riscv/virt.h | 17 | --- a/include/hw/riscv/opentitan.h |
20 | +++ b/include/hw/riscv/virt.h | 18 | +++ b/include/hw/riscv/opentitan.h |
21 | @@ -XXX,XX +XXX,XX @@ struct RISCVVirtState { | 19 | @@ -XXX,XX +XXX,XX @@ |
22 | 20 | #include "hw/intc/sifive_plic.h" | |
23 | /*< public >*/ | 21 | #include "hw/char/ibex_uart.h" |
24 | Notifier machine_done; | 22 | #include "hw/timer/ibex_timer.h" |
25 | + DeviceState *platform_bus_dev; | 23 | +#include "hw/ssi/ibex_spi_host.h" |
26 | RISCVHartArrayState soc[VIRT_SOCKETS_MAX]; | 24 | #include "qom/object.h" |
27 | DeviceState *irqchip[VIRT_SOCKETS_MAX]; | 25 | |
28 | PFlashCFI01 *flash[2]; | 26 | #define TYPE_RISCV_IBEX_SOC "riscv.lowrisc.ibex.soc" |
27 | OBJECT_DECLARE_SIMPLE_TYPE(LowRISCIbexSoCState, RISCV_IBEX_SOC) | ||
28 | |||
29 | +enum { | ||
30 | + OPENTITAN_SPI_HOST0, | ||
31 | + OPENTITAN_SPI_HOST1, | ||
32 | + OPENTITAN_NUM_SPI_HOSTS, | ||
33 | +}; | ||
34 | + | ||
35 | struct LowRISCIbexSoCState { | ||
36 | /*< private >*/ | ||
37 | SysBusDevice parent_obj; | ||
38 | @@ -XXX,XX +XXX,XX @@ struct LowRISCIbexSoCState { | ||
39 | SiFivePLICState plic; | ||
40 | IbexUartState uart; | ||
41 | IbexTimerState timer; | ||
42 | + IbexSPIHostState spi_host[OPENTITAN_NUM_SPI_HOSTS]; | ||
43 | |||
44 | MemoryRegion flash_mem; | ||
45 | MemoryRegion rom; | ||
29 | @@ -XXX,XX +XXX,XX @@ enum { | 46 | @@ -XXX,XX +XXX,XX @@ enum { |
30 | VIRT_DRAM, | ||
31 | VIRT_PCIE_MMIO, | ||
32 | VIRT_PCIE_PIO, | ||
33 | + VIRT_PLATFORM_BUS, | ||
34 | VIRT_PCIE_ECAM | ||
35 | }; | 47 | }; |
36 | 48 | ||
37 | @@ -XXX,XX +XXX,XX @@ enum { | 49 | enum { |
38 | VIRTIO_IRQ = 1, /* 1 to 8 */ | 50 | - IBEX_TIMER_TIMEREXPIRED0_0 = 126, |
39 | VIRTIO_COUNT = 8, | 51 | - IBEX_UART0_RX_PARITY_ERR_IRQ = 8, |
40 | PCIE_IRQ = 0x20, /* 32 to 35 */ | 52 | - IBEX_UART0_RX_TIMEOUT_IRQ = 7, |
41 | - VIRTIO_NDEV = 0x35 /* Arbitrary maximum number of interrupts */ | 53 | - IBEX_UART0_RX_BREAK_ERR_IRQ = 6, |
42 | + VIRT_PLATFORM_BUS_IRQ = 64, /* 64 to 96 */ | 54 | - IBEX_UART0_RX_FRAME_ERR_IRQ = 5, |
43 | + VIRTIO_NDEV = 96 /* Arbitrary maximum number of interrupts */ | 55 | - IBEX_UART0_RX_OVERFLOW_IRQ = 4, |
56 | - IBEX_UART0_TX_EMPTY_IRQ = 3, | ||
57 | - IBEX_UART0_RX_WATERMARK_IRQ = 2, | ||
58 | - IBEX_UART0_TX_WATERMARK_IRQ = 1, | ||
59 | + IBEX_UART0_TX_WATERMARK_IRQ = 1, | ||
60 | + IBEX_UART0_RX_WATERMARK_IRQ = 2, | ||
61 | + IBEX_UART0_TX_EMPTY_IRQ = 3, | ||
62 | + IBEX_UART0_RX_OVERFLOW_IRQ = 4, | ||
63 | + IBEX_UART0_RX_FRAME_ERR_IRQ = 5, | ||
64 | + IBEX_UART0_RX_BREAK_ERR_IRQ = 6, | ||
65 | + IBEX_UART0_RX_TIMEOUT_IRQ = 7, | ||
66 | + IBEX_UART0_RX_PARITY_ERR_IRQ = 8, | ||
67 | + IBEX_TIMER_TIMEREXPIRED0_0 = 126, | ||
68 | + IBEX_SPI_HOST0_ERR_IRQ = 150, | ||
69 | + IBEX_SPI_HOST0_SPI_EVENT_IRQ = 151, | ||
70 | + IBEX_SPI_HOST1_ERR_IRQ = 152, | ||
71 | + IBEX_SPI_HOST1_SPI_EVENT_IRQ = 153, | ||
44 | }; | 72 | }; |
45 | 73 | ||
46 | +#define VIRT_PLATFORM_BUS_NUM_IRQS 32 | 74 | #endif |
75 | diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c | ||
76 | index XXXXXXX..XXXXXXX 100644 | ||
77 | --- a/hw/riscv/opentitan.c | ||
78 | +++ b/hw/riscv/opentitan.c | ||
79 | @@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_init(Object *obj) | ||
80 | object_initialize_child(obj, "uart", &s->uart, TYPE_IBEX_UART); | ||
81 | |||
82 | object_initialize_child(obj, "timer", &s->timer, TYPE_IBEX_TIMER); | ||
47 | + | 83 | + |
48 | #define VIRT_IRQCHIP_IPI_MSI 1 | 84 | + for (int i = 0; i < OPENTITAN_NUM_SPI_HOSTS; i++) { |
49 | #define VIRT_IRQCHIP_NUM_MSIS 255 | 85 | + object_initialize_child(obj, "spi_host[*]", &s->spi_host[i], |
50 | #define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV | 86 | + TYPE_IBEX_SPI_HOST); |
51 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 87 | + } |
52 | index XXXXXXX..XXXXXXX 100644 | ||
53 | --- a/hw/riscv/virt.c | ||
54 | +++ b/hw/riscv/virt.c | ||
55 | @@ -XXX,XX +XXX,XX @@ | ||
56 | #include "hw/intc/riscv_imsic.h" | ||
57 | #include "hw/intc/sifive_plic.h" | ||
58 | #include "hw/misc/sifive_test.h" | ||
59 | +#include "hw/platform-bus.h" | ||
60 | #include "chardev/char.h" | ||
61 | #include "sysemu/device_tree.h" | ||
62 | #include "sysemu/sysemu.h" | ||
63 | @@ -XXX,XX +XXX,XX @@ | ||
64 | #endif | ||
65 | |||
66 | static const MemMapEntry virt_memmap[] = { | ||
67 | - [VIRT_DEBUG] = { 0x0, 0x100 }, | ||
68 | - [VIRT_MROM] = { 0x1000, 0xf000 }, | ||
69 | - [VIRT_TEST] = { 0x100000, 0x1000 }, | ||
70 | - [VIRT_RTC] = { 0x101000, 0x1000 }, | ||
71 | - [VIRT_CLINT] = { 0x2000000, 0x10000 }, | ||
72 | - [VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 }, | ||
73 | - [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, | ||
74 | - [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) }, | ||
75 | - [VIRT_APLIC_M] = { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) }, | ||
76 | - [VIRT_APLIC_S] = { 0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) }, | ||
77 | - [VIRT_UART0] = { 0x10000000, 0x100 }, | ||
78 | - [VIRT_VIRTIO] = { 0x10001000, 0x1000 }, | ||
79 | - [VIRT_FW_CFG] = { 0x10100000, 0x18 }, | ||
80 | - [VIRT_FLASH] = { 0x20000000, 0x4000000 }, | ||
81 | - [VIRT_IMSIC_M] = { 0x24000000, VIRT_IMSIC_MAX_SIZE }, | ||
82 | - [VIRT_IMSIC_S] = { 0x28000000, VIRT_IMSIC_MAX_SIZE }, | ||
83 | - [VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 }, | ||
84 | - [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 }, | ||
85 | - [VIRT_DRAM] = { 0x80000000, 0x0 }, | ||
86 | + [VIRT_DEBUG] = { 0x0, 0x100 }, | ||
87 | + [VIRT_MROM] = { 0x1000, 0xf000 }, | ||
88 | + [VIRT_TEST] = { 0x100000, 0x1000 }, | ||
89 | + [VIRT_RTC] = { 0x101000, 0x1000 }, | ||
90 | + [VIRT_CLINT] = { 0x2000000, 0x10000 }, | ||
91 | + [VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 }, | ||
92 | + [VIRT_PCIE_PIO] = { 0x3000000, 0x10000 }, | ||
93 | + [VIRT_PLATFORM_BUS] = { 0x4000000, 0x2000000 }, | ||
94 | + [VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) }, | ||
95 | + [VIRT_APLIC_M] = { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) }, | ||
96 | + [VIRT_APLIC_S] = { 0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) }, | ||
97 | + [VIRT_UART0] = { 0x10000000, 0x100 }, | ||
98 | + [VIRT_VIRTIO] = { 0x10001000, 0x1000 }, | ||
99 | + [VIRT_FW_CFG] = { 0x10100000, 0x18 }, | ||
100 | + [VIRT_FLASH] = { 0x20000000, 0x4000000 }, | ||
101 | + [VIRT_IMSIC_M] = { 0x24000000, VIRT_IMSIC_MAX_SIZE }, | ||
102 | + [VIRT_IMSIC_S] = { 0x28000000, VIRT_IMSIC_MAX_SIZE }, | ||
103 | + [VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 }, | ||
104 | + [VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 }, | ||
105 | + [VIRT_DRAM] = { 0x80000000, 0x0 }, | ||
106 | }; | ||
107 | |||
108 | /* PCIe high mmio is fixed for RV32 */ | ||
109 | @@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests, | ||
110 | return aplic_m; | ||
111 | } | 88 | } |
112 | 89 | ||
113 | +static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip) | 90 | static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp) |
114 | +{ | 91 | { |
92 | const MemMapEntry *memmap = ibex_memmap; | ||
115 | + DeviceState *dev; | 93 | + DeviceState *dev; |
116 | + SysBusDevice *sysbus; | 94 | + SysBusDevice *busdev; |
117 | + const MemMapEntry *memmap = virt_memmap; | 95 | MachineState *ms = MACHINE(qdev_get_machine()); |
118 | + int i; | 96 | LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc); |
119 | + MemoryRegion *sysmem = get_system_memory(); | 97 | MemoryRegion *sys_mem = get_system_memory(); |
98 | @@ -XXX,XX +XXX,XX @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp) | ||
99 | qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)), | ||
100 | IRQ_M_TIMER)); | ||
101 | |||
102 | + /* SPI-Hosts */ | ||
103 | + for (int i = 0; i < OPENTITAN_NUM_SPI_HOSTS; ++i) { | ||
104 | + dev = DEVICE(&(s->spi_host[i])); | ||
105 | + if (!sysbus_realize(SYS_BUS_DEVICE(&s->spi_host[i]), errp)) { | ||
106 | + return; | ||
107 | + } | ||
108 | + busdev = SYS_BUS_DEVICE(dev); | ||
109 | + sysbus_mmio_map(busdev, 0, memmap[IBEX_DEV_SPI_HOST0 + i].base); | ||
120 | + | 110 | + |
121 | + dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE); | 111 | + switch (i) { |
122 | + dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE); | 112 | + case OPENTITAN_SPI_HOST0: |
123 | + qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS); | 113 | + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(&s->plic), |
124 | + qdev_prop_set_uint32(dev, "mmio_size", memmap[VIRT_PLATFORM_BUS].size); | 114 | + IBEX_SPI_HOST0_ERR_IRQ)); |
125 | + sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); | 115 | + sysbus_connect_irq(busdev, 1, qdev_get_gpio_in(DEVICE(&s->plic), |
126 | + s->platform_bus_dev = dev; | 116 | + IBEX_SPI_HOST0_SPI_EVENT_IRQ)); |
127 | + | 117 | + break; |
128 | + sysbus = SYS_BUS_DEVICE(dev); | 118 | + case OPENTITAN_SPI_HOST1: |
129 | + for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) { | 119 | + sysbus_connect_irq(busdev, 0, qdev_get_gpio_in(DEVICE(&s->plic), |
130 | + int irq = VIRT_PLATFORM_BUS_IRQ + i; | 120 | + IBEX_SPI_HOST1_ERR_IRQ)); |
131 | + sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(irqchip, irq)); | 121 | + sysbus_connect_irq(busdev, 1, qdev_get_gpio_in(DEVICE(&s->plic), |
122 | + IBEX_SPI_HOST1_SPI_EVENT_IRQ)); | ||
123 | + break; | ||
124 | + } | ||
132 | + } | 125 | + } |
133 | + | 126 | + |
134 | + memory_region_add_subregion(sysmem, | 127 | create_unimplemented_device("riscv.lowrisc.ibex.gpio", |
135 | + memmap[VIRT_PLATFORM_BUS].base, | 128 | memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size); |
136 | + sysbus_mmio_get_region(sysbus, 0)); | 129 | create_unimplemented_device("riscv.lowrisc.ibex.spi_device", |
137 | +} | 130 | memmap[IBEX_DEV_SPI_DEVICE].base, memmap[IBEX_DEV_SPI_DEVICE].size); |
138 | + | 131 | - create_unimplemented_device("riscv.lowrisc.ibex.spi_host0", |
139 | static void virt_machine_done(Notifier *notifier, void *data) | 132 | - memmap[IBEX_DEV_SPI_HOST0].base, memmap[IBEX_DEV_SPI_HOST0].size); |
140 | { | 133 | - create_unimplemented_device("riscv.lowrisc.ibex.spi_host1", |
141 | RISCVVirtState *s = container_of(notifier, RISCVVirtState, | 134 | - memmap[IBEX_DEV_SPI_HOST1].base, memmap[IBEX_DEV_SPI_HOST1].size); |
142 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) | 135 | create_unimplemented_device("riscv.lowrisc.ibex.i2c", |
143 | memmap[VIRT_PCIE_PIO].base, | 136 | memmap[IBEX_DEV_I2C].base, memmap[IBEX_DEV_I2C].size); |
144 | DEVICE(pcie_irqchip)); | 137 | create_unimplemented_device("riscv.lowrisc.ibex.pattgen", |
145 | |||
146 | + create_platform_bus(s, DEVICE(mmio_irqchip)); | ||
147 | + | ||
148 | serial_mm_init(system_memory, memmap[VIRT_UART0].base, | ||
149 | 0, qdev_get_gpio_in(DEVICE(mmio_irqchip), UART0_IRQ), 399193, | ||
150 | serial_hd(0), DEVICE_LITTLE_ENDIAN); | ||
151 | diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig | ||
152 | index XXXXXXX..XXXXXXX 100644 | ||
153 | --- a/hw/riscv/Kconfig | ||
154 | +++ b/hw/riscv/Kconfig | ||
155 | @@ -XXX,XX +XXX,XX @@ config RISCV_VIRT | ||
156 | select SIFIVE_TEST | ||
157 | select VIRTIO_MMIO | ||
158 | select FW_CFG_DMA | ||
159 | + select PLATFORM_BUS | ||
160 | |||
161 | config SIFIVE_E | ||
162 | bool | ||
163 | -- | 138 | -- |
164 | 2.35.1 | 139 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Atish Patra <atishp@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | - add sm3p0, sm3p1, sm4ed and sm4ks instructions | 3 | Currently, the privileged specification version are defined in |
4 | a complex manner for no benefit. | ||
4 | 5 | ||
5 | Co-authored-by: Ruibo Lu <luruibo2000@163.com> | 6 | Simplify it by changing it to a simple enum based on. |
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 8 | Suggested-by: Richard Henderson <richard.henderson@linaro.org> |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-Id: <20220423023510.30794-12-liweiwei@iscas.ac.cn> | 10 | Signed-off-by: Atish Patra <atishp@rivosinc.com> |
11 | Message-Id: <20220303185440.512391-2-atishp@rivosinc.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 13 | --- |
13 | target/riscv/helper.h | 3 ++ | 14 | target/riscv/cpu.h | 7 +++++-- |
14 | target/riscv/insn32.decode | 6 +++ | 15 | 1 file changed, 5 insertions(+), 2 deletions(-) |
15 | target/riscv/crypto_helper.c | 28 ++++++++++++ | ||
16 | target/riscv/insn_trans/trans_rvk.c.inc | 58 +++++++++++++++++++++++++ | ||
17 | 4 files changed, 95 insertions(+) | ||
18 | 16 | ||
19 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | 17 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
20 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
21 | --- a/target/riscv/helper.h | 19 | --- a/target/riscv/cpu.h |
22 | +++ b/target/riscv/helper.h | 20 | +++ b/target/riscv/cpu.h |
23 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(aes64dsm, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 21 | @@ -XXX,XX +XXX,XX @@ enum { |
24 | DEF_HELPER_FLAGS_2(aes64ks2, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 22 | RISCV_FEATURE_AIA |
25 | DEF_HELPER_FLAGS_2(aes64ks1i, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 23 | }; |
26 | DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl) | 24 | |
27 | + | 25 | -#define PRIV_VERSION_1_10_0 0x00011000 |
28 | +DEF_HELPER_FLAGS_3(sm4ed, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 26 | -#define PRIV_VERSION_1_11_0 0x00011100 |
29 | +DEF_HELPER_FLAGS_3(sm4ks, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 27 | +/* Privileged specification version */ |
30 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 28 | +enum { |
31 | index XXXXXXX..XXXXXXX 100644 | 29 | + PRIV_VERSION_1_10_0 = 0, |
32 | --- a/target/riscv/insn32.decode | 30 | + PRIV_VERSION_1_11_0, |
33 | +++ b/target/riscv/insn32.decode | 31 | +}; |
34 | @@ -XXX,XX +XXX,XX @@ sha512sig0 00 01000 00110 ..... 001 ..... 0010011 @r2 | 32 | |
35 | sha512sig1 00 01000 00111 ..... 001 ..... 0010011 @r2 | 33 | #define VEXT_VERSION_1_00_0 0x00010000 |
36 | sha512sum0 00 01000 00100 ..... 001 ..... 0010011 @r2 | 34 | |
37 | sha512sum1 00 01000 00101 ..... 001 ..... 0010011 @r2 | ||
38 | +# *** RV32 Zksh Standard Extension *** | ||
39 | +sm3p0 00 01000 01000 ..... 001 ..... 0010011 @r2 | ||
40 | +sm3p1 00 01000 01001 ..... 001 ..... 0010011 @r2 | ||
41 | +# *** RV32 Zksed Standard Extension *** | ||
42 | +sm4ed .. 11000 ..... ..... 000 ..... 0110011 @k_aes | ||
43 | +sm4ks .. 11010 ..... ..... 000 ..... 0110011 @k_aes | ||
44 | diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c | ||
45 | index XXXXXXX..XXXXXXX 100644 | ||
46 | --- a/target/riscv/crypto_helper.c | ||
47 | +++ b/target/riscv/crypto_helper.c | ||
48 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes64im)(target_ulong rs1) | ||
49 | |||
50 | return result; | ||
51 | } | ||
52 | + | ||
53 | +target_ulong HELPER(sm4ed)(target_ulong rs1, target_ulong rs2, | ||
54 | + target_ulong shamt) | ||
55 | +{ | ||
56 | + uint32_t sb_in = (uint8_t)(rs2 >> shamt); | ||
57 | + uint32_t sb_out = (uint32_t)sm4_sbox[sb_in]; | ||
58 | + | ||
59 | + uint32_t x = sb_out ^ (sb_out << 8) ^ (sb_out << 2) ^ (sb_out << 18) ^ | ||
60 | + ((sb_out & 0x3f) << 26) ^ ((sb_out & 0xC0) << 10); | ||
61 | + | ||
62 | + uint32_t rotl = rol32(x, shamt); | ||
63 | + | ||
64 | + return sext32_xlen(rotl ^ (uint32_t)rs1); | ||
65 | +} | ||
66 | + | ||
67 | +target_ulong HELPER(sm4ks)(target_ulong rs1, target_ulong rs2, | ||
68 | + target_ulong shamt) | ||
69 | +{ | ||
70 | + uint32_t sb_in = (uint8_t)(rs2 >> shamt); | ||
71 | + uint32_t sb_out = sm4_sbox[sb_in]; | ||
72 | + | ||
73 | + uint32_t x = sb_out ^ ((sb_out & 0x07) << 29) ^ ((sb_out & 0xFE) << 7) ^ | ||
74 | + ((sb_out & 0x01) << 23) ^ ((sb_out & 0xF8) << 13); | ||
75 | + | ||
76 | + uint32_t rotl = rol32(x, shamt); | ||
77 | + | ||
78 | + return sext32_xlen(rotl ^ (uint32_t)rs1); | ||
79 | +} | ||
80 | #undef sext32_xlen | ||
81 | diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc | ||
82 | index XXXXXXX..XXXXXXX 100644 | ||
83 | --- a/target/riscv/insn_trans/trans_rvk.c.inc | ||
84 | +++ b/target/riscv/insn_trans/trans_rvk.c.inc | ||
85 | @@ -XXX,XX +XXX,XX @@ | ||
86 | } \ | ||
87 | } while (0) | ||
88 | |||
89 | +#define REQUIRE_ZKSED(ctx) do { \ | ||
90 | + if (!ctx->cfg_ptr->ext_zksed) { \ | ||
91 | + return false; \ | ||
92 | + } \ | ||
93 | +} while (0) | ||
94 | + | ||
95 | +#define REQUIRE_ZKSH(ctx) do { \ | ||
96 | + if (!ctx->cfg_ptr->ext_zksh) { \ | ||
97 | + return false; \ | ||
98 | + } \ | ||
99 | +} while (0) | ||
100 | + | ||
101 | static bool gen_aes32_sm4(DisasContext *ctx, arg_k_aes *a, | ||
102 | void (*func)(TCGv, TCGv, TCGv, TCGv)) | ||
103 | { | ||
104 | @@ -XXX,XX +XXX,XX @@ static bool trans_sha512sum1(DisasContext *ctx, arg_sha512sum1 *a) | ||
105 | REQUIRE_ZKNH(ctx); | ||
106 | return gen_sha512_rv64(ctx, a, EXT_NONE, tcg_gen_rotri_i64, 14, 18, 41); | ||
107 | } | ||
108 | + | ||
109 | +/* SM3 */ | ||
110 | +static bool gen_sm3(DisasContext *ctx, arg_r2 *a, int32_t b, int32_t c) | ||
111 | +{ | ||
112 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
113 | + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); | ||
114 | + TCGv_i32 t0 = tcg_temp_new_i32(); | ||
115 | + TCGv_i32 t1 = tcg_temp_new_i32(); | ||
116 | + | ||
117 | + tcg_gen_trunc_tl_i32(t0, src1); | ||
118 | + tcg_gen_rotli_i32(t1, t0, b); | ||
119 | + tcg_gen_xor_i32(t1, t0, t1); | ||
120 | + tcg_gen_rotli_i32(t0, t0, c); | ||
121 | + tcg_gen_xor_i32(t1, t1, t0); | ||
122 | + tcg_gen_ext_i32_tl(dest, t1); | ||
123 | + gen_set_gpr(ctx, a->rd, dest); | ||
124 | + | ||
125 | + tcg_temp_free_i32(t0); | ||
126 | + tcg_temp_free_i32(t1); | ||
127 | + return true; | ||
128 | +} | ||
129 | + | ||
130 | +static bool trans_sm3p0(DisasContext *ctx, arg_sm3p0 *a) | ||
131 | +{ | ||
132 | + REQUIRE_ZKSH(ctx); | ||
133 | + return gen_sm3(ctx, a, 9, 17); | ||
134 | +} | ||
135 | + | ||
136 | +static bool trans_sm3p1(DisasContext *ctx, arg_sm3p1 *a) | ||
137 | +{ | ||
138 | + REQUIRE_ZKSH(ctx); | ||
139 | + return gen_sm3(ctx, a, 15, 23); | ||
140 | +} | ||
141 | + | ||
142 | +/* SM4 */ | ||
143 | +static bool trans_sm4ed(DisasContext *ctx, arg_sm4ed *a) | ||
144 | +{ | ||
145 | + REQUIRE_ZKSED(ctx); | ||
146 | + return gen_aes32_sm4(ctx, a, gen_helper_sm4ed); | ||
147 | +} | ||
148 | + | ||
149 | +static bool trans_sm4ks(DisasContext *ctx, arg_sm4ks *a) | ||
150 | +{ | ||
151 | + REQUIRE_ZKSED(ctx); | ||
152 | + return gen_aes32_sm4(ctx, a, gen_helper_sm4ks); | ||
153 | +} | ||
154 | -- | 35 | -- |
155 | 2.35.1 | 36 | 2.35.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | Add the definition for ratified privileged specification version v1.12 | ||
4 | |||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
6 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
7 | Message-Id: <20220303185440.512391-3-atishp@rivosinc.com> | ||
8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
9 | --- | ||
10 | target/riscv/cpu.h | 1 + | ||
11 | 1 file changed, 1 insertion(+) | ||
12 | |||
13 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
14 | index XXXXXXX..XXXXXXX 100644 | ||
15 | --- a/target/riscv/cpu.h | ||
16 | +++ b/target/riscv/cpu.h | ||
17 | @@ -XXX,XX +XXX,XX @@ enum { | ||
18 | enum { | ||
19 | PRIV_VERSION_1_10_0 = 0, | ||
20 | PRIV_VERSION_1_11_0, | ||
21 | + PRIV_VERSION_1_12_0, | ||
22 | }; | ||
23 | |||
24 | #define VEXT_VERSION_1_00_0 0x00010000 | ||
25 | -- | ||
26 | 2.35.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | To allow/disallow the CSR access based on the privilege spec, a new field | ||
4 | in the csr_ops is introduced. It also adds the privileged specification | ||
5 | version (v1.12) for the CSRs introduced in the v1.12. This includes the | ||
6 | new ratified extensions such as Vector, Hypervisor and secconfig CSR. | ||
7 | However, it doesn't enforce the privilege version in this commit. | ||
8 | |||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
10 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
11 | Message-Id: <20220303185440.512391-4-atishp@rivosinc.com> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
13 | --- | ||
14 | target/riscv/cpu.h | 2 + | ||
15 | target/riscv/csr.c | 103 ++++++++++++++++++++++++++++++--------------- | ||
16 | 2 files changed, 70 insertions(+), 35 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/cpu.h | ||
21 | +++ b/target/riscv/cpu.h | ||
22 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
23 | riscv_csr_op_fn op; | ||
24 | riscv_csr_read128_fn read128; | ||
25 | riscv_csr_write128_fn write128; | ||
26 | + /* The default priv spec version should be PRIV_VERSION_1_10_0 (i.e 0) */ | ||
27 | + uint32_t min_priv_ver; | ||
28 | } riscv_csr_operations; | ||
29 | |||
30 | /* CSR function table constants */ | ||
31 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/target/riscv/csr.c | ||
34 | +++ b/target/riscv/csr.c | ||
35 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
36 | [CSR_FRM] = { "frm", fs, read_frm, write_frm }, | ||
37 | [CSR_FCSR] = { "fcsr", fs, read_fcsr, write_fcsr }, | ||
38 | /* Vector CSRs */ | ||
39 | - [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart }, | ||
40 | - [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat }, | ||
41 | - [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm }, | ||
42 | - [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr }, | ||
43 | - [CSR_VL] = { "vl", vs, read_vl }, | ||
44 | - [CSR_VTYPE] = { "vtype", vs, read_vtype }, | ||
45 | - [CSR_VLENB] = { "vlenb", vs, read_vlenb }, | ||
46 | + [CSR_VSTART] = { "vstart", vs, read_vstart, write_vstart, | ||
47 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
48 | + [CSR_VXSAT] = { "vxsat", vs, read_vxsat, write_vxsat, | ||
49 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
50 | + [CSR_VXRM] = { "vxrm", vs, read_vxrm, write_vxrm, | ||
51 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
52 | + [CSR_VCSR] = { "vcsr", vs, read_vcsr, write_vcsr, | ||
53 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
54 | + [CSR_VL] = { "vl", vs, read_vl, | ||
55 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
56 | + [CSR_VTYPE] = { "vtype", vs, read_vtype, | ||
57 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
58 | + [CSR_VLENB] = { "vlenb", vs, read_vlenb, | ||
59 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
60 | /* User Timers and Counters */ | ||
61 | [CSR_CYCLE] = { "cycle", ctr, read_instret }, | ||
62 | [CSR_INSTRET] = { "instret", ctr, read_instret }, | ||
63 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
64 | [CSR_SIEH] = { "sieh", aia_smode32, NULL, NULL, rmw_sieh }, | ||
65 | [CSR_SIPH] = { "siph", aia_smode32, NULL, NULL, rmw_siph }, | ||
66 | |||
67 | - [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus }, | ||
68 | - [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg }, | ||
69 | - [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg }, | ||
70 | - [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip }, | ||
71 | - [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip }, | ||
72 | - [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie }, | ||
73 | - [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren }, | ||
74 | - [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie }, | ||
75 | - [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval }, | ||
76 | - [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst }, | ||
77 | - [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, NULL }, | ||
78 | - [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp }, | ||
79 | - [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta }, | ||
80 | - [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah }, | ||
81 | - | ||
82 | - [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus }, | ||
83 | - [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip }, | ||
84 | - [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie }, | ||
85 | - [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec }, | ||
86 | - [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch }, | ||
87 | - [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc }, | ||
88 | - [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause }, | ||
89 | - [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval }, | ||
90 | - [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp }, | ||
91 | - | ||
92 | - [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2 }, | ||
93 | - [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst }, | ||
94 | + [CSR_HSTATUS] = { "hstatus", hmode, read_hstatus, write_hstatus, | ||
95 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
96 | + [CSR_HEDELEG] = { "hedeleg", hmode, read_hedeleg, write_hedeleg, | ||
97 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
98 | + [CSR_HIDELEG] = { "hideleg", hmode, NULL, NULL, rmw_hideleg, | ||
99 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
100 | + [CSR_HVIP] = { "hvip", hmode, NULL, NULL, rmw_hvip, | ||
101 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
102 | + [CSR_HIP] = { "hip", hmode, NULL, NULL, rmw_hip, | ||
103 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
104 | + [CSR_HIE] = { "hie", hmode, NULL, NULL, rmw_hie, | ||
105 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
106 | + [CSR_HCOUNTEREN] = { "hcounteren", hmode, read_hcounteren, write_hcounteren, | ||
107 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
108 | + [CSR_HGEIE] = { "hgeie", hmode, read_hgeie, write_hgeie, | ||
109 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
110 | + [CSR_HTVAL] = { "htval", hmode, read_htval, write_htval, | ||
111 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
112 | + [CSR_HTINST] = { "htinst", hmode, read_htinst, write_htinst, | ||
113 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
114 | + [CSR_HGEIP] = { "hgeip", hmode, read_hgeip, | ||
115 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
116 | + [CSR_HGATP] = { "hgatp", hmode, read_hgatp, write_hgatp, | ||
117 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
118 | + [CSR_HTIMEDELTA] = { "htimedelta", hmode, read_htimedelta, write_htimedelta, | ||
119 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
120 | + [CSR_HTIMEDELTAH] = { "htimedeltah", hmode32, read_htimedeltah, write_htimedeltah, | ||
121 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
122 | + | ||
123 | + [CSR_VSSTATUS] = { "vsstatus", hmode, read_vsstatus, write_vsstatus, | ||
124 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
125 | + [CSR_VSIP] = { "vsip", hmode, NULL, NULL, rmw_vsip, | ||
126 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
127 | + [CSR_VSIE] = { "vsie", hmode, NULL, NULL, rmw_vsie , | ||
128 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
129 | + [CSR_VSTVEC] = { "vstvec", hmode, read_vstvec, write_vstvec, | ||
130 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
131 | + [CSR_VSSCRATCH] = { "vsscratch", hmode, read_vsscratch, write_vsscratch, | ||
132 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
133 | + [CSR_VSEPC] = { "vsepc", hmode, read_vsepc, write_vsepc, | ||
134 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
135 | + [CSR_VSCAUSE] = { "vscause", hmode, read_vscause, write_vscause, | ||
136 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
137 | + [CSR_VSTVAL] = { "vstval", hmode, read_vstval, write_vstval, | ||
138 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
139 | + [CSR_VSATP] = { "vsatp", hmode, read_vsatp, write_vsatp, | ||
140 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
141 | + | ||
142 | + [CSR_MTVAL2] = { "mtval2", hmode, read_mtval2, write_mtval2, | ||
143 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
144 | + [CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst, | ||
145 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
146 | |||
147 | /* Virtual Interrupts and Interrupt Priorities (H-extension with AIA) */ | ||
148 | [CSR_HVIEN] = { "hvien", aia_hmode, read_zero, write_ignore }, | ||
149 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
150 | [CSR_VSIPH] = { "vsiph", aia_hmode32, NULL, NULL, rmw_vsiph }, | ||
151 | |||
152 | /* Physical Memory Protection */ | ||
153 | - [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg }, | ||
154 | + [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg, | ||
155 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
156 | [CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg }, | ||
157 | [CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg }, | ||
158 | [CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg }, | ||
159 | -- | ||
160 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Atish Patra <atishp@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | - add SEED CSR which must be accessed with a read-write instruction: | 3 | RISC-V privileged specification v1.12 introduced a mconfigptr |
4 | A read-only instruction such as CSRRS/CSRRC with rs1=x0 or CSRRSI/CSRRCI | 4 | which will hold the physical address of a configuration data |
5 | with uimm=0 will raise an illegal instruction exception. | 5 | structure. As Qemu doesn't have a configuration data structure, |
6 | - add USEED, SSEED fields for MSECCFG CSR | 6 | is read as zero which is valid as per the priv spec. |
7 | 7 | ||
8 | Co-authored-by: Ruibo Lu <luruibo2000@163.com> | ||
9 | Co-authored-by: Zewen Ye <lustrew@foxmail.com> | ||
10 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
13 | Message-Id: <20220423023510.30794-13-liweiwei@iscas.ac.cn> | 9 | Signed-off-by: Atish Patra <atishp@rivosinc.com> |
10 | Message-Id: <20220303185440.512391-5-atishp@rivosinc.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
15 | --- | 12 | --- |
16 | target/riscv/cpu_bits.h | 9 +++++ | 13 | target/riscv/cpu_bits.h | 1 + |
17 | target/riscv/pmp.h | 8 ++-- | 14 | target/riscv/csr.c | 2 ++ |
18 | target/riscv/csr.c | 80 ++++++++++++++++++++++++++++++++++++++++ | 15 | 2 files changed, 3 insertions(+) |
19 | target/riscv/op_helper.c | 9 +++++ | ||
20 | 4 files changed, 103 insertions(+), 3 deletions(-) | ||
21 | 16 | ||
22 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h | 17 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h |
23 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
24 | --- a/target/riscv/cpu_bits.h | 19 | --- a/target/riscv/cpu_bits.h |
25 | +++ b/target/riscv/cpu_bits.h | 20 | +++ b/target/riscv/cpu_bits.h |
26 | @@ -XXX,XX +XXX,XX @@ | 21 | @@ -XXX,XX +XXX,XX @@ |
27 | #define CSR_VSPMMASK 0x2c1 | 22 | #define CSR_MARCHID 0xf12 |
28 | #define CSR_VSPMBASE 0x2c2 | 23 | #define CSR_MIMPID 0xf13 |
29 | 24 | #define CSR_MHARTID 0xf14 | |
30 | +/* Crypto Extension */ | 25 | +#define CSR_MCONFIGPTR 0xf15 |
31 | +#define CSR_SEED 0x015 | 26 | |
32 | + | 27 | /* Machine Trap Setup */ |
33 | /* mstatus CSR bits */ | 28 | #define CSR_MSTATUS 0x300 |
34 | #define MSTATUS_UIE 0x00000001 | ||
35 | #define MSTATUS_SIE 0x00000002 | ||
36 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { | ||
37 | #define HVICTL_VALID_MASK \ | ||
38 | (HVICTL_VTI | HVICTL_IID | HVICTL_IPRIOM | HVICTL_IPRIO) | ||
39 | |||
40 | +/* seed CSR bits */ | ||
41 | +#define SEED_OPST (0b11 << 30) | ||
42 | +#define SEED_OPST_BIST (0b00 << 30) | ||
43 | +#define SEED_OPST_WAIT (0b01 << 30) | ||
44 | +#define SEED_OPST_ES16 (0b10 << 30) | ||
45 | +#define SEED_OPST_DEAD (0b11 << 30) | ||
46 | #endif | ||
47 | diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h | ||
48 | index XXXXXXX..XXXXXXX 100644 | ||
49 | --- a/target/riscv/pmp.h | ||
50 | +++ b/target/riscv/pmp.h | ||
51 | @@ -XXX,XX +XXX,XX @@ typedef enum { | ||
52 | } pmp_am_t; | ||
53 | |||
54 | typedef enum { | ||
55 | - MSECCFG_MML = 1 << 0, | ||
56 | - MSECCFG_MMWP = 1 << 1, | ||
57 | - MSECCFG_RLB = 1 << 2 | ||
58 | + MSECCFG_MML = 1 << 0, | ||
59 | + MSECCFG_MMWP = 1 << 1, | ||
60 | + MSECCFG_RLB = 1 << 2, | ||
61 | + MSECCFG_USEED = 1 << 8, | ||
62 | + MSECCFG_SSEED = 1 << 9 | ||
63 | } mseccfg_field_t; | ||
64 | |||
65 | typedef struct { | ||
66 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 29 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
67 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
68 | --- a/target/riscv/csr.c | 31 | --- a/target/riscv/csr.c |
69 | +++ b/target/riscv/csr.c | 32 | +++ b/target/riscv/csr.c |
70 | @@ -XXX,XX +XXX,XX @@ | ||
71 | #include "qemu/main-loop.h" | ||
72 | #include "exec/exec-all.h" | ||
73 | #include "sysemu/cpu-timers.h" | ||
74 | +#include "qemu/guest-random.h" | ||
75 | +#include "qapi/error.h" | ||
76 | |||
77 | /* CSR function table public API */ | ||
78 | void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops) | ||
79 | @@ -XXX,XX +XXX,XX @@ static RISCVException debug(CPURISCVState *env, int csrno) | ||
80 | } | ||
81 | #endif | ||
82 | |||
83 | +static RISCVException seed(CPURISCVState *env, int csrno) | ||
84 | +{ | ||
85 | + RISCVCPU *cpu = env_archcpu(env); | ||
86 | + | ||
87 | + if (!cpu->cfg.ext_zkr) { | ||
88 | + return RISCV_EXCP_ILLEGAL_INST; | ||
89 | + } | ||
90 | + | ||
91 | +#if !defined(CONFIG_USER_ONLY) | ||
92 | + /* | ||
93 | + * With a CSR read-write instruction: | ||
94 | + * 1) The seed CSR is always available in machine mode as normal. | ||
95 | + * 2) Attempted access to seed from virtual modes VS and VU always raises | ||
96 | + * an exception(virtual instruction exception only if mseccfg.sseed=1). | ||
97 | + * 3) Without the corresponding access control bit set to 1, any attempted | ||
98 | + * access to seed from U, S or HS modes will raise an illegal instruction | ||
99 | + * exception. | ||
100 | + */ | ||
101 | + if (env->priv == PRV_M) { | ||
102 | + return RISCV_EXCP_NONE; | ||
103 | + } else if (riscv_cpu_virt_enabled(env)) { | ||
104 | + if (env->mseccfg & MSECCFG_SSEED) { | ||
105 | + return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||
106 | + } else { | ||
107 | + return RISCV_EXCP_ILLEGAL_INST; | ||
108 | + } | ||
109 | + } else { | ||
110 | + if (env->priv == PRV_S && (env->mseccfg & MSECCFG_SSEED)) { | ||
111 | + return RISCV_EXCP_NONE; | ||
112 | + } else if (env->priv == PRV_U && (env->mseccfg & MSECCFG_USEED)) { | ||
113 | + return RISCV_EXCP_NONE; | ||
114 | + } else { | ||
115 | + return RISCV_EXCP_ILLEGAL_INST; | ||
116 | + } | ||
117 | + } | ||
118 | +#else | ||
119 | + return RISCV_EXCP_NONE; | ||
120 | +#endif | ||
121 | +} | ||
122 | + | ||
123 | /* User Floating-Point CSRs */ | ||
124 | static RISCVException read_fflags(CPURISCVState *env, int csrno, | ||
125 | target_ulong *val) | ||
126 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_upmbase(CPURISCVState *env, int csrno, | ||
127 | |||
128 | #endif | ||
129 | |||
130 | +/* Crypto Extension */ | ||
131 | +static RISCVException rmw_seed(CPURISCVState *env, int csrno, | ||
132 | + target_ulong *ret_value, | ||
133 | + target_ulong new_value, | ||
134 | + target_ulong write_mask) | ||
135 | +{ | ||
136 | + uint16_t random_v; | ||
137 | + Error *random_e = NULL; | ||
138 | + int random_r; | ||
139 | + target_ulong rval; | ||
140 | + | ||
141 | + random_r = qemu_guest_getrandom(&random_v, 2, &random_e); | ||
142 | + if (unlikely(random_r < 0)) { | ||
143 | + /* | ||
144 | + * Failed, for unknown reasons in the crypto subsystem. | ||
145 | + * The best we can do is log the reason and return a | ||
146 | + * failure indication to the guest. There is no reason | ||
147 | + * we know to expect the failure to be transitory, so | ||
148 | + * indicate DEAD to avoid having the guest spin on WAIT. | ||
149 | + */ | ||
150 | + qemu_log_mask(LOG_UNIMP, "%s: Crypto failure: %s", | ||
151 | + __func__, error_get_pretty(random_e)); | ||
152 | + error_free(random_e); | ||
153 | + rval = SEED_OPST_DEAD; | ||
154 | + } else { | ||
155 | + rval = random_v | SEED_OPST_ES16; | ||
156 | + } | ||
157 | + | ||
158 | + if (ret_value) { | ||
159 | + *ret_value = rval; | ||
160 | + } | ||
161 | + | ||
162 | + return RISCV_EXCP_NONE; | ||
163 | +} | ||
164 | + | ||
165 | /* | ||
166 | * riscv_csrrw - read and/or update control and status register | ||
167 | * | ||
168 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | 33 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { |
169 | [CSR_TIME] = { "time", ctr, read_time }, | 34 | [CSR_MIMPID] = { "mimpid", any, read_zero }, |
170 | [CSR_TIMEH] = { "timeh", ctr32, read_timeh }, | 35 | [CSR_MHARTID] = { "mhartid", any, read_mhartid }, |
171 | 36 | ||
172 | + /* Crypto Extension */ | 37 | + [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero, |
173 | + [CSR_SEED] = { "seed", seed, NULL, NULL, rmw_seed }, | 38 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, |
174 | + | 39 | /* Machine Trap Setup */ |
175 | #if !defined(CONFIG_USER_ONLY) | 40 | [CSR_MSTATUS] = { "mstatus", any, read_mstatus, write_mstatus, NULL, |
176 | /* Machine Timers and Counters */ | 41 | read_mstatus_i128 }, |
177 | [CSR_MCYCLE] = { "mcycle", any, read_instret }, | ||
178 | diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c | ||
179 | index XXXXXXX..XXXXXXX 100644 | ||
180 | --- a/target/riscv/op_helper.c | ||
181 | +++ b/target/riscv/op_helper.c | ||
182 | @@ -XXX,XX +XXX,XX @@ void helper_raise_exception(CPURISCVState *env, uint32_t exception) | ||
183 | |||
184 | target_ulong helper_csrr(CPURISCVState *env, int csr) | ||
185 | { | ||
186 | + /* | ||
187 | + * The seed CSR must be accessed with a read-write instruction. A | ||
188 | + * read-only instruction such as CSRRS/CSRRC with rs1=x0 or CSRRSI/ | ||
189 | + * CSRRCI with uimm=0 will raise an illegal instruction exception. | ||
190 | + */ | ||
191 | + if (csr == CSR_SEED) { | ||
192 | + riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); | ||
193 | + } | ||
194 | + | ||
195 | target_ulong val = 0; | ||
196 | RISCVException ret = riscv_csrrw(env, csr, &val, 0, 0); | ||
197 | |||
198 | -- | 42 | -- |
199 | 2.35.1 | 43 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Atish Patra <atishp@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | - add sha512sum0, sha512sig0, sha512sum1 and sha512sig1 instructions | 3 | The RISC-V privileged specification v1.12 defines few execution |
4 | 4 | environment configuration CSRs that can be used enable/disable | |
5 | Co-authored-by: Zewen Ye <lustrew@foxmail.com> | 5 | extensions per privilege levels. |
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 6 | |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 7 | Add the basic support for these CSRs. |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 8 | |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-Id: <20220423023510.30794-11-liweiwei@iscas.ac.cn> | 10 | Signed-off-by: Atish Patra <atishp@rivosinc.com> |
11 | Message-Id: <20220303185440.512391-6-atishp@rivosinc.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 13 | --- |
13 | target/riscv/insn32.decode | 5 +++ | 14 | target/riscv/cpu.h | 5 ++ |
14 | target/riscv/insn_trans/trans_rvk.c.inc | 53 +++++++++++++++++++++++++ | 15 | target/riscv/cpu_bits.h | 39 +++++++++++++++ |
15 | 2 files changed, 58 insertions(+) | 16 | target/riscv/csr.c | 107 ++++++++++++++++++++++++++++++++++++++++ |
16 | 17 | target/riscv/machine.c | 23 +++++++++ | |
17 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 18 | 4 files changed, 174 insertions(+) |
18 | index XXXXXXX..XXXXXXX 100644 | 19 | |
19 | --- a/target/riscv/insn32.decode | 20 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
20 | +++ b/target/riscv/insn32.decode | 21 | index XXXXXXX..XXXXXXX 100644 |
21 | @@ -XXX,XX +XXX,XX @@ sha512sig0l 01 01010 ..... ..... 000 ..... 0110011 @r | 22 | --- a/target/riscv/cpu.h |
22 | sha512sig0h 01 01110 ..... ..... 000 ..... 0110011 @r | 23 | +++ b/target/riscv/cpu.h |
23 | sha512sig1l 01 01011 ..... ..... 000 ..... 0110011 @r | 24 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { |
24 | sha512sig1h 01 01111 ..... ..... 000 ..... 0110011 @r | 25 | target_ulong spmbase; |
25 | +# *** RV64 Zknh Standard Extension *** | 26 | target_ulong upmmask; |
26 | +sha512sig0 00 01000 00110 ..... 001 ..... 0010011 @r2 | 27 | target_ulong upmbase; |
27 | +sha512sig1 00 01000 00111 ..... 001 ..... 0010011 @r2 | 28 | + |
28 | +sha512sum0 00 01000 00100 ..... 001 ..... 0010011 @r2 | 29 | + /* CSRs for execution enviornment configuration */ |
29 | +sha512sum1 00 01000 00101 ..... 001 ..... 0010011 @r2 | 30 | + uint64_t menvcfg; |
30 | diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc | 31 | + target_ulong senvcfg; |
31 | index XXXXXXX..XXXXXXX 100644 | 32 | + uint64_t henvcfg; |
32 | --- a/target/riscv/insn_trans/trans_rvk.c.inc | 33 | #endif |
33 | +++ b/target/riscv/insn_trans/trans_rvk.c.inc | 34 | target_ulong cur_pmmask; |
34 | @@ -XXX,XX +XXX,XX @@ static bool trans_sha512sig1h(DisasContext *ctx, arg_sha512sig1h *a) | 35 | target_ulong cur_pmbase; |
35 | REQUIRE_ZKNH(ctx); | 36 | diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h |
36 | return gen_sha512h_rv32(ctx, a, EXT_NONE, tcg_gen_rotli_i64, 3, 6, 19); | 37 | index XXXXXXX..XXXXXXX 100644 |
38 | --- a/target/riscv/cpu_bits.h | ||
39 | +++ b/target/riscv/cpu_bits.h | ||
40 | @@ -XXX,XX +XXX,XX @@ | ||
41 | #define CSR_STVEC 0x105 | ||
42 | #define CSR_SCOUNTEREN 0x106 | ||
43 | |||
44 | +/* Supervisor Configuration CSRs */ | ||
45 | +#define CSR_SENVCFG 0x10A | ||
46 | + | ||
47 | /* Supervisor Trap Handling */ | ||
48 | #define CSR_SSCRATCH 0x140 | ||
49 | #define CSR_SEPC 0x141 | ||
50 | @@ -XXX,XX +XXX,XX @@ | ||
51 | #define CSR_HTIMEDELTA 0x605 | ||
52 | #define CSR_HTIMEDELTAH 0x615 | ||
53 | |||
54 | +/* Hypervisor Configuration CSRs */ | ||
55 | +#define CSR_HENVCFG 0x60A | ||
56 | +#define CSR_HENVCFGH 0x61A | ||
57 | + | ||
58 | /* Virtual CSRs */ | ||
59 | #define CSR_VSSTATUS 0x200 | ||
60 | #define CSR_VSIE 0x204 | ||
61 | @@ -XXX,XX +XXX,XX @@ | ||
62 | #define CSR_VSIEH 0x214 | ||
63 | #define CSR_VSIPH 0x254 | ||
64 | |||
65 | +/* Machine Configuration CSRs */ | ||
66 | +#define CSR_MENVCFG 0x30A | ||
67 | +#define CSR_MENVCFGH 0x31A | ||
68 | + | ||
69 | /* Enhanced Physical Memory Protection (ePMP) */ | ||
70 | #define CSR_MSECCFG 0x747 | ||
71 | #define CSR_MSECCFGH 0x757 | ||
72 | @@ -XXX,XX +XXX,XX @@ typedef enum RISCVException { | ||
73 | #define PM_EXT_CLEAN 0x00000002ULL | ||
74 | #define PM_EXT_DIRTY 0x00000003ULL | ||
75 | |||
76 | +/* Execution enviornment configuration bits */ | ||
77 | +#define MENVCFG_FIOM BIT(0) | ||
78 | +#define MENVCFG_CBIE (3UL << 4) | ||
79 | +#define MENVCFG_CBCFE BIT(6) | ||
80 | +#define MENVCFG_CBZE BIT(7) | ||
81 | +#define MENVCFG_PBMTE (1ULL << 62) | ||
82 | +#define MENVCFG_STCE (1ULL << 63) | ||
83 | + | ||
84 | +/* For RV32 */ | ||
85 | +#define MENVCFGH_PBMTE BIT(30) | ||
86 | +#define MENVCFGH_STCE BIT(31) | ||
87 | + | ||
88 | +#define SENVCFG_FIOM MENVCFG_FIOM | ||
89 | +#define SENVCFG_CBIE MENVCFG_CBIE | ||
90 | +#define SENVCFG_CBCFE MENVCFG_CBCFE | ||
91 | +#define SENVCFG_CBZE MENVCFG_CBZE | ||
92 | + | ||
93 | +#define HENVCFG_FIOM MENVCFG_FIOM | ||
94 | +#define HENVCFG_CBIE MENVCFG_CBIE | ||
95 | +#define HENVCFG_CBCFE MENVCFG_CBCFE | ||
96 | +#define HENVCFG_CBZE MENVCFG_CBZE | ||
97 | +#define HENVCFG_PBMTE MENVCFG_PBMTE | ||
98 | +#define HENVCFG_STCE MENVCFG_STCE | ||
99 | + | ||
100 | +/* For RV32 */ | ||
101 | +#define HENVCFGH_PBMTE MENVCFGH_PBMTE | ||
102 | +#define HENVCFGH_STCE MENVCFGH_STCE | ||
103 | + | ||
104 | /* Offsets for every pair of control bits per each priv level */ | ||
105 | #define XS_OFFSET 0ULL | ||
106 | #define U_OFFSET 2ULL | ||
107 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
108 | index XXXXXXX..XXXXXXX 100644 | ||
109 | --- a/target/riscv/csr.c | ||
110 | +++ b/target/riscv/csr.c | ||
111 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_mtval(CPURISCVState *env, int csrno, | ||
112 | return RISCV_EXCP_NONE; | ||
37 | } | 113 | } |
38 | + | 114 | |
39 | +static bool gen_sha512_rv64(DisasContext *ctx, arg_r2 *a, DisasExtend ext, | 115 | +/* Execution environment configuration setup */ |
40 | + void (*func)(TCGv_i64, TCGv_i64, int64_t), | 116 | +static RISCVException read_menvcfg(CPURISCVState *env, int csrno, |
41 | + int64_t num1, int64_t num2, int64_t num3) | 117 | + target_ulong *val) |
42 | +{ | 118 | +{ |
43 | + TCGv dest = dest_gpr(ctx, a->rd); | 119 | + *val = env->menvcfg; |
44 | + TCGv src1 = get_gpr(ctx, a->rs1, ext); | 120 | + return RISCV_EXCP_NONE; |
45 | + TCGv_i64 t0 = tcg_temp_new_i64(); | 121 | +} |
46 | + TCGv_i64 t1 = tcg_temp_new_i64(); | 122 | + |
47 | + TCGv_i64 t2 = tcg_temp_new_i64(); | 123 | +static RISCVException write_menvcfg(CPURISCVState *env, int csrno, |
48 | + | 124 | + target_ulong val) |
49 | + tcg_gen_extu_tl_i64(t0, src1); | 125 | +{ |
50 | + tcg_gen_rotri_i64(t1, t0, num1); | 126 | + uint64_t mask = MENVCFG_FIOM | MENVCFG_CBIE | MENVCFG_CBCFE | MENVCFG_CBZE; |
51 | + tcg_gen_rotri_i64(t2, t0, num2); | 127 | + |
52 | + tcg_gen_xor_i64(t1, t1, t2); | 128 | + if (riscv_cpu_mxl(env) == MXL_RV64) { |
53 | + func(t2, t0, num3); | 129 | + mask |= MENVCFG_PBMTE | MENVCFG_STCE; |
54 | + tcg_gen_xor_i64(t1, t1, t2); | 130 | + } |
55 | + tcg_gen_trunc_i64_tl(dest, t1); | 131 | + env->menvcfg = (env->menvcfg & ~mask) | (val & mask); |
56 | + | 132 | + |
57 | + gen_set_gpr(ctx, a->rd, dest); | 133 | + return RISCV_EXCP_NONE; |
58 | + tcg_temp_free_i64(t0); | 134 | +} |
59 | + tcg_temp_free_i64(t1); | 135 | + |
60 | + tcg_temp_free_i64(t2); | 136 | +static RISCVException read_menvcfgh(CPURISCVState *env, int csrno, |
61 | + return true; | 137 | + target_ulong *val) |
62 | +} | 138 | +{ |
63 | + | 139 | + *val = env->menvcfg >> 32; |
64 | +static bool trans_sha512sig0(DisasContext *ctx, arg_sha512sig0 *a) | 140 | + return RISCV_EXCP_NONE; |
65 | +{ | 141 | +} |
66 | + REQUIRE_64BIT(ctx); | 142 | + |
67 | + REQUIRE_ZKNH(ctx); | 143 | +static RISCVException write_menvcfgh(CPURISCVState *env, int csrno, |
68 | + return gen_sha512_rv64(ctx, a, EXT_NONE, tcg_gen_shri_i64, 1, 8, 7); | 144 | + target_ulong val) |
69 | +} | 145 | +{ |
70 | + | 146 | + uint64_t mask = MENVCFG_PBMTE | MENVCFG_STCE; |
71 | +static bool trans_sha512sig1(DisasContext *ctx, arg_sha512sig1 *a) | 147 | + uint64_t valh = (uint64_t)val << 32; |
72 | +{ | 148 | + |
73 | + REQUIRE_64BIT(ctx); | 149 | + env->menvcfg = (env->menvcfg & ~mask) | (valh & mask); |
74 | + REQUIRE_ZKNH(ctx); | 150 | + |
75 | + return gen_sha512_rv64(ctx, a, EXT_NONE, tcg_gen_shri_i64, 19, 61, 6); | 151 | + return RISCV_EXCP_NONE; |
76 | +} | 152 | +} |
77 | + | 153 | + |
78 | +static bool trans_sha512sum0(DisasContext *ctx, arg_sha512sum0 *a) | 154 | +static RISCVException read_senvcfg(CPURISCVState *env, int csrno, |
79 | +{ | 155 | + target_ulong *val) |
80 | + REQUIRE_64BIT(ctx); | 156 | +{ |
81 | + REQUIRE_ZKNH(ctx); | 157 | + *val = env->senvcfg; |
82 | + return gen_sha512_rv64(ctx, a, EXT_NONE, tcg_gen_rotri_i64, 28, 34, 39); | 158 | + return RISCV_EXCP_NONE; |
83 | +} | 159 | +} |
84 | + | 160 | + |
85 | +static bool trans_sha512sum1(DisasContext *ctx, arg_sha512sum1 *a) | 161 | +static RISCVException write_senvcfg(CPURISCVState *env, int csrno, |
86 | +{ | 162 | + target_ulong val) |
87 | + REQUIRE_64BIT(ctx); | 163 | +{ |
88 | + REQUIRE_ZKNH(ctx); | 164 | + uint64_t mask = SENVCFG_FIOM | SENVCFG_CBIE | SENVCFG_CBCFE | SENVCFG_CBZE; |
89 | + return gen_sha512_rv64(ctx, a, EXT_NONE, tcg_gen_rotri_i64, 14, 18, 41); | 165 | + |
90 | +} | 166 | + env->senvcfg = (env->senvcfg & ~mask) | (val & mask); |
167 | + | ||
168 | + return RISCV_EXCP_NONE; | ||
169 | +} | ||
170 | + | ||
171 | +static RISCVException read_henvcfg(CPURISCVState *env, int csrno, | ||
172 | + target_ulong *val) | ||
173 | +{ | ||
174 | + *val = env->henvcfg; | ||
175 | + return RISCV_EXCP_NONE; | ||
176 | +} | ||
177 | + | ||
178 | +static RISCVException write_henvcfg(CPURISCVState *env, int csrno, | ||
179 | + target_ulong val) | ||
180 | +{ | ||
181 | + uint64_t mask = HENVCFG_FIOM | HENVCFG_CBIE | HENVCFG_CBCFE | HENVCFG_CBZE; | ||
182 | + | ||
183 | + if (riscv_cpu_mxl(env) == MXL_RV64) { | ||
184 | + mask |= HENVCFG_PBMTE | HENVCFG_STCE; | ||
185 | + } | ||
186 | + | ||
187 | + env->henvcfg = (env->henvcfg & ~mask) | (val & mask); | ||
188 | + | ||
189 | + return RISCV_EXCP_NONE; | ||
190 | +} | ||
191 | + | ||
192 | +static RISCVException read_henvcfgh(CPURISCVState *env, int csrno, | ||
193 | + target_ulong *val) | ||
194 | +{ | ||
195 | + *val = env->henvcfg >> 32; | ||
196 | + return RISCV_EXCP_NONE; | ||
197 | +} | ||
198 | + | ||
199 | +static RISCVException write_henvcfgh(CPURISCVState *env, int csrno, | ||
200 | + target_ulong val) | ||
201 | +{ | ||
202 | + uint64_t mask = HENVCFG_PBMTE | HENVCFG_STCE; | ||
203 | + uint64_t valh = (uint64_t)val << 32; | ||
204 | + | ||
205 | + env->henvcfg = (env->henvcfg & ~mask) | (valh & mask); | ||
206 | + | ||
207 | + return RISCV_EXCP_NONE; | ||
208 | +} | ||
209 | + | ||
210 | static RISCVException rmw_mip64(CPURISCVState *env, int csrno, | ||
211 | uint64_t *ret_val, | ||
212 | uint64_t new_val, uint64_t wr_mask) | ||
213 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | ||
214 | [CSR_MVIPH] = { "mviph", aia_any32, read_zero, write_ignore }, | ||
215 | [CSR_MIPH] = { "miph", aia_any32, NULL, NULL, rmw_miph }, | ||
216 | |||
217 | + /* Execution environment configuration */ | ||
218 | + [CSR_MENVCFG] = { "menvcfg", any, read_menvcfg, write_menvcfg, | ||
219 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
220 | + [CSR_MENVCFGH] = { "menvcfgh", any32, read_menvcfgh, write_menvcfgh, | ||
221 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
222 | + [CSR_SENVCFG] = { "senvcfg", smode, read_senvcfg, write_senvcfg, | ||
223 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
224 | + [CSR_HENVCFG] = { "henvcfg", hmode, read_henvcfg, write_henvcfg, | ||
225 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
226 | + [CSR_HENVCFGH] = { "henvcfgh", hmode32, read_henvcfgh, write_henvcfgh, | ||
227 | + .min_priv_ver = PRIV_VERSION_1_12_0 }, | ||
228 | + | ||
229 | /* Supervisor Trap Setup */ | ||
230 | [CSR_SSTATUS] = { "sstatus", smode, read_sstatus, write_sstatus, NULL, | ||
231 | read_sstatus_i128 }, | ||
232 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c | ||
233 | index XXXXXXX..XXXXXXX 100644 | ||
234 | --- a/target/riscv/machine.c | ||
235 | +++ b/target/riscv/machine.c | ||
236 | @@ -XXX,XX +XXX,XX @@ static int riscv_cpu_post_load(void *opaque, int version_id) | ||
237 | return 0; | ||
238 | } | ||
239 | |||
240 | +static bool envcfg_needed(void *opaque) | ||
241 | +{ | ||
242 | + RISCVCPU *cpu = opaque; | ||
243 | + CPURISCVState *env = &cpu->env; | ||
244 | + | ||
245 | + return (env->priv_ver >= PRIV_VERSION_1_12_0 ? 1 : 0); | ||
246 | +} | ||
247 | + | ||
248 | +static const VMStateDescription vmstate_envcfg = { | ||
249 | + .name = "cpu/envcfg", | ||
250 | + .version_id = 1, | ||
251 | + .minimum_version_id = 1, | ||
252 | + .needed = envcfg_needed, | ||
253 | + .fields = (VMStateField[]) { | ||
254 | + VMSTATE_UINT64(env.menvcfg, RISCVCPU), | ||
255 | + VMSTATE_UINTTL(env.senvcfg, RISCVCPU), | ||
256 | + VMSTATE_UINT64(env.henvcfg, RISCVCPU), | ||
257 | + | ||
258 | + VMSTATE_END_OF_LIST() | ||
259 | + } | ||
260 | +}; | ||
261 | + | ||
262 | const VMStateDescription vmstate_riscv_cpu = { | ||
263 | .name = "cpu", | ||
264 | .version_id = 3, | ||
265 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = { | ||
266 | &vmstate_pointermasking, | ||
267 | &vmstate_rv128, | ||
268 | &vmstate_kvmtimer, | ||
269 | + &vmstate_envcfg, | ||
270 | NULL | ||
271 | } | ||
272 | }; | ||
91 | -- | 273 | -- |
92 | 2.35.1 | 274 | 2.35.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Atish Patra <atishp@rivosinc.com> | ||
1 | 2 | ||
3 | Virt machine uses privileged specification version 1.12 now. | ||
4 | All other machine continue to use the default one defined for that | ||
5 | machine unless changed to 1.12 by the user explicitly. | ||
6 | |||
7 | This commit enforces the privilege version for csrs introduced in | ||
8 | v1.12 or after. | ||
9 | |||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
12 | Message-Id: <20220303185440.512391-7-atishp@rivosinc.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/cpu.c | 8 +++++--- | ||
16 | target/riscv/csr.c | 5 +++++ | ||
17 | 2 files changed, 10 insertions(+), 3 deletions(-) | ||
18 | |||
19 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/target/riscv/cpu.c | ||
22 | +++ b/target/riscv/cpu.c | ||
23 | @@ -XXX,XX +XXX,XX @@ static void riscv_any_cpu_init(Object *obj) | ||
24 | #elif defined(TARGET_RISCV64) | ||
25 | set_misa(env, MXL_RV64, RVI | RVM | RVA | RVF | RVD | RVC | RVU); | ||
26 | #endif | ||
27 | - set_priv_version(env, PRIV_VERSION_1_11_0); | ||
28 | + set_priv_version(env, PRIV_VERSION_1_12_0); | ||
29 | } | ||
30 | |||
31 | #if defined(TARGET_RISCV64) | ||
32 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
33 | } | ||
34 | |||
35 | if (cpu->cfg.priv_spec) { | ||
36 | - if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { | ||
37 | + if (!g_strcmp0(cpu->cfg.priv_spec, "v1.12.0")) { | ||
38 | + priv_version = PRIV_VERSION_1_12_0; | ||
39 | + } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.11.0")) { | ||
40 | priv_version = PRIV_VERSION_1_11_0; | ||
41 | } else if (!g_strcmp0(cpu->cfg.priv_spec, "v1.10.0")) { | ||
42 | priv_version = PRIV_VERSION_1_10_0; | ||
43 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | ||
44 | if (priv_version) { | ||
45 | set_priv_version(env, priv_version); | ||
46 | } else if (!env->priv_ver) { | ||
47 | - set_priv_version(env, PRIV_VERSION_1_11_0); | ||
48 | + set_priv_version(env, PRIV_VERSION_1_12_0); | ||
49 | } | ||
50 | |||
51 | if (cpu->cfg.mmu) { | ||
52 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
53 | index XXXXXXX..XXXXXXX 100644 | ||
54 | --- a/target/riscv/csr.c | ||
55 | +++ b/target/riscv/csr.c | ||
56 | @@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env, | ||
57 | { | ||
58 | /* check privileges and return RISCV_EXCP_ILLEGAL_INST if check fails */ | ||
59 | int read_only = get_field(csrno, 0xC00) == 3; | ||
60 | + int csr_min_priv = csr_ops[csrno].min_priv_ver; | ||
61 | #if !defined(CONFIG_USER_ONLY) | ||
62 | int effective_priv = env->priv; | ||
63 | |||
64 | @@ -XXX,XX +XXX,XX @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env, | ||
65 | return RISCV_EXCP_ILLEGAL_INST; | ||
66 | } | ||
67 | |||
68 | + if (env->priv_ver < csr_min_priv) { | ||
69 | + return RISCV_EXCP_ILLEGAL_INST; | ||
70 | + } | ||
71 | + | ||
72 | return csr_ops[csrno].predicate(env, csrno); | ||
73 | } | ||
74 | |||
75 | -- | ||
76 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Alistair Francis <alistair.francis@wdc.com> |
---|---|---|---|
2 | 2 | ||
3 | Imply the TPM sysbus devices. This allows users to add TPM devices to | 3 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
4 | the RISC-V virt board. | 4 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> |
5 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
6 | Message-Id: <20220317061817.3856850-2-alistair.francis@opensource.wdc.com> | ||
7 | --- | ||
8 | target/riscv/cpu.c | 20 ++++++++++---------- | ||
9 | 1 file changed, 10 insertions(+), 10 deletions(-) | ||
5 | 10 | ||
6 | This was tested by first creating an emulated TPM device: | 11 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
7 | |||
8 | swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \ | ||
9 | --ctrl type=unixio,path=swtpm-sock | ||
10 | |||
11 | Then launching QEMU with: | ||
12 | |||
13 | -chardev socket,id=chrtpm,path=swtpm-sock \ | ||
14 | -tpmdev emulator,id=tpm0,chardev=chrtpm \ | ||
15 | -device tpm-tis-device,tpmdev=tpm0 | ||
16 | |||
17 | The TPM device can be seen in the memory tree and the generated device | ||
18 | tree. | ||
19 | |||
20 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/942 | ||
21 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
22 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | ||
23 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
24 | Message-Id: <20220427234146.1130752-7-alistair.francis@opensource.wdc.com> | ||
25 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
26 | --- | ||
27 | docs/system/riscv/virt.rst | 20 ++++++++++++++++++++ | ||
28 | hw/riscv/virt.c | 4 ++++ | ||
29 | hw/riscv/Kconfig | 1 + | ||
30 | 3 files changed, 25 insertions(+) | ||
31 | |||
32 | diff --git a/docs/system/riscv/virt.rst b/docs/system/riscv/virt.rst | ||
33 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
34 | --- a/docs/system/riscv/virt.rst | 13 | --- a/target/riscv/cpu.c |
35 | +++ b/docs/system/riscv/virt.rst | 14 | +++ b/target/riscv/cpu.c |
36 | @@ -XXX,XX +XXX,XX @@ The minimal QEMU commands to run U-Boot SPL are: | 15 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) |
37 | To test 32-bit U-Boot images, switch to use qemu-riscv32_smode_defconfig and | 16 | if (cpu->cfg.ext_i && cpu->cfg.ext_e) { |
38 | riscv32_spl_defconfig builds, and replace ``qemu-system-riscv64`` with | 17 | error_setg(errp, |
39 | ``qemu-system-riscv32`` in the command lines above to boot the 32-bit U-Boot. | 18 | "I and E extensions are incompatible"); |
40 | + | 19 | - return; |
41 | +Enabling TPM | 20 | - } |
42 | +------------ | 21 | + return; |
43 | + | 22 | + } |
44 | +A TPM device can be connected to the virt board by following the steps below. | 23 | |
45 | + | 24 | if (!cpu->cfg.ext_i && !cpu->cfg.ext_e) { |
46 | +First launch the TPM emulator | 25 | error_setg(errp, |
47 | + | 26 | "Either I or E extension must be set"); |
48 | + swtpm socket --tpm2 -t -d --tpmstate dir=/tmp/tpm \ | 27 | - return; |
49 | + --ctrl type=unixio,path=swtpm-sock | 28 | - } |
50 | + | 29 | + return; |
51 | +Then launch QEMU with: | 30 | + } |
52 | + | 31 | |
53 | + ... | 32 | - if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & |
54 | + -chardev socket,id=chrtpm,path=swtpm-sock \ | 33 | - cpu->cfg.ext_a & cpu->cfg.ext_f & |
55 | + -tpmdev emulator,id=tpm0,chardev=chrtpm \ | 34 | - cpu->cfg.ext_d)) { |
56 | + -device tpm-tis-device,tpmdev=tpm0 | 35 | + if (cpu->cfg.ext_g && !(cpu->cfg.ext_i & cpu->cfg.ext_m & |
57 | + | 36 | + cpu->cfg.ext_a & cpu->cfg.ext_f & |
58 | +The TPM device can be seen in the memory tree and the generated device | 37 | + cpu->cfg.ext_d)) { |
59 | +tree and should be accessible from the guest software. | 38 | warn_report("Setting G will also set IMAFD"); |
60 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 39 | cpu->cfg.ext_i = true; |
61 | index XXXXXXX..XXXXXXX 100644 | 40 | cpu->cfg.ext_m = true; |
62 | --- a/hw/riscv/virt.c | 41 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) |
63 | +++ b/hw/riscv/virt.c | 42 | case IRQ_S_EXT: |
64 | @@ -XXX,XX +XXX,XX @@ | 43 | case IRQ_VS_EXT: |
65 | #include "sysemu/device_tree.h" | 44 | case IRQ_M_EXT: |
66 | #include "sysemu/sysemu.h" | 45 | - if (kvm_enabled()) { |
67 | #include "sysemu/kvm.h" | 46 | + if (kvm_enabled()) { |
68 | +#include "sysemu/tpm.h" | 47 | kvm_riscv_set_irq(cpu, irq, level); |
69 | #include "hw/pci/pci.h" | 48 | - } else { |
70 | #include "hw/pci-host/gpex.h" | 49 | + } else { |
71 | #include "hw/display/ramfb.h" | 50 | riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level)); |
72 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data) | 51 | - } |
73 | hc->plug = virt_machine_device_plug_cb; | 52 | + } |
74 | 53 | break; | |
75 | machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); | 54 | default: |
76 | +#ifdef CONFIG_TPM | 55 | g_assert_not_reached(); |
77 | + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); | ||
78 | +#endif | ||
79 | |||
80 | object_class_property_add_bool(oc, "aclint", virt_get_aclint, | ||
81 | virt_set_aclint); | ||
82 | diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig | ||
83 | index XXXXXXX..XXXXXXX 100644 | ||
84 | --- a/hw/riscv/Kconfig | ||
85 | +++ b/hw/riscv/Kconfig | ||
86 | @@ -XXX,XX +XXX,XX @@ config RISCV_VIRT | ||
87 | imply PCI_DEVICES | ||
88 | imply VIRTIO_VGA | ||
89 | imply TEST_DEVICES | ||
90 | + imply TPM_TIS_SYSBUS | ||
91 | select RISCV_NUMA | ||
92 | select GOLDFISH_RTC | ||
93 | select MSI_NONBROKEN | ||
94 | -- | 56 | -- |
95 | 2.35.1 | 57 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Alistair Francis <alistair.francis@wdc.com> |
---|---|---|---|
2 | 2 | ||
3 | The ARM virt machine currently uses sysbus-fdt to create device tree | 3 | The RISC-V specification states that: |
4 | entries for dynamically created MMIO devices. | 4 | "Supervisor-level external interrupts are made pending based on the |
5 | logical-OR of the software-writable SEIP bit and the signal from the | ||
6 | external interrupt controller." | ||
5 | 7 | ||
6 | The RISC-V virt machine can also benefit from this, so move the code to | 8 | We currently only allow either the interrupt controller or software to |
7 | the core directory. | 9 | set the bit, which is incorrect. |
8 | 10 | ||
11 | This patch removes the miclaim mask when writing MIP to allow M-mode | ||
12 | software to inject interrupts, even with an interrupt controller. | ||
13 | |||
14 | We then also need to keep track of which source is setting MIP_SEIP. The | ||
15 | final value is a OR of both, so we add two bools and use that to keep | ||
16 | track of the current state. This way either source can change without | ||
17 | losing the correct value. | ||
18 | |||
19 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/904 | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 20 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | ||
11 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 21 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> |
12 | Message-Id: <20220427234146.1130752-3-alistair.francis@opensource.wdc.com> | 22 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> |
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 23 | Message-Id: <20220317061817.3856850-3-alistair.francis@opensource.wdc.com> |
14 | --- | 24 | --- |
15 | include/hw/{arm => core}/sysbus-fdt.h | 0 | 25 | target/riscv/cpu.h | 8 ++++++++ |
16 | hw/arm/virt.c | 2 +- | 26 | target/riscv/cpu.c | 10 +++++++++- |
17 | hw/arm/xlnx-versal-virt.c | 1 - | 27 | target/riscv/csr.c | 8 ++++++-- |
18 | hw/{arm => core}/sysbus-fdt.c | 2 +- | 28 | 3 files changed, 23 insertions(+), 3 deletions(-) |
19 | hw/arm/meson.build | 1 - | ||
20 | hw/core/meson.build | 1 + | ||
21 | 6 files changed, 3 insertions(+), 4 deletions(-) | ||
22 | rename include/hw/{arm => core}/sysbus-fdt.h (100%) | ||
23 | rename hw/{arm => core}/sysbus-fdt.c (99%) | ||
24 | 29 | ||
25 | diff --git a/include/hw/arm/sysbus-fdt.h b/include/hw/core/sysbus-fdt.h | 30 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
26 | similarity index 100% | ||
27 | rename from include/hw/arm/sysbus-fdt.h | ||
28 | rename to include/hw/core/sysbus-fdt.h | ||
29 | diff --git a/hw/arm/virt.c b/hw/arm/virt.c | ||
30 | index XXXXXXX..XXXXXXX 100644 | 31 | index XXXXXXX..XXXXXXX 100644 |
31 | --- a/hw/arm/virt.c | 32 | --- a/target/riscv/cpu.h |
32 | +++ b/hw/arm/virt.c | 33 | +++ b/target/riscv/cpu.h |
33 | @@ -XXX,XX +XXX,XX @@ | 34 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { |
34 | #include "qemu/module.h" | 35 | uint64_t mstatus; |
35 | #include "hw/pci-host/gpex.h" | 36 | |
36 | #include "hw/virtio/virtio-pci.h" | 37 | uint64_t mip; |
37 | -#include "hw/arm/sysbus-fdt.h" | 38 | + /* |
38 | +#include "hw/core/sysbus-fdt.h" | 39 | + * MIP contains the software writable version of SEIP ORed with the |
39 | #include "hw/platform-bus.h" | 40 | + * external interrupt value. The MIP register is always up-to-date. |
40 | #include "hw/qdev-properties.h" | 41 | + * To keep track of the current source, we also save booleans of the values |
41 | #include "hw/arm/fdt.h" | 42 | + * here. |
42 | diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c | 43 | + */ |
44 | + bool external_seip; | ||
45 | + bool software_seip; | ||
46 | |||
47 | uint64_t miclaim; | ||
48 | |||
49 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | ||
43 | index XXXXXXX..XXXXXXX 100644 | 50 | index XXXXXXX..XXXXXXX 100644 |
44 | --- a/hw/arm/xlnx-versal-virt.c | 51 | --- a/target/riscv/cpu.c |
45 | +++ b/hw/arm/xlnx-versal-virt.c | 52 | +++ b/target/riscv/cpu.c |
46 | @@ -XXX,XX +XXX,XX @@ | 53 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) |
47 | #include "sysemu/device_tree.h" | 54 | case IRQ_VS_TIMER: |
48 | #include "hw/boards.h" | 55 | case IRQ_M_TIMER: |
49 | #include "hw/sysbus.h" | 56 | case IRQ_U_EXT: |
50 | -#include "hw/arm/sysbus-fdt.h" | 57 | - case IRQ_S_EXT: |
51 | #include "hw/arm/fdt.h" | 58 | case IRQ_VS_EXT: |
52 | #include "cpu.h" | 59 | case IRQ_M_EXT: |
53 | #include "hw/qdev-properties.h" | 60 | if (kvm_enabled()) { |
54 | diff --git a/hw/arm/sysbus-fdt.c b/hw/core/sysbus-fdt.c | 61 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) |
55 | similarity index 99% | 62 | riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level)); |
56 | rename from hw/arm/sysbus-fdt.c | 63 | } |
57 | rename to hw/core/sysbus-fdt.c | 64 | break; |
65 | + case IRQ_S_EXT: | ||
66 | + if (kvm_enabled()) { | ||
67 | + kvm_riscv_set_irq(cpu, irq, level); | ||
68 | + } else { | ||
69 | + env->external_seip = level; | ||
70 | + riscv_cpu_update_mip(cpu, 1 << irq, | ||
71 | + BOOL_TO_MASK(level | env->software_seip)); | ||
72 | + } | ||
73 | + break; | ||
74 | default: | ||
75 | g_assert_not_reached(); | ||
76 | } | ||
77 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | ||
58 | index XXXXXXX..XXXXXXX 100644 | 78 | index XXXXXXX..XXXXXXX 100644 |
59 | --- a/hw/arm/sysbus-fdt.c | 79 | --- a/target/riscv/csr.c |
60 | +++ b/hw/core/sysbus-fdt.c | 80 | +++ b/target/riscv/csr.c |
61 | @@ -XXX,XX +XXX,XX @@ | 81 | @@ -XXX,XX +XXX,XX @@ static RISCVException rmw_mip64(CPURISCVState *env, int csrno, |
62 | #ifdef CONFIG_LINUX | 82 | uint64_t new_val, uint64_t wr_mask) |
63 | #include <linux/vfio.h> | 83 | { |
64 | #endif | 84 | RISCVCPU *cpu = env_archcpu(env); |
65 | -#include "hw/arm/sysbus-fdt.h" | 85 | - /* Allow software control of delegable interrupts not claimed by hardware */ |
66 | +#include "hw/core/sysbus-fdt.h" | 86 | - uint64_t old_mip, mask = wr_mask & delegable_ints & ~env->miclaim; |
67 | #include "qemu/error-report.h" | 87 | + uint64_t old_mip, mask = wr_mask & delegable_ints; |
68 | #include "sysemu/device_tree.h" | 88 | uint32_t gin; |
69 | #include "sysemu/tpm.h" | 89 | |
70 | diff --git a/hw/arm/meson.build b/hw/arm/meson.build | 90 | + if (mask & MIP_SEIP) { |
71 | index XXXXXXX..XXXXXXX 100644 | 91 | + env->software_seip = new_val & MIP_SEIP; |
72 | --- a/hw/arm/meson.build | 92 | + new_val |= env->external_seip * MIP_SEIP; |
73 | +++ b/hw/arm/meson.build | 93 | + } |
74 | @@ -XXX,XX +XXX,XX @@ | 94 | + |
75 | arm_ss = ss.source_set() | 95 | if (mask) { |
76 | arm_ss.add(files('boot.c'), fdt) | 96 | old_mip = riscv_cpu_update_mip(cpu, mask, (new_val & mask)); |
77 | -arm_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c')) | 97 | } else { |
78 | arm_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c')) | ||
79 | arm_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) | ||
80 | arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c')) | ||
81 | diff --git a/hw/core/meson.build b/hw/core/meson.build | ||
82 | index XXXXXXX..XXXXXXX 100644 | ||
83 | --- a/hw/core/meson.build | ||
84 | +++ b/hw/core/meson.build | ||
85 | @@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_PTIMER', if_true: files('ptimer.c')) | ||
86 | softmmu_ss.add(when: 'CONFIG_REGISTER', if_true: files('register.c')) | ||
87 | softmmu_ss.add(when: 'CONFIG_SPLIT_IRQ', if_true: files('split-irq.c')) | ||
88 | softmmu_ss.add(when: 'CONFIG_XILINX_AXI', if_true: files('stream.c')) | ||
89 | +softmmu_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c')) | ||
90 | |||
91 | softmmu_ss.add(files( | ||
92 | 'cpu-sysemu.c', | ||
93 | -- | 98 | -- |
94 | 2.35.1 | 99 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Bin Meng <bin.meng@windriver.com> |
---|---|---|---|
2 | 2 | ||
3 | - add aes32esmi, aes32esi, aes32dsmi and aes32dsi instructions | 3 | This adds initial support for the Sdtrig extension via the Trigger |
4 | Module, as defined in the RISC-V Debug Specification [1]. | ||
4 | 5 | ||
5 | Co-authored-by: Zewen Ye <lustrew@foxmail.com> | 6 | Only "Address / Data Match" trigger (type 2) is implemented as of now, |
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | which is mainly used for hardware breakpoint and watchpoint. The number |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 8 | of type 2 triggers implemented is 2, which is the number that we can |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 9 | find in the SiFive U54/U74 cores. |
10 | |||
11 | [1] https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf | ||
12 | |||
13 | Signed-off-by: Bin Meng <bin.meng@windriver.com> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-Id: <20220423023510.30794-7-liweiwei@iscas.ac.cn> | 15 | Message-Id: <20220315065529.62198-2-bmeng.cn@gmail.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/helper.h | 6 ++ | 18 | target/riscv/cpu.h | 5 + |
14 | target/riscv/insn32.decode | 11 +++ | 19 | target/riscv/debug.h | 108 +++++++++++++ |
15 | target/riscv/crypto_helper.c | 105 ++++++++++++++++++++++++ | 20 | target/riscv/debug.c | 339 +++++++++++++++++++++++++++++++++++++++ |
16 | target/riscv/translate.c | 1 + | 21 | target/riscv/meson.build | 1 + |
17 | target/riscv/insn_trans/trans_rvk.c.inc | 71 ++++++++++++++++ | 22 | 4 files changed, 453 insertions(+) |
18 | target/riscv/meson.build | 3 +- | 23 | create mode 100644 target/riscv/debug.h |
19 | 6 files changed, 196 insertions(+), 1 deletion(-) | 24 | create mode 100644 target/riscv/debug.c |
20 | create mode 100644 target/riscv/crypto_helper.c | ||
21 | create mode 100644 target/riscv/insn_trans/trans_rvk.c.inc | ||
22 | 25 | ||
23 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | 26 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
24 | index XXXXXXX..XXXXXXX 100644 | 27 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/target/riscv/helper.h | 28 | --- a/target/riscv/cpu.h |
26 | +++ b/target/riscv/helper.h | 29 | +++ b/target/riscv/cpu.h |
27 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_5(divu_i128, tl, env, tl, tl, tl, tl) | 30 | @@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState CPURISCVState; |
28 | DEF_HELPER_5(divs_i128, tl, env, tl, tl, tl, tl) | 31 | |
29 | DEF_HELPER_5(remu_i128, tl, env, tl, tl, tl, tl) | 32 | #if !defined(CONFIG_USER_ONLY) |
30 | DEF_HELPER_5(rems_i128, tl, env, tl, tl, tl, tl) | 33 | #include "pmp.h" |
31 | + | 34 | +#include "debug.h" |
32 | +/* Crypto functions */ | 35 | #endif |
33 | +DEF_HELPER_FLAGS_3(aes32esmi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 36 | |
34 | +DEF_HELPER_FLAGS_3(aes32esi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 37 | #define RV_VLEN_MAX 1024 |
35 | +DEF_HELPER_FLAGS_3(aes32dsmi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 38 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { |
36 | +DEF_HELPER_FLAGS_3(aes32dsi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 39 | pmp_table_t pmp_state; |
37 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 40 | target_ulong mseccfg; |
38 | index XXXXXXX..XXXXXXX 100644 | 41 | |
39 | --- a/target/riscv/insn32.decode | 42 | + /* trigger module */ |
40 | +++ b/target/riscv/insn32.decode | 43 | + target_ulong trigger_cur; |
41 | @@ -XXX,XX +XXX,XX @@ | 44 | + type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM]; |
42 | %imm_b 31:s1 7:1 25:6 8:4 !function=ex_shift_1 | 45 | + |
43 | %imm_j 31:s1 12:8 20:1 21:10 !function=ex_shift_1 | 46 | /* machine specific rdtime callback */ |
44 | %imm_u 12:s20 !function=ex_shift_12 | 47 | uint64_t (*rdtime_fn)(uint32_t); |
45 | +%imm_bs 30:2 !function=ex_shift_3 | 48 | uint32_t rdtime_fn_arg; |
46 | 49 | diff --git a/target/riscv/debug.h b/target/riscv/debug.h | |
47 | # Argument sets: | ||
48 | &empty | ||
49 | @@ -XXX,XX +XXX,XX @@ | ||
50 | &rmr vm rd rs2 | ||
51 | &r2nfvm vm rd rs1 nf | ||
52 | &rnfvm vm rd rs1 rs2 nf | ||
53 | +&k_aes shamt rs2 rs1 rd | ||
54 | |||
55 | # Formats 32: | ||
56 | @r ....... ..... ..... ... ..... ....... &r %rs2 %rs1 %rd | ||
57 | @@ -XXX,XX +XXX,XX @@ | ||
58 | @sfence_vma ....... ..... ..... ... ..... ....... %rs2 %rs1 | ||
59 | @sfence_vm ....... ..... ..... ... ..... ....... %rs1 | ||
60 | |||
61 | +@k_aes .. ..... ..... ..... ... ..... ....... &k_aes shamt=%imm_bs %rs2 %rs1 %rd | ||
62 | + | ||
63 | # Formats 64: | ||
64 | @sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd | ||
65 | |||
66 | @@ -XXX,XX +XXX,XX @@ sfence_w_inval 0001100 00000 00000 000 00000 1110011 | ||
67 | sfence_inval_ir 0001100 00001 00000 000 00000 1110011 | ||
68 | hinval_vvma 0010011 ..... ..... 000 00000 1110011 @hfence_vvma | ||
69 | hinval_gvma 0110011 ..... ..... 000 00000 1110011 @hfence_gvma | ||
70 | + | ||
71 | +# *** RV32 Zknd Standard Extension *** | ||
72 | +aes32dsmi .. 10111 ..... ..... 000 ..... 0110011 @k_aes | ||
73 | +aes32dsi .. 10101 ..... ..... 000 ..... 0110011 @k_aes | ||
74 | +# *** RV32 Zkne Standard Extension *** | ||
75 | +aes32esmi .. 10011 ..... ..... 000 ..... 0110011 @k_aes | ||
76 | +aes32esi .. 10001 ..... ..... 000 ..... 0110011 @k_aes | ||
77 | diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c | ||
78 | new file mode 100644 | 50 | new file mode 100644 |
79 | index XXXXXXX..XXXXXXX | 51 | index XXXXXXX..XXXXXXX |
80 | --- /dev/null | 52 | --- /dev/null |
81 | +++ b/target/riscv/crypto_helper.c | 53 | +++ b/target/riscv/debug.h |
82 | @@ -XXX,XX +XXX,XX @@ | 54 | @@ -XXX,XX +XXX,XX @@ |
83 | +/* | 55 | +/* |
84 | + * RISC-V Crypto Emulation Helpers for QEMU. | 56 | + * QEMU RISC-V Native Debug Support |
85 | + * | 57 | + * |
86 | + * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com | 58 | + * Copyright (c) 2022 Wind River Systems, Inc. |
87 | + * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com | 59 | + * |
60 | + * Author: | ||
61 | + * Bin Meng <bin.meng@windriver.com> | ||
88 | + * | 62 | + * |
89 | + * This program is free software; you can redistribute it and/or modify it | 63 | + * This program is free software; you can redistribute it and/or modify it |
90 | + * under the terms and conditions of the GNU General Public License, | 64 | + * under the terms and conditions of the GNU General Public License, |
91 | + * version 2 or later, as published by the Free Software Foundation. | 65 | + * version 2 or later, as published by the Free Software Foundation. |
92 | + * | 66 | + * |
... | ... | ||
97 | + * | 71 | + * |
98 | + * You should have received a copy of the GNU General Public License along with | 72 | + * You should have received a copy of the GNU General Public License along with |
99 | + * this program. If not, see <http://www.gnu.org/licenses/>. | 73 | + * this program. If not, see <http://www.gnu.org/licenses/>. |
100 | + */ | 74 | + */ |
101 | + | 75 | + |
102 | +#include "qemu/osdep.h" | 76 | +#ifndef RISCV_DEBUG_H |
103 | +#include "cpu.h" | 77 | +#define RISCV_DEBUG_H |
104 | +#include "exec/exec-all.h" | 78 | + |
105 | +#include "exec/helper-proto.h" | 79 | +/* trigger indexes implemented */ |
106 | +#include "crypto/aes.h" | 80 | +enum { |
107 | +#include "crypto/sm4.h" | 81 | + TRIGGER_TYPE2_IDX_0 = 0, |
108 | + | 82 | + TRIGGER_TYPE2_IDX_1, |
109 | +#define AES_XTIME(a) \ | 83 | + TRIGGER_TYPE2_NUM, |
110 | + ((a << 1) ^ ((a & 0x80) ? 0x1b : 0)) | 84 | + TRIGGER_NUM = TRIGGER_TYPE2_NUM |
111 | + | 85 | +}; |
112 | +#define AES_GFMUL(a, b) (( \ | 86 | + |
113 | + (((b) & 0x1) ? (a) : 0) ^ \ | 87 | +/* register index of tdata CSRs */ |
114 | + (((b) & 0x2) ? AES_XTIME(a) : 0) ^ \ | 88 | +enum { |
115 | + (((b) & 0x4) ? AES_XTIME(AES_XTIME(a)) : 0) ^ \ | 89 | + TDATA1 = 0, |
116 | + (((b) & 0x8) ? AES_XTIME(AES_XTIME(AES_XTIME(a))) : 0)) & 0xFF) | 90 | + TDATA2, |
117 | + | 91 | + TDATA3, |
118 | +static inline uint32_t aes_mixcolumn_byte(uint8_t x, bool fwd) | 92 | + TDATA_NUM |
119 | +{ | 93 | +}; |
120 | + uint32_t u; | 94 | + |
121 | + | 95 | +typedef enum { |
122 | + if (fwd) { | 96 | + TRIGGER_TYPE_NO_EXIST = 0, /* trigger does not exist */ |
123 | + u = (AES_GFMUL(x, 3) << 24) | (x << 16) | (x << 8) | | 97 | + TRIGGER_TYPE_AD_MATCH = 2, /* address/data match trigger */ |
124 | + (AES_GFMUL(x, 2) << 0); | 98 | + TRIGGER_TYPE_INST_CNT = 3, /* instruction count trigger */ |
125 | + } else { | 99 | + TRIGGER_TYPE_INT = 4, /* interrupt trigger */ |
126 | + u = (AES_GFMUL(x, 0xb) << 24) | (AES_GFMUL(x, 0xd) << 16) | | 100 | + TRIGGER_TYPE_EXCP = 5, /* exception trigger */ |
127 | + (AES_GFMUL(x, 0x9) << 8) | (AES_GFMUL(x, 0xe) << 0); | 101 | + TRIGGER_TYPE_AD_MATCH6 = 6, /* new address/data match trigger */ |
128 | + } | 102 | + TRIGGER_TYPE_EXT_SRC = 7, /* external source trigger */ |
129 | + return u; | 103 | + TRIGGER_TYPE_UNAVAIL = 15 /* trigger exists, but unavailable */ |
130 | +} | 104 | +} trigger_type_t; |
131 | + | 105 | + |
132 | +#define sext32_xlen(x) (target_ulong)(int32_t)(x) | 106 | +typedef struct { |
133 | + | 107 | + target_ulong mcontrol; |
134 | +static inline target_ulong aes32_operation(target_ulong shamt, | 108 | + target_ulong maddress; |
135 | + target_ulong rs1, target_ulong rs2, | 109 | + struct CPUBreakpoint *bp; |
136 | + bool enc, bool mix) | 110 | + struct CPUWatchpoint *wp; |
137 | +{ | 111 | +} type2_trigger_t; |
138 | + uint8_t si = rs2 >> shamt; | 112 | + |
139 | + uint8_t so; | 113 | +/* tdata field masks */ |
140 | + uint32_t mixed; | 114 | + |
141 | + target_ulong res; | 115 | +#define RV32_TYPE(t) ((uint32_t)(t) << 28) |
142 | + | 116 | +#define RV32_TYPE_MASK (0xf << 28) |
143 | + if (enc) { | 117 | +#define RV32_DMODE BIT(27) |
144 | + so = AES_sbox[si]; | 118 | +#define RV64_TYPE(t) ((uint64_t)(t) << 60) |
145 | + if (mix) { | 119 | +#define RV64_TYPE_MASK (0xfULL << 60) |
146 | + mixed = aes_mixcolumn_byte(so, true); | 120 | +#define RV64_DMODE BIT_ULL(59) |
147 | + } else { | 121 | + |
148 | + mixed = so; | 122 | +/* mcontrol field masks */ |
149 | + } | 123 | + |
150 | + } else { | 124 | +#define TYPE2_LOAD BIT(0) |
151 | + so = AES_isbox[si]; | 125 | +#define TYPE2_STORE BIT(1) |
152 | + if (mix) { | 126 | +#define TYPE2_EXEC BIT(2) |
153 | + mixed = aes_mixcolumn_byte(so, false); | 127 | +#define TYPE2_U BIT(3) |
154 | + } else { | 128 | +#define TYPE2_S BIT(4) |
155 | + mixed = so; | 129 | +#define TYPE2_M BIT(6) |
156 | + } | 130 | +#define TYPE2_MATCH (0xf << 7) |
157 | + } | 131 | +#define TYPE2_CHAIN BIT(11) |
158 | + mixed = rol32(mixed, shamt); | 132 | +#define TYPE2_ACTION (0xf << 12) |
159 | + res = rs1 ^ mixed; | 133 | +#define TYPE2_SIZELO (0x3 << 16) |
160 | + | 134 | +#define TYPE2_TIMING BIT(18) |
161 | + return sext32_xlen(res); | 135 | +#define TYPE2_SELECT BIT(19) |
162 | +} | 136 | +#define TYPE2_HIT BIT(20) |
163 | + | 137 | +#define TYPE2_SIZEHI (0x3 << 21) /* RV64 only */ |
164 | +target_ulong HELPER(aes32esmi)(target_ulong rs1, target_ulong rs2, | 138 | + |
165 | + target_ulong shamt) | 139 | +/* access size */ |
166 | +{ | 140 | +enum { |
167 | + return aes32_operation(shamt, rs1, rs2, true, true); | 141 | + SIZE_ANY = 0, |
168 | +} | 142 | + SIZE_1B, |
169 | + | 143 | + SIZE_2B, |
170 | +target_ulong HELPER(aes32esi)(target_ulong rs1, target_ulong rs2, | 144 | + SIZE_4B, |
171 | + target_ulong shamt) | 145 | + SIZE_6B, |
172 | +{ | 146 | + SIZE_8B, |
173 | + return aes32_operation(shamt, rs1, rs2, true, false); | 147 | + SIZE_10B, |
174 | +} | 148 | + SIZE_12B, |
175 | + | 149 | + SIZE_14B, |
176 | +target_ulong HELPER(aes32dsmi)(target_ulong rs1, target_ulong rs2, | 150 | + SIZE_16B, |
177 | + target_ulong shamt) | 151 | + SIZE_NUM = 16 |
178 | +{ | 152 | +}; |
179 | + return aes32_operation(shamt, rs1, rs2, false, true); | 153 | + |
180 | +} | 154 | +bool tdata_available(CPURISCVState *env, int tdata_index); |
181 | + | 155 | + |
182 | +target_ulong HELPER(aes32dsi)(target_ulong rs1, target_ulong rs2, | 156 | +target_ulong tselect_csr_read(CPURISCVState *env); |
183 | + target_ulong shamt) | 157 | +void tselect_csr_write(CPURISCVState *env, target_ulong val); |
184 | +{ | 158 | + |
185 | + return aes32_operation(shamt, rs1, rs2, false, false); | 159 | +target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index); |
186 | +} | 160 | +void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val); |
187 | +#undef sext32_xlen | 161 | + |
188 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | 162 | +#endif /* RISCV_DEBUG_H */ |
189 | index XXXXXXX..XXXXXXX 100644 | 163 | diff --git a/target/riscv/debug.c b/target/riscv/debug.c |
190 | --- a/target/riscv/translate.c | ||
191 | +++ b/target/riscv/translate.c | ||
192 | @@ -XXX,XX +XXX,XX @@ static uint32_t opcode_at(DisasContextBase *dcbase, target_ulong pc) | ||
193 | #include "insn_trans/trans_rvv.c.inc" | ||
194 | #include "insn_trans/trans_rvb.c.inc" | ||
195 | #include "insn_trans/trans_rvzfh.c.inc" | ||
196 | +#include "insn_trans/trans_rvk.c.inc" | ||
197 | #include "insn_trans/trans_privileged.c.inc" | ||
198 | #include "insn_trans/trans_svinval.c.inc" | ||
199 | #include "insn_trans/trans_xventanacondops.c.inc" | ||
200 | diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc | ||
201 | new file mode 100644 | 164 | new file mode 100644 |
202 | index XXXXXXX..XXXXXXX | 165 | index XXXXXXX..XXXXXXX |
203 | --- /dev/null | 166 | --- /dev/null |
204 | +++ b/target/riscv/insn_trans/trans_rvk.c.inc | 167 | +++ b/target/riscv/debug.c |
205 | @@ -XXX,XX +XXX,XX @@ | 168 | @@ -XXX,XX +XXX,XX @@ |
206 | +/* | 169 | +/* |
207 | + * RISC-V translation routines for the Zk[nd,ne,nh,sed,sh] Standard Extension. | 170 | + * QEMU RISC-V Native Debug Support |
208 | + * | 171 | + * |
209 | + * Copyright (c) 2021 Ruibo Lu, luruibo2000@163.com | 172 | + * Copyright (c) 2022 Wind River Systems, Inc. |
210 | + * Copyright (c) 2021 Zewen Ye, lustrew@foxmail.com | 173 | + * |
174 | + * Author: | ||
175 | + * Bin Meng <bin.meng@windriver.com> | ||
176 | + * | ||
177 | + * This provides the native debug support via the Trigger Module, as defined | ||
178 | + * in the RISC-V Debug Specification: | ||
179 | + * https://github.com/riscv/riscv-debug-spec/raw/master/riscv-debug-stable.pdf | ||
211 | + * | 180 | + * |
212 | + * This program is free software; you can redistribute it and/or modify it | 181 | + * This program is free software; you can redistribute it and/or modify it |
213 | + * under the terms and conditions of the GNU General Public License, | 182 | + * under the terms and conditions of the GNU General Public License, |
214 | + * version 2 or later, as published by the Free Software Foundation. | 183 | + * version 2 or later, as published by the Free Software Foundation. |
215 | + * | 184 | + * |
... | ... | ||
220 | + * | 189 | + * |
221 | + * You should have received a copy of the GNU General Public License along with | 190 | + * You should have received a copy of the GNU General Public License along with |
222 | + * this program. If not, see <http://www.gnu.org/licenses/>. | 191 | + * this program. If not, see <http://www.gnu.org/licenses/>. |
223 | + */ | 192 | + */ |
224 | + | 193 | + |
225 | +#define REQUIRE_ZKND(ctx) do { \ | 194 | +#include "qemu/osdep.h" |
226 | + if (!ctx->cfg_ptr->ext_zknd) { \ | 195 | +#include "qemu/log.h" |
227 | + return false; \ | 196 | +#include "qapi/error.h" |
228 | + } \ | 197 | +#include "cpu.h" |
229 | +} while (0) | 198 | +#include "trace.h" |
230 | + | 199 | +#include "exec/exec-all.h" |
231 | +#define REQUIRE_ZKNE(ctx) do { \ | 200 | + |
232 | + if (!ctx->cfg_ptr->ext_zkne) { \ | 201 | +/* |
233 | + return false; \ | 202 | + * The following M-mode trigger CSRs are implemented: |
234 | + } \ | 203 | + * |
235 | +} while (0) | 204 | + * - tselect |
236 | + | 205 | + * - tdata1 |
237 | +static bool gen_aes32_sm4(DisasContext *ctx, arg_k_aes *a, | 206 | + * - tdata2 |
238 | + void (*func)(TCGv, TCGv, TCGv, TCGv)) | 207 | + * - tdata3 |
239 | +{ | 208 | + * |
240 | + TCGv shamt = tcg_constant_tl(a->shamt); | 209 | + * We don't support writable 'type' field in the tdata1 register, so there is |
241 | + TCGv dest = dest_gpr(ctx, a->rd); | 210 | + * no need to implement the "tinfo" CSR. |
242 | + TCGv src1 = get_gpr(ctx, a->rs1, EXT_NONE); | 211 | + * |
243 | + TCGv src2 = get_gpr(ctx, a->rs2, EXT_NONE); | 212 | + * The following triggers are implemented: |
244 | + | 213 | + * |
245 | + func(dest, src1, src2, shamt); | 214 | + * Index | Type | tdata mapping | Description |
246 | + gen_set_gpr(ctx, a->rd, dest); | 215 | + * ------+------+------------------------+------------ |
247 | + return true; | 216 | + * 0 | 2 | tdata1, tdata2 | Address / Data Match |
248 | +} | 217 | + * 1 | 2 | tdata1, tdata2 | Address / Data Match |
249 | + | 218 | + */ |
250 | +static bool trans_aes32esmi(DisasContext *ctx, arg_aes32esmi *a) | 219 | + |
251 | +{ | 220 | +/* tdata availability of a trigger */ |
252 | + REQUIRE_32BIT(ctx); | 221 | +typedef bool tdata_avail[TDATA_NUM]; |
253 | + REQUIRE_ZKNE(ctx); | 222 | + |
254 | + return gen_aes32_sm4(ctx, a, gen_helper_aes32esmi); | 223 | +static tdata_avail tdata_mapping[TRIGGER_NUM] = { |
255 | +} | 224 | + [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = { true, true, false }, |
256 | + | 225 | +}; |
257 | +static bool trans_aes32esi(DisasContext *ctx, arg_aes32esi *a) | 226 | + |
258 | +{ | 227 | +/* only breakpoint size 1/2/4/8 supported */ |
259 | + REQUIRE_32BIT(ctx); | 228 | +static int access_size[SIZE_NUM] = { |
260 | + REQUIRE_ZKNE(ctx); | 229 | + [SIZE_ANY] = 0, |
261 | + return gen_aes32_sm4(ctx, a, gen_helper_aes32esi); | 230 | + [SIZE_1B] = 1, |
262 | +} | 231 | + [SIZE_2B] = 2, |
263 | + | 232 | + [SIZE_4B] = 4, |
264 | +static bool trans_aes32dsmi(DisasContext *ctx, arg_aes32dsmi *a) | 233 | + [SIZE_6B] = -1, |
265 | +{ | 234 | + [SIZE_8B] = 8, |
266 | + REQUIRE_32BIT(ctx); | 235 | + [6 ... 15] = -1, |
267 | + REQUIRE_ZKND(ctx); | 236 | +}; |
268 | + return gen_aes32_sm4(ctx, a, gen_helper_aes32dsmi); | 237 | + |
269 | +} | 238 | +static inline target_ulong trigger_type(CPURISCVState *env, |
270 | + | 239 | + trigger_type_t type) |
271 | +static bool trans_aes32dsi(DisasContext *ctx, arg_aes32dsi *a) | 240 | +{ |
272 | +{ | 241 | + target_ulong tdata1; |
273 | + REQUIRE_32BIT(ctx); | 242 | + |
274 | + REQUIRE_ZKND(ctx); | 243 | + switch (riscv_cpu_mxl(env)) { |
275 | + return gen_aes32_sm4(ctx, a, gen_helper_aes32dsi); | 244 | + case MXL_RV32: |
245 | + tdata1 = RV32_TYPE(type); | ||
246 | + break; | ||
247 | + case MXL_RV64: | ||
248 | + tdata1 = RV64_TYPE(type); | ||
249 | + break; | ||
250 | + default: | ||
251 | + g_assert_not_reached(); | ||
252 | + } | ||
253 | + | ||
254 | + return tdata1; | ||
255 | +} | ||
256 | + | ||
257 | +bool tdata_available(CPURISCVState *env, int tdata_index) | ||
258 | +{ | ||
259 | + if (unlikely(tdata_index >= TDATA_NUM)) { | ||
260 | + return false; | ||
261 | + } | ||
262 | + | ||
263 | + if (unlikely(env->trigger_cur >= TRIGGER_NUM)) { | ||
264 | + return false; | ||
265 | + } | ||
266 | + | ||
267 | + return tdata_mapping[env->trigger_cur][tdata_index]; | ||
268 | +} | ||
269 | + | ||
270 | +target_ulong tselect_csr_read(CPURISCVState *env) | ||
271 | +{ | ||
272 | + return env->trigger_cur; | ||
273 | +} | ||
274 | + | ||
275 | +void tselect_csr_write(CPURISCVState *env, target_ulong val) | ||
276 | +{ | ||
277 | + /* all target_ulong bits of tselect are implemented */ | ||
278 | + env->trigger_cur = val; | ||
279 | +} | ||
280 | + | ||
281 | +static target_ulong tdata1_validate(CPURISCVState *env, target_ulong val, | ||
282 | + trigger_type_t t) | ||
283 | +{ | ||
284 | + uint32_t type, dmode; | ||
285 | + target_ulong tdata1; | ||
286 | + | ||
287 | + switch (riscv_cpu_mxl(env)) { | ||
288 | + case MXL_RV32: | ||
289 | + type = extract32(val, 28, 4); | ||
290 | + dmode = extract32(val, 27, 1); | ||
291 | + tdata1 = RV32_TYPE(t); | ||
292 | + break; | ||
293 | + case MXL_RV64: | ||
294 | + type = extract64(val, 60, 4); | ||
295 | + dmode = extract64(val, 59, 1); | ||
296 | + tdata1 = RV64_TYPE(t); | ||
297 | + break; | ||
298 | + default: | ||
299 | + g_assert_not_reached(); | ||
300 | + } | ||
301 | + | ||
302 | + if (type != t) { | ||
303 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
304 | + "ignoring type write to tdata1 register\n"); | ||
305 | + } | ||
306 | + if (dmode != 0) { | ||
307 | + qemu_log_mask(LOG_UNIMP, "debug mode is not supported\n"); | ||
308 | + } | ||
309 | + | ||
310 | + return tdata1; | ||
311 | +} | ||
312 | + | ||
313 | +static inline void warn_always_zero_bit(target_ulong val, target_ulong mask, | ||
314 | + const char *msg) | ||
315 | +{ | ||
316 | + if (val & mask) { | ||
317 | + qemu_log_mask(LOG_UNIMP, "%s bit is always zero\n", msg); | ||
318 | + } | ||
319 | +} | ||
320 | + | ||
321 | +static uint32_t type2_breakpoint_size(CPURISCVState *env, target_ulong ctrl) | ||
322 | +{ | ||
323 | + uint32_t size, sizelo, sizehi = 0; | ||
324 | + | ||
325 | + if (riscv_cpu_mxl(env) == MXL_RV64) { | ||
326 | + sizehi = extract32(ctrl, 21, 2); | ||
327 | + } | ||
328 | + sizelo = extract32(ctrl, 16, 2); | ||
329 | + size = (sizehi << 2) | sizelo; | ||
330 | + | ||
331 | + return size; | ||
332 | +} | ||
333 | + | ||
334 | +static inline bool type2_breakpoint_enabled(target_ulong ctrl) | ||
335 | +{ | ||
336 | + bool mode = !!(ctrl & (TYPE2_U | TYPE2_S | TYPE2_M)); | ||
337 | + bool rwx = !!(ctrl & (TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); | ||
338 | + | ||
339 | + return mode && rwx; | ||
340 | +} | ||
341 | + | ||
342 | +static target_ulong type2_mcontrol_validate(CPURISCVState *env, | ||
343 | + target_ulong ctrl) | ||
344 | +{ | ||
345 | + target_ulong val; | ||
346 | + uint32_t size; | ||
347 | + | ||
348 | + /* validate the generic part first */ | ||
349 | + val = tdata1_validate(env, ctrl, TRIGGER_TYPE_AD_MATCH); | ||
350 | + | ||
351 | + /* validate unimplemented (always zero) bits */ | ||
352 | + warn_always_zero_bit(ctrl, TYPE2_MATCH, "match"); | ||
353 | + warn_always_zero_bit(ctrl, TYPE2_CHAIN, "chain"); | ||
354 | + warn_always_zero_bit(ctrl, TYPE2_ACTION, "action"); | ||
355 | + warn_always_zero_bit(ctrl, TYPE2_TIMING, "timing"); | ||
356 | + warn_always_zero_bit(ctrl, TYPE2_SELECT, "select"); | ||
357 | + warn_always_zero_bit(ctrl, TYPE2_HIT, "hit"); | ||
358 | + | ||
359 | + /* validate size encoding */ | ||
360 | + size = type2_breakpoint_size(env, ctrl); | ||
361 | + if (access_size[size] == -1) { | ||
362 | + qemu_log_mask(LOG_UNIMP, "access size %d is not supported, using SIZE_ANY\n", | ||
363 | + size); | ||
364 | + } else { | ||
365 | + val |= (ctrl & TYPE2_SIZELO); | ||
366 | + if (riscv_cpu_mxl(env) == MXL_RV64) { | ||
367 | + val |= (ctrl & TYPE2_SIZEHI); | ||
368 | + } | ||
369 | + } | ||
370 | + | ||
371 | + /* keep the mode and attribute bits */ | ||
372 | + val |= (ctrl & (TYPE2_U | TYPE2_S | TYPE2_M | | ||
373 | + TYPE2_LOAD | TYPE2_STORE | TYPE2_EXEC)); | ||
374 | + | ||
375 | + return val; | ||
376 | +} | ||
377 | + | ||
378 | +static void type2_breakpoint_insert(CPURISCVState *env, target_ulong index) | ||
379 | +{ | ||
380 | + target_ulong ctrl = env->type2_trig[index].mcontrol; | ||
381 | + target_ulong addr = env->type2_trig[index].maddress; | ||
382 | + bool enabled = type2_breakpoint_enabled(ctrl); | ||
383 | + CPUState *cs = env_cpu(env); | ||
384 | + int flags = BP_CPU | BP_STOP_BEFORE_ACCESS; | ||
385 | + uint32_t size; | ||
386 | + | ||
387 | + if (!enabled) { | ||
388 | + return; | ||
389 | + } | ||
390 | + | ||
391 | + if (ctrl & TYPE2_EXEC) { | ||
392 | + cpu_breakpoint_insert(cs, addr, flags, &env->type2_trig[index].bp); | ||
393 | + } | ||
394 | + | ||
395 | + if (ctrl & TYPE2_LOAD) { | ||
396 | + flags |= BP_MEM_READ; | ||
397 | + } | ||
398 | + if (ctrl & TYPE2_STORE) { | ||
399 | + flags |= BP_MEM_WRITE; | ||
400 | + } | ||
401 | + | ||
402 | + if (flags & BP_MEM_ACCESS) { | ||
403 | + size = type2_breakpoint_size(env, ctrl); | ||
404 | + if (size != 0) { | ||
405 | + cpu_watchpoint_insert(cs, addr, size, flags, | ||
406 | + &env->type2_trig[index].wp); | ||
407 | + } else { | ||
408 | + cpu_watchpoint_insert(cs, addr, 8, flags, | ||
409 | + &env->type2_trig[index].wp); | ||
410 | + } | ||
411 | + } | ||
412 | +} | ||
413 | + | ||
414 | +static void type2_breakpoint_remove(CPURISCVState *env, target_ulong index) | ||
415 | +{ | ||
416 | + CPUState *cs = env_cpu(env); | ||
417 | + | ||
418 | + if (env->type2_trig[index].bp) { | ||
419 | + cpu_breakpoint_remove_by_ref(cs, env->type2_trig[index].bp); | ||
420 | + env->type2_trig[index].bp = NULL; | ||
421 | + } | ||
422 | + | ||
423 | + if (env->type2_trig[index].wp) { | ||
424 | + cpu_watchpoint_remove_by_ref(cs, env->type2_trig[index].wp); | ||
425 | + env->type2_trig[index].wp = NULL; | ||
426 | + } | ||
427 | +} | ||
428 | + | ||
429 | +static target_ulong type2_reg_read(CPURISCVState *env, | ||
430 | + target_ulong trigger_index, int tdata_index) | ||
431 | +{ | ||
432 | + uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0; | ||
433 | + target_ulong tdata; | ||
434 | + | ||
435 | + switch (tdata_index) { | ||
436 | + case TDATA1: | ||
437 | + tdata = env->type2_trig[index].mcontrol; | ||
438 | + break; | ||
439 | + case TDATA2: | ||
440 | + tdata = env->type2_trig[index].maddress; | ||
441 | + break; | ||
442 | + default: | ||
443 | + g_assert_not_reached(); | ||
444 | + } | ||
445 | + | ||
446 | + return tdata; | ||
447 | +} | ||
448 | + | ||
449 | +static void type2_reg_write(CPURISCVState *env, target_ulong trigger_index, | ||
450 | + int tdata_index, target_ulong val) | ||
451 | +{ | ||
452 | + uint32_t index = trigger_index - TRIGGER_TYPE2_IDX_0; | ||
453 | + target_ulong new_val; | ||
454 | + | ||
455 | + switch (tdata_index) { | ||
456 | + case TDATA1: | ||
457 | + new_val = type2_mcontrol_validate(env, val); | ||
458 | + if (new_val != env->type2_trig[index].mcontrol) { | ||
459 | + env->type2_trig[index].mcontrol = new_val; | ||
460 | + type2_breakpoint_remove(env, index); | ||
461 | + type2_breakpoint_insert(env, index); | ||
462 | + } | ||
463 | + break; | ||
464 | + case TDATA2: | ||
465 | + if (val != env->type2_trig[index].maddress) { | ||
466 | + env->type2_trig[index].maddress = val; | ||
467 | + type2_breakpoint_remove(env, index); | ||
468 | + type2_breakpoint_insert(env, index); | ||
469 | + } | ||
470 | + break; | ||
471 | + default: | ||
472 | + g_assert_not_reached(); | ||
473 | + } | ||
474 | + | ||
475 | + return; | ||
476 | +} | ||
477 | + | ||
478 | +typedef target_ulong (*tdata_read_func)(CPURISCVState *env, | ||
479 | + target_ulong trigger_index, | ||
480 | + int tdata_index); | ||
481 | + | ||
482 | +static tdata_read_func trigger_read_funcs[TRIGGER_NUM] = { | ||
483 | + [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_read, | ||
484 | +}; | ||
485 | + | ||
486 | +typedef void (*tdata_write_func)(CPURISCVState *env, | ||
487 | + target_ulong trigger_index, | ||
488 | + int tdata_index, | ||
489 | + target_ulong val); | ||
490 | + | ||
491 | +static tdata_write_func trigger_write_funcs[TRIGGER_NUM] = { | ||
492 | + [TRIGGER_TYPE2_IDX_0 ... TRIGGER_TYPE2_IDX_1] = type2_reg_write, | ||
493 | +}; | ||
494 | + | ||
495 | +target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index) | ||
496 | +{ | ||
497 | + tdata_read_func read_func = trigger_read_funcs[env->trigger_cur]; | ||
498 | + | ||
499 | + return read_func(env, env->trigger_cur, tdata_index); | ||
500 | +} | ||
501 | + | ||
502 | +void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val) | ||
503 | +{ | ||
504 | + tdata_write_func write_func = trigger_write_funcs[env->trigger_cur]; | ||
505 | + | ||
506 | + return write_func(env, env->trigger_cur, tdata_index, val); | ||
276 | +} | 507 | +} |
277 | diff --git a/target/riscv/meson.build b/target/riscv/meson.build | 508 | diff --git a/target/riscv/meson.build b/target/riscv/meson.build |
278 | index XXXXXXX..XXXXXXX 100644 | 509 | index XXXXXXX..XXXXXXX 100644 |
279 | --- a/target/riscv/meson.build | 510 | --- a/target/riscv/meson.build |
280 | +++ b/target/riscv/meson.build | 511 | +++ b/target/riscv/meson.build |
281 | @@ -XXX,XX +XXX,XX @@ riscv_ss.add(files( | 512 | @@ -XXX,XX +XXX,XX @@ riscv_softmmu_ss = ss.source_set() |
282 | 'vector_helper.c', | 513 | riscv_softmmu_ss.add(files( |
283 | 'bitmanip_helper.c', | 514 | 'arch_dump.c', |
284 | 'translate.c', | 515 | 'pmp.c', |
285 | - 'm128_helper.c' | 516 | + 'debug.c', |
286 | + 'm128_helper.c', | 517 | 'monitor.c', |
287 | + 'crypto_helper.c' | 518 | 'machine.c' |
288 | )) | 519 | )) |
289 | riscv_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'), if_false: files('kvm-stub.c')) | ||
290 | |||
291 | -- | 520 | -- |
292 | 2.35.1 | 521 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Weiwei Li <liweiwei@iscas.ac.cn> |
---|---|---|---|
2 | 2 | ||
3 | - add sha256sig0, sha256sig1, sha256sum0 and sha256sum1 instructions | 3 | for some cases, scale is always equal or less than 0, since lmul is not larger than 3 |
4 | 4 | ||
5 | Co-authored-by: Zewen Ye <lustrew@foxmail.com> | ||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 7 | Reviewed-by: Frank Chang <frank.chang@sifive.com> |
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-Id: <20220423023510.30794-9-liweiwei@iscas.ac.cn> | 9 | Message-Id: <20220325085902.29500-1-liweiwei@iscas.ac.cn> |
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 11 | --- |
13 | target/riscv/insn32.decode | 5 +++ | 12 | target/riscv/insn_trans/trans_rvv.c.inc | 8 +++----- |
14 | target/riscv/insn_trans/trans_rvk.c.inc | 55 +++++++++++++++++++++++++ | 13 | 1 file changed, 3 insertions(+), 5 deletions(-) |
15 | 2 files changed, 60 insertions(+) | ||
16 | 14 | ||
17 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 15 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc |
18 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/insn32.decode | 17 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
20 | +++ b/target/riscv/insn32.decode | 18 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
21 | @@ -XXX,XX +XXX,XX @@ aes64esm 00 11011 ..... ..... 000 ..... 0110011 @r | 19 | @@ -XXX,XX +XXX,XX @@ GEN_LDST_WHOLE_TRANS(vs8r_v, 8, true) |
22 | # *** RV64 Zkne/zknd Standard Extension *** | 20 | static inline uint32_t MAXSZ(DisasContext *s) |
23 | aes64ks2 01 11111 ..... ..... 000 ..... 0110011 @r | ||
24 | aes64ks1i 00 11000 1.... ..... 001 ..... 0010011 @i_aes | ||
25 | +# *** RV32 Zknh Standard Extension *** | ||
26 | +sha256sig0 00 01000 00010 ..... 001 ..... 0010011 @r2 | ||
27 | +sha256sig1 00 01000 00011 ..... 001 ..... 0010011 @r2 | ||
28 | +sha256sum0 00 01000 00000 ..... 001 ..... 0010011 @r2 | ||
29 | +sha256sum1 00 01000 00001 ..... 001 ..... 0010011 @r2 | ||
30 | diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc | ||
31 | index XXXXXXX..XXXXXXX 100644 | ||
32 | --- a/target/riscv/insn_trans/trans_rvk.c.inc | ||
33 | +++ b/target/riscv/insn_trans/trans_rvk.c.inc | ||
34 | @@ -XXX,XX +XXX,XX @@ | ||
35 | } \ | ||
36 | } while (0) | ||
37 | |||
38 | +#define REQUIRE_ZKNH(ctx) do { \ | ||
39 | + if (!ctx->cfg_ptr->ext_zknh) { \ | ||
40 | + return false; \ | ||
41 | + } \ | ||
42 | +} while (0) | ||
43 | + | ||
44 | static bool gen_aes32_sm4(DisasContext *ctx, arg_k_aes *a, | ||
45 | void (*func)(TCGv, TCGv, TCGv, TCGv)) | ||
46 | { | 21 | { |
47 | @@ -XXX,XX +XXX,XX @@ static bool trans_aes64im(DisasContext *ctx, arg_aes64im *a) | 22 | int scale = s->lmul - 3; |
48 | REQUIRE_ZKND(ctx); | 23 | - return scale < 0 ? s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale; |
49 | return gen_unary(ctx, a, EXT_NONE, gen_helper_aes64im); | 24 | + return s->cfg_ptr->vlen >> -scale; |
50 | } | 25 | } |
51 | + | 26 | |
52 | +static bool gen_sha256(DisasContext *ctx, arg_r2 *a, DisasExtend ext, | 27 | static bool opivv_check(DisasContext *s, arg_rmrr *a) |
53 | + void (*func)(TCGv_i32, TCGv_i32, int32_t), | 28 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a) |
54 | + int32_t num1, int32_t num2, int32_t num3) | 29 | |
55 | +{ | 30 | if (a->vm && s->vl_eq_vlmax) { |
56 | + TCGv dest = dest_gpr(ctx, a->rd); | 31 | int scale = s->lmul - (s->sew + 3); |
57 | + TCGv src1 = get_gpr(ctx, a->rs1, ext); | 32 | - int vlmax = scale < 0 ? |
58 | + TCGv_i32 t0 = tcg_temp_new_i32(); | 33 | - s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale; |
59 | + TCGv_i32 t1 = tcg_temp_new_i32(); | 34 | + int vlmax = s->cfg_ptr->vlen >> -scale; |
60 | + TCGv_i32 t2 = tcg_temp_new_i32(); | 35 | TCGv_i64 dest = tcg_temp_new_i64(); |
61 | + | 36 | |
62 | + tcg_gen_trunc_tl_i32(t0, src1); | 37 | if (a->rs1 == 0) { |
63 | + tcg_gen_rotri_i32(t1, t0, num1); | 38 | @@ -XXX,XX +XXX,XX @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a) |
64 | + tcg_gen_rotri_i32(t2, t0, num2); | 39 | |
65 | + tcg_gen_xor_i32(t1, t1, t2); | 40 | if (a->vm && s->vl_eq_vlmax) { |
66 | + func(t2, t0, num3); | 41 | int scale = s->lmul - (s->sew + 3); |
67 | + tcg_gen_xor_i32(t1, t1, t2); | 42 | - int vlmax = scale < 0 ? |
68 | + tcg_gen_ext_i32_tl(dest, t1); | 43 | - s->cfg_ptr->vlen >> -scale : s->cfg_ptr->vlen << scale; |
69 | + | 44 | + int vlmax = s->cfg_ptr->vlen >> -scale; |
70 | + gen_set_gpr(ctx, a->rd, dest); | 45 | if (a->rs1 >= vlmax) { |
71 | + tcg_temp_free_i32(t0); | 46 | tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd), |
72 | + tcg_temp_free_i32(t1); | 47 | MAXSZ(s), MAXSZ(s), 0); |
73 | + tcg_temp_free_i32(t2); | ||
74 | + return true; | ||
75 | +} | ||
76 | + | ||
77 | +static bool trans_sha256sig0(DisasContext *ctx, arg_sha256sig0 *a) | ||
78 | +{ | ||
79 | + REQUIRE_ZKNH(ctx); | ||
80 | + return gen_sha256(ctx, a, EXT_NONE, tcg_gen_shri_i32, 7, 18, 3); | ||
81 | +} | ||
82 | + | ||
83 | +static bool trans_sha256sig1(DisasContext *ctx, arg_sha256sig1 *a) | ||
84 | +{ | ||
85 | + REQUIRE_ZKNH(ctx); | ||
86 | + return gen_sha256(ctx, a, EXT_NONE, tcg_gen_shri_i32, 17, 19, 10); | ||
87 | +} | ||
88 | + | ||
89 | +static bool trans_sha256sum0(DisasContext *ctx, arg_sha256sum0 *a) | ||
90 | +{ | ||
91 | + REQUIRE_ZKNH(ctx); | ||
92 | + return gen_sha256(ctx, a, EXT_NONE, tcg_gen_rotri_i32, 2, 13, 22); | ||
93 | +} | ||
94 | + | ||
95 | +static bool trans_sha256sum1(DisasContext *ctx, arg_sha256sum1 *a) | ||
96 | +{ | ||
97 | + REQUIRE_ZKNH(ctx); | ||
98 | + return gen_sha256(ctx, a, EXT_NONE, tcg_gen_rotri_i32, 6, 11, 25); | ||
99 | +} | ||
100 | -- | 48 | -- |
101 | 2.35.1 | 49 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Weiwei Li <liweiwei@iscas.ac.cn> |
---|---|---|---|
2 | 2 | ||
3 | - add xperm4 and xperm8 instructions | 3 | LEN is not used for GEN_VEXT_VMV_WHOLE macro, so vmv<nr>r.v can share |
4 | the same helper | ||
4 | 5 | ||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> |
7 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 8 | Reviewed-by: Frank Chang <frank.chang@sifive.com> |
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Message-Id: <20220423023510.30794-5-liweiwei@iscas.ac.cn> | 10 | Message-Id: <20220325085902.29500-2-liweiwei@iscas.ac.cn> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 12 | --- |
12 | target/riscv/helper.h | 2 ++ | 13 | target/riscv/helper.h | 5 +---- |
13 | target/riscv/insn32.decode | 4 ++++ | 14 | target/riscv/vector_helper.c | 29 ++++++++++--------------- |
14 | target/riscv/bitmanip_helper.c | 27 +++++++++++++++++++++++++ | 15 | target/riscv/insn_trans/trans_rvv.c.inc | 17 +++++---------- |
15 | target/riscv/insn_trans/trans_rvb.c.inc | 18 +++++++++++++++++ | 16 | 3 files changed, 18 insertions(+), 33 deletions(-) |
16 | 4 files changed, 51 insertions(+) | ||
17 | 17 | ||
18 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | 18 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h |
19 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/target/riscv/helper.h | 20 | --- a/target/riscv/helper.h |
21 | +++ b/target/riscv/helper.h | 21 | +++ b/target/riscv/helper.h |
22 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 22 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_6(vcompress_vm_h, void, ptr, ptr, ptr, ptr, env, i32) |
23 | DEF_HELPER_FLAGS_1(brev8, TCG_CALL_NO_RWG_SE, tl, tl) | 23 | DEF_HELPER_6(vcompress_vm_w, void, ptr, ptr, ptr, ptr, env, i32) |
24 | DEF_HELPER_FLAGS_1(unzip, TCG_CALL_NO_RWG_SE, tl, tl) | 24 | DEF_HELPER_6(vcompress_vm_d, void, ptr, ptr, ptr, ptr, env, i32) |
25 | DEF_HELPER_FLAGS_1(zip, TCG_CALL_NO_RWG_SE, tl, tl) | 25 | |
26 | +DEF_HELPER_FLAGS_2(xperm4, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 26 | -DEF_HELPER_4(vmv1r_v, void, ptr, ptr, env, i32) |
27 | +DEF_HELPER_FLAGS_2(xperm8, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 27 | -DEF_HELPER_4(vmv2r_v, void, ptr, ptr, env, i32) |
28 | 28 | -DEF_HELPER_4(vmv4r_v, void, ptr, ptr, env, i32) | |
29 | /* Floating Point - Half Precision */ | 29 | -DEF_HELPER_4(vmv8r_v, void, ptr, ptr, env, i32) |
30 | DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | 30 | +DEF_HELPER_4(vmvr_v, void, ptr, ptr, env, i32) |
31 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 31 | |
32 | DEF_HELPER_5(vzext_vf2_h, void, ptr, ptr, ptr, env, i32) | ||
33 | DEF_HELPER_5(vzext_vf2_w, void, ptr, ptr, ptr, env, i32) | ||
34 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c | ||
32 | index XXXXXXX..XXXXXXX 100644 | 35 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/target/riscv/insn32.decode | 36 | --- a/target/riscv/vector_helper.c |
34 | +++ b/target/riscv/insn32.decode | 37 | +++ b/target/riscv/vector_helper.c |
35 | @@ -XXX,XX +XXX,XX @@ clmulh 0000101 .......... 011 ..... 0110011 @r | 38 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VCOMPRESS_VM(vcompress_vm_w, uint32_t, H4) |
36 | # *** RV32 extra Zbc Standard Extension *** | 39 | GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8) |
37 | clmulr 0000101 .......... 010 ..... 0110011 @r | 40 | |
38 | 41 | /* Vector Whole Register Move */ | |
39 | +# *** RV32 Zbkx Standard Extension *** | 42 | -#define GEN_VEXT_VMV_WHOLE(NAME, LEN) \ |
40 | +xperm4 0010100 .......... 010 ..... 0110011 @r | 43 | -void HELPER(NAME)(void *vd, void *vs2, CPURISCVState *env, \ |
41 | +xperm8 0010100 .......... 100 ..... 0110011 @r | 44 | - uint32_t desc) \ |
45 | -{ \ | ||
46 | - /* EEW = 8 */ \ | ||
47 | - uint32_t maxsz = simd_maxsz(desc); \ | ||
48 | - uint32_t i = env->vstart; \ | ||
49 | - \ | ||
50 | - memcpy((uint8_t *)vd + H1(i), \ | ||
51 | - (uint8_t *)vs2 + H1(i), \ | ||
52 | - maxsz - env->vstart); \ | ||
53 | - \ | ||
54 | - env->vstart = 0; \ | ||
55 | -} | ||
56 | +void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc) | ||
57 | +{ | ||
58 | + /* EEW = 8 */ | ||
59 | + uint32_t maxsz = simd_maxsz(desc); | ||
60 | + uint32_t i = env->vstart; | ||
42 | + | 61 | + |
43 | # *** RV32 Zbs Standard Extension *** | 62 | + memcpy((uint8_t *)vd + H1(i), |
44 | bclr 0100100 .......... 001 ..... 0110011 @r | 63 | + (uint8_t *)vs2 + H1(i), |
45 | bclri 01001. ........... 001 ..... 0010011 @sh | 64 | + maxsz - env->vstart); |
46 | diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c | 65 | |
66 | -GEN_VEXT_VMV_WHOLE(vmv1r_v, 1) | ||
67 | -GEN_VEXT_VMV_WHOLE(vmv2r_v, 2) | ||
68 | -GEN_VEXT_VMV_WHOLE(vmv4r_v, 4) | ||
69 | -GEN_VEXT_VMV_WHOLE(vmv8r_v, 8) | ||
70 | + env->vstart = 0; | ||
71 | +} | ||
72 | |||
73 | /* Vector Integer Extension */ | ||
74 | #define GEN_VEXT_INT_EXT(NAME, ETYPE, DTYPE, HD, HS1) \ | ||
75 | diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc | ||
47 | index XXXXXXX..XXXXXXX 100644 | 76 | index XXXXXXX..XXXXXXX 100644 |
48 | --- a/target/riscv/bitmanip_helper.c | 77 | --- a/target/riscv/insn_trans/trans_rvv.c.inc |
49 | +++ b/target/riscv/bitmanip_helper.c | 78 | +++ b/target/riscv/insn_trans/trans_rvv.c.inc |
50 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(zip)(target_ulong rs1) | 79 | @@ -XXX,XX +XXX,XX @@ static bool trans_vcompress_vm(DisasContext *s, arg_r *a) |
51 | x = do_shuf_stage(x, shuf_masks[0], shuf_masks[0] >> 1, 1); | 80 | * Whole Vector Register Move Instructions ignore vtype and vl setting. |
52 | return x; | 81 | * Thus, we don't need to check vill bit. (Section 16.6) |
82 | */ | ||
83 | -#define GEN_VMV_WHOLE_TRANS(NAME, LEN, SEQ) \ | ||
84 | +#define GEN_VMV_WHOLE_TRANS(NAME, LEN) \ | ||
85 | static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
86 | { \ | ||
87 | if (require_rvv(s) && \ | ||
88 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
89 | } else { \ | ||
90 | TCGLabel *over = gen_new_label(); \ | ||
91 | tcg_gen_brcondi_tl(TCG_COND_GEU, cpu_vstart, maxsz, over); \ | ||
92 | - \ | ||
93 | - static gen_helper_gvec_2_ptr * const fns[4] = { \ | ||
94 | - gen_helper_vmv1r_v, gen_helper_vmv2r_v, \ | ||
95 | - gen_helper_vmv4r_v, gen_helper_vmv8r_v, \ | ||
96 | - }; \ | ||
97 | tcg_gen_gvec_2_ptr(vreg_ofs(s, a->rd), vreg_ofs(s, a->rs2), \ | ||
98 | - cpu_env, maxsz, maxsz, 0, fns[SEQ]); \ | ||
99 | + cpu_env, maxsz, maxsz, 0, gen_helper_vmvr_v); \ | ||
100 | mark_vs_dirty(s); \ | ||
101 | gen_set_label(over); \ | ||
102 | } \ | ||
103 | @@ -XXX,XX +XXX,XX @@ static bool trans_##NAME(DisasContext *s, arg_##NAME * a) \ | ||
104 | return false; \ | ||
53 | } | 105 | } |
54 | + | 106 | |
55 | +static inline target_ulong do_xperm(target_ulong rs1, target_ulong rs2, | 107 | -GEN_VMV_WHOLE_TRANS(vmv1r_v, 1, 0) |
56 | + uint32_t sz_log2) | 108 | -GEN_VMV_WHOLE_TRANS(vmv2r_v, 2, 1) |
57 | +{ | 109 | -GEN_VMV_WHOLE_TRANS(vmv4r_v, 4, 2) |
58 | + target_ulong r = 0; | 110 | -GEN_VMV_WHOLE_TRANS(vmv8r_v, 8, 3) |
59 | + target_ulong sz = 1LL << sz_log2; | 111 | +GEN_VMV_WHOLE_TRANS(vmv1r_v, 1) |
60 | + target_ulong mask = (1LL << sz) - 1; | 112 | +GEN_VMV_WHOLE_TRANS(vmv2r_v, 2) |
61 | + target_ulong pos; | 113 | +GEN_VMV_WHOLE_TRANS(vmv4r_v, 4) |
62 | + | 114 | +GEN_VMV_WHOLE_TRANS(vmv8r_v, 8) |
63 | + for (int i = 0; i < TARGET_LONG_BITS; i += sz) { | 115 | |
64 | + pos = ((rs2 >> i) & mask) << sz_log2; | 116 | static bool int_ext_check(DisasContext *s, arg_rmr *a, uint8_t div) |
65 | + if (pos < sizeof(target_ulong) * 8) { | ||
66 | + r |= ((rs1 >> pos) & mask) << i; | ||
67 | + } | ||
68 | + } | ||
69 | + return r; | ||
70 | +} | ||
71 | + | ||
72 | +target_ulong HELPER(xperm4)(target_ulong rs1, target_ulong rs2) | ||
73 | +{ | ||
74 | + return do_xperm(rs1, rs2, 2); | ||
75 | +} | ||
76 | + | ||
77 | +target_ulong HELPER(xperm8)(target_ulong rs1, target_ulong rs2) | ||
78 | +{ | ||
79 | + return do_xperm(rs1, rs2, 3); | ||
80 | +} | ||
81 | diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc | ||
82 | index XXXXXXX..XXXXXXX 100644 | ||
83 | --- a/target/riscv/insn_trans/trans_rvb.c.inc | ||
84 | +++ b/target/riscv/insn_trans/trans_rvb.c.inc | ||
85 | @@ -XXX,XX +XXX,XX @@ | ||
86 | } \ | ||
87 | } while (0) | ||
88 | |||
89 | +#define REQUIRE_ZBKX(ctx) do { \ | ||
90 | + if (!ctx->cfg_ptr->ext_zbkx) { \ | ||
91 | + return false; \ | ||
92 | + } \ | ||
93 | +} while (0) | ||
94 | + | ||
95 | static void gen_clz(TCGv ret, TCGv arg1) | ||
96 | { | 117 | { |
97 | tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS); | ||
98 | @@ -XXX,XX +XXX,XX @@ static bool trans_zip(DisasContext *ctx, arg_zip *a) | ||
99 | REQUIRE_ZBKB(ctx); | ||
100 | return gen_unary(ctx, a, EXT_NONE, gen_helper_zip); | ||
101 | } | ||
102 | + | ||
103 | +static bool trans_xperm4(DisasContext *ctx, arg_xperm4 *a) | ||
104 | +{ | ||
105 | + REQUIRE_ZBKX(ctx); | ||
106 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm4, NULL); | ||
107 | +} | ||
108 | + | ||
109 | +static bool trans_xperm8(DisasContext *ctx, arg_xperm8 *a) | ||
110 | +{ | ||
111 | + REQUIRE_ZBKX(ctx); | ||
112 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm8, NULL); | ||
113 | +} | ||
114 | -- | 118 | -- |
115 | 2.35.1 | 119 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Tsukasa OI <research_trasio@irq.a4lg.com> |
---|---|---|---|
2 | 2 | ||
3 | - add zbk* and zk* strings to isa_edata_arr | 3 | Some bits in RISC-V `misa' CSR should not be reflected in the ISA |
4 | string. For instance, `S' and `U' (represents existence of supervisor | ||
5 | and user mode, respectively) in `misa' CSR must not be copied since | ||
6 | neither `S' nor `U' are valid single-letter extensions. | ||
4 | 7 | ||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 8 | This commit also removes all reserved/dropped single-letter "extensions" |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 9 | from the list. |
7 | Tested-by: Jiatai He <jiatai2021@iscas.ac.cn> | 10 | |
11 | - "B": Not going to be a single-letter extension (misa.B is reserved). | ||
12 | - "J": Not going to be a single-letter extension (misa.J is reserved). | ||
13 | - "K": Not going to be a single-letter extension (misa.K is reserved). | ||
14 | - "L": Dropped. | ||
15 | - "N": Dropped. | ||
16 | - "T": Dropped. | ||
17 | |||
18 | It also clarifies that the variable `riscv_single_letter_exts' is a | ||
19 | single-letter extension order list. | ||
20 | |||
21 | Signed-off-by: Tsukasa OI <research_trasio@irq.a4lg.com> | ||
8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 22 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Message-Id: <20220426095204.24142-1-liweiwei@iscas.ac.cn> | 23 | Message-Id: <4a4c11213a161a7eedabe46abe58b351bb0e2ef2.1648473008.git.research_trasio@irq.a4lg.com> |
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 24 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 25 | --- |
12 | target/riscv/cpu.c | 13 +++++++++++++ | 26 | target/riscv/cpu.c | 10 +++++----- |
13 | 1 file changed, 13 insertions(+) | 27 | 1 file changed, 5 insertions(+), 5 deletions(-) |
14 | 28 | ||
15 | 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 |
16 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/target/riscv/cpu.c | 31 | --- a/target/riscv/cpu.c |
18 | +++ b/target/riscv/cpu.c | 32 | +++ b/target/riscv/cpu.c |
19 | @@ -XXX,XX +XXX,XX @@ static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) | 33 | @@ -XXX,XX +XXX,XX @@ |
20 | ISA_EDATA_ENTRY(zba, ext_zba), | 34 | |
21 | ISA_EDATA_ENTRY(zbb, ext_zbb), | 35 | /* RISC-V CPU definitions */ |
22 | ISA_EDATA_ENTRY(zbc, ext_zbc), | 36 | |
23 | + ISA_EDATA_ENTRY(zbkb, ext_zbkb), | 37 | -static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG"; |
24 | + ISA_EDATA_ENTRY(zbkc, ext_zbkc), | 38 | +static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; |
25 | + ISA_EDATA_ENTRY(zbkx, ext_zbkx), | 39 | |
26 | ISA_EDATA_ENTRY(zbs, ext_zbs), | 40 | const char * const riscv_int_regnames[] = { |
27 | + ISA_EDATA_ENTRY(zk, ext_zk), | 41 | "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1", |
28 | + ISA_EDATA_ENTRY(zkn, ext_zkn), | 42 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) |
29 | + ISA_EDATA_ENTRY(zknd, ext_zknd), | 43 | char *riscv_isa_string(RISCVCPU *cpu) |
30 | + ISA_EDATA_ENTRY(zkne, ext_zkne), | 44 | { |
31 | + ISA_EDATA_ENTRY(zknh, ext_zknh), | 45 | int i; |
32 | + ISA_EDATA_ENTRY(zkr, ext_zkr), | 46 | - const size_t maxlen = sizeof("rv128") + sizeof(riscv_exts) + 1; |
33 | + ISA_EDATA_ENTRY(zks, ext_zks), | 47 | + const size_t maxlen = sizeof("rv128") + sizeof(riscv_single_letter_exts); |
34 | + ISA_EDATA_ENTRY(zksed, ext_zksed), | 48 | char *isa_str = g_new(char, maxlen); |
35 | + ISA_EDATA_ENTRY(zksh, ext_zksh), | 49 | char *p = isa_str + snprintf(isa_str, maxlen, "rv%d", TARGET_LONG_BITS); |
36 | + ISA_EDATA_ENTRY(zkt, ext_zkt), | 50 | - for (i = 0; i < sizeof(riscv_exts); i++) { |
37 | ISA_EDATA_ENTRY(zve32f, ext_zve32f), | 51 | - if (cpu->env.misa_ext & RV(riscv_exts[i])) { |
38 | ISA_EDATA_ENTRY(zve64f, ext_zve64f), | 52 | - *p++ = qemu_tolower(riscv_exts[i]); |
39 | ISA_EDATA_ENTRY(svinval, ext_svinval), | 53 | + for (i = 0; i < sizeof(riscv_single_letter_exts) - 1; i++) { |
54 | + if (cpu->env.misa_ext & RV(riscv_single_letter_exts[i])) { | ||
55 | + *p++ = qemu_tolower(riscv_single_letter_exts[i]); | ||
56 | } | ||
57 | } | ||
58 | *p = '\0'; | ||
40 | -- | 59 | -- |
41 | 2.35.1 | 60 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Atish Patra <atishp@rivosinc.com> |
---|---|---|---|
2 | 2 | ||
3 | - add sha512sum0r, sha512sig0l, sha512sum1r, sha512sig1l, sha512sig0h and sha512sig1h instructions | 3 | The Linux kernel parses the ISA extensions from "riscv,isa" DT |
4 | property. It used to parse only the single letter base extensions | ||
5 | until now. A generic ISA extension parsing framework was proposed[1] | ||
6 | recently that can parse multi-letter ISA extensions as well. | ||
4 | 7 | ||
5 | Co-authored-by: Zewen Ye <lustrew@foxmail.com> | 8 | Generate the extended ISA string by appending the available ISA extensions |
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 9 | to the "riscv,isa" string if it is enabled so that kernel can process it. |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 10 | |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 11 | [1] https://lkml.org/lkml/2022/2/15/263 |
12 | |||
13 | Reviewed-by: Anup Patel <anup@brainfault.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-Id: <20220423023510.30794-10-liweiwei@iscas.ac.cn> | 15 | Reviewed-by: Frank Chang <frank.chang@sifive.com> |
16 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
17 | Tested-by: Bin Meng <bmeng.cn@gmail.com> | ||
18 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
19 | Suggested-by: Heiko Stubner <heiko@sntech.de> | ||
20 | Signed-off-by: Atish Patra <atishp@rivosinc.com> | ||
21 | Message-Id: <20220329195657.1725425-1-atishp@rivosinc.com> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 22 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 23 | --- |
13 | target/riscv/insn32.decode | 6 ++ | 24 | target/riscv/cpu.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++ |
14 | target/riscv/insn_trans/trans_rvk.c.inc | 100 ++++++++++++++++++++++++ | 25 | 1 file changed, 60 insertions(+) |
15 | 2 files changed, 106 insertions(+) | ||
16 | 26 | ||
17 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 27 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
18 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
19 | --- a/target/riscv/insn32.decode | 29 | --- a/target/riscv/cpu.c |
20 | +++ b/target/riscv/insn32.decode | 30 | +++ b/target/riscv/cpu.c |
21 | @@ -XXX,XX +XXX,XX @@ sha256sig0 00 01000 00010 ..... 001 ..... 0010011 @r2 | 31 | @@ -XXX,XX +XXX,XX @@ |
22 | sha256sig1 00 01000 00011 ..... 001 ..... 0010011 @r2 | 32 | |
23 | sha256sum0 00 01000 00000 ..... 001 ..... 0010011 @r2 | 33 | static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; |
24 | sha256sum1 00 01000 00001 ..... 001 ..... 0010011 @r2 | 34 | |
25 | +sha512sum0r 01 01000 ..... ..... 000 ..... 0110011 @r | 35 | +struct isa_ext_data { |
26 | +sha512sum1r 01 01001 ..... ..... 000 ..... 0110011 @r | 36 | + const char *name; |
27 | +sha512sig0l 01 01010 ..... ..... 000 ..... 0110011 @r | 37 | + bool enabled; |
28 | +sha512sig0h 01 01110 ..... ..... 000 ..... 0110011 @r | 38 | +}; |
29 | +sha512sig1l 01 01011 ..... ..... 000 ..... 0110011 @r | 39 | + |
30 | +sha512sig1h 01 01111 ..... ..... 000 ..... 0110011 @r | 40 | const char * const riscv_int_regnames[] = { |
31 | diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc | 41 | "x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1", |
32 | index XXXXXXX..XXXXXXX 100644 | 42 | "x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3", |
33 | --- a/target/riscv/insn_trans/trans_rvk.c.inc | 43 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_class_init(ObjectClass *c, void *data) |
34 | +++ b/target/riscv/insn_trans/trans_rvk.c.inc | 44 | device_class_set_props(dc, riscv_cpu_properties); |
35 | @@ -XXX,XX +XXX,XX @@ static bool trans_sha256sum1(DisasContext *ctx, arg_sha256sum1 *a) | ||
36 | REQUIRE_ZKNH(ctx); | ||
37 | return gen_sha256(ctx, a, EXT_NONE, tcg_gen_rotri_i32, 6, 11, 25); | ||
38 | } | 45 | } |
46 | |||
47 | +#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop} | ||
39 | + | 48 | + |
40 | +static bool gen_sha512_rv32(DisasContext *ctx, arg_r *a, DisasExtend ext, | 49 | +static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int max_str_len) |
41 | + void (*func1)(TCGv_i64, TCGv_i64, int64_t), | ||
42 | + void (*func2)(TCGv_i64, TCGv_i64, int64_t), | ||
43 | + int64_t num1, int64_t num2, int64_t num3) | ||
44 | +{ | 50 | +{ |
45 | + TCGv dest = dest_gpr(ctx, a->rd); | 51 | + char *old = *isa_str; |
46 | + TCGv src1 = get_gpr(ctx, a->rs1, ext); | 52 | + char *new = *isa_str; |
47 | + TCGv src2 = get_gpr(ctx, a->rs2, ext); | 53 | + int i; |
48 | + TCGv_i64 t0 = tcg_temp_new_i64(); | ||
49 | + TCGv_i64 t1 = tcg_temp_new_i64(); | ||
50 | + TCGv_i64 t2 = tcg_temp_new_i64(); | ||
51 | + | 54 | + |
52 | + tcg_gen_concat_tl_i64(t0, src1, src2); | 55 | + /** |
53 | + func1(t1, t0, num1); | 56 | + * Here are the ordering rules of extension naming defined by RISC-V |
54 | + func2(t2, t0, num2); | 57 | + * specification : |
55 | + tcg_gen_xor_i64(t1, t1, t2); | 58 | + * 1. All extensions should be separated from other multi-letter extensions |
56 | + tcg_gen_rotri_i64(t2, t0, num3); | 59 | + * by an underscore. |
57 | + tcg_gen_xor_i64(t1, t1, t2); | 60 | + * 2. The first letter following the 'Z' conventionally indicates the most |
58 | + tcg_gen_trunc_i64_tl(dest, t1); | 61 | + * closely related alphabetical extension category, IMAFDQLCBKJTPVH. |
62 | + * If multiple 'Z' extensions are named, they should be ordered first | ||
63 | + * by category, then alphabetically within a category. | ||
64 | + * 3. Standard supervisor-level extensions (starts with 'S') should be | ||
65 | + * listed after standard unprivileged extensions. If multiple | ||
66 | + * supervisor-level extensions are listed, they should be ordered | ||
67 | + * alphabetically. | ||
68 | + * 4. Non-standard extensions (starts with 'X') must be listed after all | ||
69 | + * standard extensions. They must be separated from other multi-letter | ||
70 | + * extensions by an underscore. | ||
71 | + */ | ||
72 | + struct isa_ext_data isa_edata_arr[] = { | ||
73 | + ISA_EDATA_ENTRY(zfh, ext_zfh), | ||
74 | + ISA_EDATA_ENTRY(zfhmin, ext_zfhmin), | ||
75 | + ISA_EDATA_ENTRY(zfinx, ext_zfinx), | ||
76 | + ISA_EDATA_ENTRY(zhinx, ext_zhinx), | ||
77 | + ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin), | ||
78 | + ISA_EDATA_ENTRY(zdinx, ext_zdinx), | ||
79 | + ISA_EDATA_ENTRY(zba, ext_zba), | ||
80 | + ISA_EDATA_ENTRY(zbb, ext_zbb), | ||
81 | + ISA_EDATA_ENTRY(zbc, ext_zbc), | ||
82 | + ISA_EDATA_ENTRY(zbs, ext_zbs), | ||
83 | + ISA_EDATA_ENTRY(zve32f, ext_zve32f), | ||
84 | + ISA_EDATA_ENTRY(zve64f, ext_zve64f), | ||
85 | + ISA_EDATA_ENTRY(svinval, ext_svinval), | ||
86 | + ISA_EDATA_ENTRY(svnapot, ext_svnapot), | ||
87 | + ISA_EDATA_ENTRY(svpbmt, ext_svpbmt), | ||
88 | + }; | ||
59 | + | 89 | + |
60 | + gen_set_gpr(ctx, a->rd, dest); | 90 | + for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) { |
61 | + tcg_temp_free_i64(t0); | 91 | + if (isa_edata_arr[i].enabled) { |
62 | + tcg_temp_free_i64(t1); | 92 | + new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL); |
63 | + tcg_temp_free_i64(t2); | 93 | + g_free(old); |
64 | + return true; | 94 | + old = new; |
95 | + } | ||
96 | + } | ||
97 | + | ||
98 | + *isa_str = new; | ||
65 | +} | 99 | +} |
66 | + | 100 | + |
67 | +static bool trans_sha512sum0r(DisasContext *ctx, arg_sha512sum0r *a) | 101 | char *riscv_isa_string(RISCVCPU *cpu) |
68 | +{ | 102 | { |
69 | + REQUIRE_32BIT(ctx); | 103 | int i; |
70 | + REQUIRE_ZKNH(ctx); | 104 | @@ -XXX,XX +XXX,XX @@ char *riscv_isa_string(RISCVCPU *cpu) |
71 | + return gen_sha512_rv32(ctx, a, EXT_NONE, tcg_gen_rotli_i64, | 105 | } |
72 | + tcg_gen_rotli_i64, 25, 30, 28); | 106 | } |
73 | +} | 107 | *p = '\0'; |
74 | + | 108 | + riscv_isa_string_ext(cpu, &isa_str, maxlen); |
75 | +static bool trans_sha512sum1r(DisasContext *ctx, arg_sha512sum1r *a) | 109 | return isa_str; |
76 | +{ | 110 | } |
77 | + REQUIRE_32BIT(ctx); | 111 | |
78 | + REQUIRE_ZKNH(ctx); | ||
79 | + return gen_sha512_rv32(ctx, a, EXT_NONE, tcg_gen_rotli_i64, | ||
80 | + tcg_gen_rotri_i64, 23, 14, 18); | ||
81 | +} | ||
82 | + | ||
83 | +static bool trans_sha512sig0l(DisasContext *ctx, arg_sha512sig0l *a) | ||
84 | +{ | ||
85 | + REQUIRE_32BIT(ctx); | ||
86 | + REQUIRE_ZKNH(ctx); | ||
87 | + return gen_sha512_rv32(ctx, a, EXT_NONE, tcg_gen_rotri_i64, | ||
88 | + tcg_gen_rotri_i64, 1, 7, 8); | ||
89 | +} | ||
90 | + | ||
91 | +static bool trans_sha512sig1l(DisasContext *ctx, arg_sha512sig1l *a) | ||
92 | +{ | ||
93 | + REQUIRE_32BIT(ctx); | ||
94 | + REQUIRE_ZKNH(ctx); | ||
95 | + return gen_sha512_rv32(ctx, a, EXT_NONE, tcg_gen_rotli_i64, | ||
96 | + tcg_gen_rotri_i64, 3, 6, 19); | ||
97 | +} | ||
98 | + | ||
99 | +static bool gen_sha512h_rv32(DisasContext *ctx, arg_r *a, DisasExtend ext, | ||
100 | + void (*func)(TCGv_i64, TCGv_i64, int64_t), | ||
101 | + int64_t num1, int64_t num2, int64_t num3) | ||
102 | +{ | ||
103 | + TCGv dest = dest_gpr(ctx, a->rd); | ||
104 | + TCGv src1 = get_gpr(ctx, a->rs1, ext); | ||
105 | + TCGv src2 = get_gpr(ctx, a->rs2, ext); | ||
106 | + TCGv_i64 t0 = tcg_temp_new_i64(); | ||
107 | + TCGv_i64 t1 = tcg_temp_new_i64(); | ||
108 | + TCGv_i64 t2 = tcg_temp_new_i64(); | ||
109 | + | ||
110 | + tcg_gen_concat_tl_i64(t0, src1, src2); | ||
111 | + func(t1, t0, num1); | ||
112 | + tcg_gen_ext32u_i64(t2, t0); | ||
113 | + tcg_gen_shri_i64(t2, t2, num2); | ||
114 | + tcg_gen_xor_i64(t1, t1, t2); | ||
115 | + tcg_gen_rotri_i64(t2, t0, num3); | ||
116 | + tcg_gen_xor_i64(t1, t1, t2); | ||
117 | + tcg_gen_trunc_i64_tl(dest, t1); | ||
118 | + | ||
119 | + gen_set_gpr(ctx, a->rd, dest); | ||
120 | + tcg_temp_free_i64(t0); | ||
121 | + tcg_temp_free_i64(t1); | ||
122 | + tcg_temp_free_i64(t2); | ||
123 | + return true; | ||
124 | +} | ||
125 | + | ||
126 | +static bool trans_sha512sig0h(DisasContext *ctx, arg_sha512sig0h *a) | ||
127 | +{ | ||
128 | + REQUIRE_32BIT(ctx); | ||
129 | + REQUIRE_ZKNH(ctx); | ||
130 | + return gen_sha512h_rv32(ctx, a, EXT_NONE, tcg_gen_rotri_i64, 1, 7, 8); | ||
131 | +} | ||
132 | + | ||
133 | +static bool trans_sha512sig1h(DisasContext *ctx, arg_sha512sig1h *a) | ||
134 | +{ | ||
135 | + REQUIRE_32BIT(ctx); | ||
136 | + REQUIRE_ZKNH(ctx); | ||
137 | + return gen_sha512h_rv32(ctx, a, EXT_NONE, tcg_gen_rotli_i64, 3, 6, 19); | ||
138 | +} | ||
139 | -- | 112 | -- |
140 | 2.35.1 | 113 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Weiwei Li <liweiwei@iscas.ac.cn> |
---|---|---|---|
2 | 2 | ||
3 | - reuse partial instructions of zbb extension, update extension check for them | 3 | The spec for vmv<nf>r.v says: 'the instructions operate as if EEW=SEW, |
4 | - add brev8, pack, packh, packw, unzip, zip instructions | 4 | EMUL = NREG, effective length evl= EMUL * VLEN/SEW.' |
5 | |||
6 | So the start byte for vstart != 0 should take sew into account | ||
5 | 7 | ||
6 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 8 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> |
7 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 9 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> |
8 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Acked-by: Alistair Francis <alistair.francis@wdc.com> |
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 11 | Message-Id: <20220330021316.18223-1-liweiwei@iscas.ac.cn> |
10 | Message-Id: <20220423023510.30794-3-liweiwei@iscas.ac.cn> | ||
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 13 | --- |
13 | target/riscv/helper.h | 3 + | 14 | target/riscv/vector_helper.c | 8 +++++--- |
14 | target/riscv/insn32.decode | 45 +++++++----- | 15 | 1 file changed, 5 insertions(+), 3 deletions(-) |
15 | target/riscv/bitmanip_helper.c | 53 ++++++++++++++ | ||
16 | target/riscv/translate.c | 7 ++ | ||
17 | target/riscv/insn_trans/trans_rvb.c.inc | 94 +++++++++++++++++++++---- | ||
18 | 5 files changed, 174 insertions(+), 28 deletions(-) | ||
19 | 16 | ||
20 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | 17 | diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c |
21 | index XXXXXXX..XXXXXXX 100644 | 18 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/target/riscv/helper.h | 19 | --- a/target/riscv/vector_helper.c |
23 | +++ b/target/riscv/helper.h | 20 | +++ b/target/riscv/vector_helper.c |
24 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64) | 21 | @@ -XXX,XX +XXX,XX @@ GEN_VEXT_VCOMPRESS_VM(vcompress_vm_d, uint64_t, H8) |
25 | /* Bitmanip */ | 22 | /* Vector Whole Register Move */ |
26 | DEF_HELPER_FLAGS_2(clmul, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 23 | void HELPER(vmvr_v)(void *vd, void *vs2, CPURISCVState *env, uint32_t desc) |
27 | DEF_HELPER_FLAGS_2(clmulr, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 24 | { |
28 | +DEF_HELPER_FLAGS_1(brev8, TCG_CALL_NO_RWG_SE, tl, tl) | 25 | - /* EEW = 8 */ |
29 | +DEF_HELPER_FLAGS_1(unzip, TCG_CALL_NO_RWG_SE, tl, tl) | 26 | + /* EEW = SEW */ |
30 | +DEF_HELPER_FLAGS_1(zip, TCG_CALL_NO_RWG_SE, tl, tl) | 27 | uint32_t maxsz = simd_maxsz(desc); |
31 | 28 | - uint32_t i = env->vstart; | |
32 | /* Floating Point - Half Precision */ | 29 | + uint32_t sewb = 1 << FIELD_EX64(env->vtype, VTYPE, VSEW); |
33 | DEF_HELPER_FLAGS_3(fadd_h, TCG_CALL_NO_RWG, i64, env, i64, i64) | 30 | + uint32_t startb = env->vstart * sewb; |
34 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 31 | + uint32_t i = startb; |
35 | index XXXXXXX..XXXXXXX 100644 | 32 | |
36 | --- a/target/riscv/insn32.decode | 33 | memcpy((uint8_t *)vd + H1(i), |
37 | +++ b/target/riscv/insn32.decode | 34 | (uint8_t *)vs2 + H1(i), |
38 | @@ -XXX,XX +XXX,XX @@ sh2add_uw 0010000 .......... 100 ..... 0111011 @r | 35 | - maxsz - env->vstart); |
39 | sh3add_uw 0010000 .......... 110 ..... 0111011 @r | 36 | + maxsz - startb); |
40 | slli_uw 00001 ............ 001 ..... 0011011 @sh | 37 | |
41 | 38 | env->vstart = 0; | |
42 | -# *** RV32 Zbb Standard Extension *** | ||
43 | +# *** RV32 Zbb/Zbkb Standard Extension *** | ||
44 | andn 0100000 .......... 111 ..... 0110011 @r | ||
45 | +rol 0110000 .......... 001 ..... 0110011 @r | ||
46 | +ror 0110000 .......... 101 ..... 0110011 @r | ||
47 | +rori 01100 ............ 101 ..... 0010011 @sh | ||
48 | +# The encoding for rev8 differs between RV32 and RV64. | ||
49 | +# rev8_32 denotes the RV32 variant. | ||
50 | +rev8_32 011010 011000 ..... 101 ..... 0010011 @r2 | ||
51 | +# The encoding for zext.h differs between RV32 and RV64. | ||
52 | +# zext_h_32 denotes the RV32 variant. | ||
53 | +{ | ||
54 | + zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 | ||
55 | + pack 0000100 ..... ..... 100 ..... 0110011 @r | ||
56 | +} | ||
57 | +xnor 0100000 .......... 100 ..... 0110011 @r | ||
58 | +# *** RV32 extra Zbb Standard Extension *** | ||
59 | clz 011000 000000 ..... 001 ..... 0010011 @r2 | ||
60 | cpop 011000 000010 ..... 001 ..... 0010011 @r2 | ||
61 | ctz 011000 000001 ..... 001 ..... 0010011 @r2 | ||
62 | @@ -XXX,XX +XXX,XX @@ min 0000101 .......... 100 ..... 0110011 @r | ||
63 | minu 0000101 .......... 101 ..... 0110011 @r | ||
64 | orc_b 001010 000111 ..... 101 ..... 0010011 @r2 | ||
65 | orn 0100000 .......... 110 ..... 0110011 @r | ||
66 | -# The encoding for rev8 differs between RV32 and RV64. | ||
67 | -# rev8_32 denotes the RV32 variant. | ||
68 | -rev8_32 011010 011000 ..... 101 ..... 0010011 @r2 | ||
69 | -rol 0110000 .......... 001 ..... 0110011 @r | ||
70 | -ror 0110000 .......... 101 ..... 0110011 @r | ||
71 | -rori 01100 ............ 101 ..... 0010011 @sh | ||
72 | sext_b 011000 000100 ..... 001 ..... 0010011 @r2 | ||
73 | sext_h 011000 000101 ..... 001 ..... 0010011 @r2 | ||
74 | -xnor 0100000 .......... 100 ..... 0110011 @r | ||
75 | -# The encoding for zext.h differs between RV32 and RV64. | ||
76 | -# zext_h_32 denotes the RV32 variant. | ||
77 | -zext_h_32 0000100 00000 ..... 100 ..... 0110011 @r2 | ||
78 | +# *** RV32 extra Zbkb Standard Extension *** | ||
79 | +brev8 0110100 00111 ..... 101 ..... 0010011 @r2 #grevi | ||
80 | +packh 0000100 .......... 111 ..... 0110011 @r | ||
81 | +unzip 0000100 01111 ..... 101 ..... 0010011 @r2 #unshfl | ||
82 | +zip 0000100 01111 ..... 001 ..... 0010011 @r2 #shfl | ||
83 | |||
84 | -# *** RV64 Zbb Standard Extension (in addition to RV32 Zbb) *** | ||
85 | -clzw 0110000 00000 ..... 001 ..... 0011011 @r2 | ||
86 | -ctzw 0110000 00001 ..... 001 ..... 0011011 @r2 | ||
87 | -cpopw 0110000 00010 ..... 001 ..... 0011011 @r2 | ||
88 | +# *** RV64 Zbb/Zbkb Standard Extension (in addition to RV32 Zbb/Zbkb) *** | ||
89 | # The encoding for rev8 differs between RV32 and RV64. | ||
90 | # When executing on RV64, the encoding used in RV32 is an illegal | ||
91 | # instruction, so we use different handler functions to differentiate. | ||
92 | @@ -XXX,XX +XXX,XX @@ rorw 0110000 .......... 101 ..... 0111011 @r | ||
93 | # The encoding for zext.h differs between RV32 and RV64. | ||
94 | # When executing on RV64, the encoding used in RV32 is an illegal | ||
95 | # instruction, so we use different handler functions to differentiate. | ||
96 | -zext_h_64 0000100 00000 ..... 100 ..... 0111011 @r2 | ||
97 | +{ | ||
98 | + zext_h_64 0000100 00000 ..... 100 ..... 0111011 @r2 | ||
99 | + packw 0000100 ..... ..... 100 ..... 0111011 @r | ||
100 | +} | ||
101 | +# *** RV64 extra Zbb Standard Extension (in addition to RV32 Zbb) *** | ||
102 | +clzw 0110000 00000 ..... 001 ..... 0011011 @r2 | ||
103 | +ctzw 0110000 00001 ..... 001 ..... 0011011 @r2 | ||
104 | +cpopw 0110000 00010 ..... 001 ..... 0011011 @r2 | ||
105 | |||
106 | # *** RV32 Zbc Standard Extension *** | ||
107 | clmul 0000101 .......... 001 ..... 0110011 @r | ||
108 | diff --git a/target/riscv/bitmanip_helper.c b/target/riscv/bitmanip_helper.c | ||
109 | index XXXXXXX..XXXXXXX 100644 | ||
110 | --- a/target/riscv/bitmanip_helper.c | ||
111 | +++ b/target/riscv/bitmanip_helper.c | ||
112 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(clmulr)(target_ulong rs1, target_ulong rs2) | ||
113 | |||
114 | return result; | ||
115 | } | 39 | } |
116 | + | ||
117 | +static inline target_ulong do_swap(target_ulong x, uint64_t mask, int shift) | ||
118 | +{ | ||
119 | + return ((x & mask) << shift) | ((x & ~mask) >> shift); | ||
120 | +} | ||
121 | + | ||
122 | +target_ulong HELPER(brev8)(target_ulong rs1) | ||
123 | +{ | ||
124 | + target_ulong x = rs1; | ||
125 | + | ||
126 | + x = do_swap(x, 0x5555555555555555ull, 1); | ||
127 | + x = do_swap(x, 0x3333333333333333ull, 2); | ||
128 | + x = do_swap(x, 0x0f0f0f0f0f0f0f0full, 4); | ||
129 | + return x; | ||
130 | +} | ||
131 | + | ||
132 | +static const uint64_t shuf_masks[] = { | ||
133 | + dup_const(MO_8, 0x44), | ||
134 | + dup_const(MO_8, 0x30), | ||
135 | + dup_const(MO_16, 0x0f00), | ||
136 | + dup_const(MO_32, 0xff0000) | ||
137 | +}; | ||
138 | + | ||
139 | +static inline target_ulong do_shuf_stage(target_ulong src, uint64_t maskL, | ||
140 | + uint64_t maskR, int shift) | ||
141 | +{ | ||
142 | + target_ulong x = src & ~(maskL | maskR); | ||
143 | + | ||
144 | + x |= ((src << shift) & maskL) | ((src >> shift) & maskR); | ||
145 | + return x; | ||
146 | +} | ||
147 | + | ||
148 | +target_ulong HELPER(unzip)(target_ulong rs1) | ||
149 | +{ | ||
150 | + target_ulong x = rs1; | ||
151 | + | ||
152 | + x = do_shuf_stage(x, shuf_masks[0], shuf_masks[0] >> 1, 1); | ||
153 | + x = do_shuf_stage(x, shuf_masks[1], shuf_masks[1] >> 2, 2); | ||
154 | + x = do_shuf_stage(x, shuf_masks[2], shuf_masks[2] >> 4, 4); | ||
155 | + x = do_shuf_stage(x, shuf_masks[3], shuf_masks[3] >> 8, 8); | ||
156 | + return x; | ||
157 | +} | ||
158 | + | ||
159 | +target_ulong HELPER(zip)(target_ulong rs1) | ||
160 | +{ | ||
161 | + target_ulong x = rs1; | ||
162 | + | ||
163 | + x = do_shuf_stage(x, shuf_masks[3], shuf_masks[3] >> 8, 8); | ||
164 | + x = do_shuf_stage(x, shuf_masks[2], shuf_masks[2] >> 4, 4); | ||
165 | + x = do_shuf_stage(x, shuf_masks[1], shuf_masks[1] >> 2, 2); | ||
166 | + x = do_shuf_stage(x, shuf_masks[0], shuf_masks[0] >> 1, 1); | ||
167 | + return x; | ||
168 | +} | ||
169 | diff --git a/target/riscv/translate.c b/target/riscv/translate.c | ||
170 | index XXXXXXX..XXXXXXX 100644 | ||
171 | --- a/target/riscv/translate.c | ||
172 | +++ b/target/riscv/translate.c | ||
173 | @@ -XXX,XX +XXX,XX @@ EX_SH(12) | ||
174 | } \ | ||
175 | } while (0) | ||
176 | |||
177 | +#define REQUIRE_EITHER_EXT(ctx, A, B) do { \ | ||
178 | + if (!ctx->cfg_ptr->ext_##A && \ | ||
179 | + !ctx->cfg_ptr->ext_##B) { \ | ||
180 | + return false; \ | ||
181 | + } \ | ||
182 | +} while (0) | ||
183 | + | ||
184 | static int ex_rvc_register(DisasContext *ctx, int reg) | ||
185 | { | ||
186 | return 8 + reg; | ||
187 | diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc | ||
188 | index XXXXXXX..XXXXXXX 100644 | ||
189 | --- a/target/riscv/insn_trans/trans_rvb.c.inc | ||
190 | +++ b/target/riscv/insn_trans/trans_rvb.c.inc | ||
191 | @@ -XXX,XX +XXX,XX @@ | ||
192 | /* | ||
193 | - * RISC-V translation routines for the Zb[abcs] Standard Extension. | ||
194 | + * RISC-V translation routines for the Zb[abcs] and Zbk[bcx] Standard Extension. | ||
195 | * | ||
196 | * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com | ||
197 | * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com | ||
198 | @@ -XXX,XX +XXX,XX @@ | ||
199 | } \ | ||
200 | } while (0) | ||
201 | |||
202 | +#define REQUIRE_ZBKB(ctx) do { \ | ||
203 | + if (!ctx->cfg_ptr->ext_zbkb) { \ | ||
204 | + return false; \ | ||
205 | + } \ | ||
206 | +} while (0) | ||
207 | + | ||
208 | static void gen_clz(TCGv ret, TCGv arg1) | ||
209 | { | ||
210 | tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS); | ||
211 | @@ -XXX,XX +XXX,XX @@ static bool trans_cpop(DisasContext *ctx, arg_cpop *a) | ||
212 | |||
213 | static bool trans_andn(DisasContext *ctx, arg_andn *a) | ||
214 | { | ||
215 | - REQUIRE_ZBB(ctx); | ||
216 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
217 | return gen_logic(ctx, a, tcg_gen_andc_tl); | ||
218 | } | ||
219 | |||
220 | static bool trans_orn(DisasContext *ctx, arg_orn *a) | ||
221 | { | ||
222 | - REQUIRE_ZBB(ctx); | ||
223 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
224 | return gen_logic(ctx, a, tcg_gen_orc_tl); | ||
225 | } | ||
226 | |||
227 | static bool trans_xnor(DisasContext *ctx, arg_xnor *a) | ||
228 | { | ||
229 | - REQUIRE_ZBB(ctx); | ||
230 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
231 | return gen_logic(ctx, a, tcg_gen_eqv_tl); | ||
232 | } | ||
233 | |||
234 | @@ -XXX,XX +XXX,XX @@ static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2) | ||
235 | |||
236 | static bool trans_ror(DisasContext *ctx, arg_ror *a) | ||
237 | { | ||
238 | - REQUIRE_ZBB(ctx); | ||
239 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
240 | return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw, NULL); | ||
241 | } | ||
242 | |||
243 | @@ -XXX,XX +XXX,XX @@ static void gen_roriw(TCGv ret, TCGv arg1, target_long shamt) | ||
244 | |||
245 | static bool trans_rori(DisasContext *ctx, arg_rori *a) | ||
246 | { | ||
247 | - REQUIRE_ZBB(ctx); | ||
248 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
249 | return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE, | ||
250 | tcg_gen_rotri_tl, gen_roriw, NULL); | ||
251 | } | ||
252 | @@ -XXX,XX +XXX,XX @@ static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2) | ||
253 | |||
254 | static bool trans_rol(DisasContext *ctx, arg_rol *a) | ||
255 | { | ||
256 | - REQUIRE_ZBB(ctx); | ||
257 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
258 | return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw, NULL); | ||
259 | } | ||
260 | |||
261 | @@ -XXX,XX +XXX,XX @@ static void gen_rev8_32(TCGv ret, TCGv src1) | ||
262 | static bool trans_rev8_32(DisasContext *ctx, arg_rev8_32 *a) | ||
263 | { | ||
264 | REQUIRE_32BIT(ctx); | ||
265 | - REQUIRE_ZBB(ctx); | ||
266 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
267 | return gen_unary(ctx, a, EXT_NONE, gen_rev8_32); | ||
268 | } | ||
269 | |||
270 | static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 *a) | ||
271 | { | ||
272 | REQUIRE_64BIT(ctx); | ||
273 | - REQUIRE_ZBB(ctx); | ||
274 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
275 | return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl); | ||
276 | } | ||
277 | |||
278 | @@ -XXX,XX +XXX,XX @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a) | ||
279 | static bool trans_rorw(DisasContext *ctx, arg_rorw *a) | ||
280 | { | ||
281 | REQUIRE_64BIT(ctx); | ||
282 | - REQUIRE_ZBB(ctx); | ||
283 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
284 | ctx->ol = MXL_RV32; | ||
285 | return gen_shift(ctx, a, EXT_NONE, gen_rorw, NULL); | ||
286 | } | ||
287 | @@ -XXX,XX +XXX,XX @@ static bool trans_rorw(DisasContext *ctx, arg_rorw *a) | ||
288 | static bool trans_roriw(DisasContext *ctx, arg_roriw *a) | ||
289 | { | ||
290 | REQUIRE_64BIT(ctx); | ||
291 | - REQUIRE_ZBB(ctx); | ||
292 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
293 | ctx->ol = MXL_RV32; | ||
294 | return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL); | ||
295 | } | ||
296 | @@ -XXX,XX +XXX,XX @@ static bool trans_roriw(DisasContext *ctx, arg_roriw *a) | ||
297 | static bool trans_rolw(DisasContext *ctx, arg_rolw *a) | ||
298 | { | ||
299 | REQUIRE_64BIT(ctx); | ||
300 | - REQUIRE_ZBB(ctx); | ||
301 | + REQUIRE_EITHER_EXT(ctx, zbb, zbkb); | ||
302 | ctx->ol = MXL_RV32; | ||
303 | return gen_shift(ctx, a, EXT_NONE, gen_rolw, NULL); | ||
304 | } | ||
305 | @@ -XXX,XX +XXX,XX @@ static bool trans_clmulr(DisasContext *ctx, arg_clmulh *a) | ||
306 | REQUIRE_ZBC(ctx); | ||
307 | return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr, NULL); | ||
308 | } | ||
309 | + | ||
310 | +static void gen_pack(TCGv ret, TCGv src1, TCGv src2) | ||
311 | +{ | ||
312 | + tcg_gen_deposit_tl(ret, src1, src2, | ||
313 | + TARGET_LONG_BITS / 2, | ||
314 | + TARGET_LONG_BITS / 2); | ||
315 | +} | ||
316 | + | ||
317 | +static void gen_packh(TCGv ret, TCGv src1, TCGv src2) | ||
318 | +{ | ||
319 | + TCGv t = tcg_temp_new(); | ||
320 | + | ||
321 | + tcg_gen_ext8u_tl(t, src2); | ||
322 | + tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8); | ||
323 | + tcg_temp_free(t); | ||
324 | +} | ||
325 | + | ||
326 | +static void gen_packw(TCGv ret, TCGv src1, TCGv src2) | ||
327 | +{ | ||
328 | + TCGv t = tcg_temp_new(); | ||
329 | + | ||
330 | + tcg_gen_ext16s_tl(t, src2); | ||
331 | + tcg_gen_deposit_tl(ret, src1, t, 16, TARGET_LONG_BITS - 16); | ||
332 | + tcg_temp_free(t); | ||
333 | +} | ||
334 | + | ||
335 | +static bool trans_brev8(DisasContext *ctx, arg_brev8 *a) | ||
336 | +{ | ||
337 | + REQUIRE_ZBKB(ctx); | ||
338 | + return gen_unary(ctx, a, EXT_NONE, gen_helper_brev8); | ||
339 | +} | ||
340 | + | ||
341 | +static bool trans_pack(DisasContext *ctx, arg_pack *a) | ||
342 | +{ | ||
343 | + REQUIRE_ZBKB(ctx); | ||
344 | + return gen_arith(ctx, a, EXT_NONE, gen_pack, NULL); | ||
345 | +} | ||
346 | + | ||
347 | +static bool trans_packh(DisasContext *ctx, arg_packh *a) | ||
348 | +{ | ||
349 | + REQUIRE_ZBKB(ctx); | ||
350 | + return gen_arith(ctx, a, EXT_NONE, gen_packh, NULL); | ||
351 | +} | ||
352 | + | ||
353 | +static bool trans_packw(DisasContext *ctx, arg_packw *a) | ||
354 | +{ | ||
355 | + REQUIRE_64BIT(ctx); | ||
356 | + REQUIRE_ZBKB(ctx); | ||
357 | + return gen_arith(ctx, a, EXT_NONE, gen_packw, NULL); | ||
358 | +} | ||
359 | + | ||
360 | +static bool trans_unzip(DisasContext *ctx, arg_unzip *a) | ||
361 | +{ | ||
362 | + REQUIRE_32BIT(ctx); | ||
363 | + REQUIRE_ZBKB(ctx); | ||
364 | + return gen_unary(ctx, a, EXT_NONE, gen_helper_unzip); | ||
365 | +} | ||
366 | + | ||
367 | +static bool trans_zip(DisasContext *ctx, arg_zip *a) | ||
368 | +{ | ||
369 | + REQUIRE_32BIT(ctx); | ||
370 | + REQUIRE_ZBKB(ctx); | ||
371 | + return gen_unary(ctx, a, EXT_NONE, gen_helper_zip); | ||
372 | +} | ||
373 | -- | 40 | -- |
374 | 2.35.1 | 41 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Richard Henderson <richard.henderson@linaro.org> |
---|---|---|---|
2 | 2 | ||
3 | - reuse partial instructions of zbc extension, update extension check for them | 3 | The riscv_raise_exception function stores its argument into |
4 | exception_index and then exits to the main loop. When we | ||
5 | have already set exception_index, we can just exit directly. | ||
4 | 6 | ||
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 7 | Signed-off-by: Richard Henderson <richard.henderson@linaro.org> |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | 9 | Message-Id: <20220401125948.79292-2-richard.henderson@linaro.org> |
9 | Message-Id: <20220423023510.30794-4-liweiwei@iscas.ac.cn> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 11 | --- |
12 | target/riscv/insn32.decode | 3 ++- | 12 | target/riscv/cpu_helper.c | 6 +++--- |
13 | target/riscv/insn_trans/trans_rvb.c.inc | 4 ++-- | 13 | 1 file changed, 3 insertions(+), 3 deletions(-) |
14 | 2 files changed, 4 insertions(+), 3 deletions(-) | ||
15 | 14 | ||
16 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | 15 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c |
17 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/target/riscv/insn32.decode | 17 | --- a/target/riscv/cpu_helper.c |
19 | +++ b/target/riscv/insn32.decode | 18 | +++ b/target/riscv/cpu_helper.c |
20 | @@ -XXX,XX +XXX,XX @@ clzw 0110000 00000 ..... 001 ..... 0011011 @r2 | 19 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, |
21 | ctzw 0110000 00001 ..... 001 ..... 0011011 @r2 | 20 | env->badaddr = addr; |
22 | cpopw 0110000 00010 ..... 001 ..... 0011011 @r2 | 21 | env->two_stage_lookup = riscv_cpu_virt_enabled(env) || |
23 | 22 | riscv_cpu_two_stage_lookup(mmu_idx); | |
24 | -# *** RV32 Zbc Standard Extension *** | 23 | - riscv_raise_exception(&cpu->env, cs->exception_index, retaddr); |
25 | +# *** RV32 Zbc/Zbkc Standard Extension *** | 24 | + cpu_loop_exit_restore(cs, retaddr); |
26 | clmul 0000101 .......... 001 ..... 0110011 @r | ||
27 | clmulh 0000101 .......... 011 ..... 0110011 @r | ||
28 | +# *** RV32 extra Zbc Standard Extension *** | ||
29 | clmulr 0000101 .......... 010 ..... 0110011 @r | ||
30 | |||
31 | # *** RV32 Zbs Standard Extension *** | ||
32 | diff --git a/target/riscv/insn_trans/trans_rvb.c.inc b/target/riscv/insn_trans/trans_rvb.c.inc | ||
33 | index XXXXXXX..XXXXXXX 100644 | ||
34 | --- a/target/riscv/insn_trans/trans_rvb.c.inc | ||
35 | +++ b/target/riscv/insn_trans/trans_rvb.c.inc | ||
36 | @@ -XXX,XX +XXX,XX @@ static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a) | ||
37 | |||
38 | static bool trans_clmul(DisasContext *ctx, arg_clmul *a) | ||
39 | { | ||
40 | - REQUIRE_ZBC(ctx); | ||
41 | + REQUIRE_EITHER_EXT(ctx, zbc, zbkc); | ||
42 | return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul, NULL); | ||
43 | } | 25 | } |
44 | 26 | ||
45 | @@ -XXX,XX +XXX,XX @@ static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2) | 27 | void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, |
46 | 28 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr, | |
47 | static bool trans_clmulh(DisasContext *ctx, arg_clmulr *a) | 29 | env->badaddr = addr; |
48 | { | 30 | env->two_stage_lookup = riscv_cpu_virt_enabled(env) || |
49 | - REQUIRE_ZBC(ctx); | 31 | riscv_cpu_two_stage_lookup(mmu_idx); |
50 | + REQUIRE_EITHER_EXT(ctx, zbc, zbkc); | 32 | - riscv_raise_exception(env, cs->exception_index, retaddr); |
51 | return gen_arith(ctx, a, EXT_NONE, gen_clmulh, NULL); | 33 | + cpu_loop_exit_restore(cs, retaddr); |
52 | } | 34 | } |
53 | 35 | ||
36 | bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
37 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, | ||
38 | first_stage_error, | ||
39 | riscv_cpu_virt_enabled(env) || | ||
40 | riscv_cpu_two_stage_lookup(mmu_idx)); | ||
41 | - riscv_raise_exception(env, cs->exception_index, retaddr); | ||
42 | + cpu_loop_exit_restore(cs, retaddr); | ||
43 | } | ||
44 | |||
45 | return true; | ||
54 | -- | 46 | -- |
55 | 2.35.1 | 47 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de> |
---|---|---|---|
2 | 2 | ||
3 | Move the binary and device tree loading code to the machine done | 3 | The -bios option is silently ignored if used in combination with -enable-kvm. |
4 | notifier. This allows us to prepare for editing the device tree as part | 4 | The reason is that the machine starts in S-Mode, and the bios typically runs in |
5 | of the notifier. | 5 | M-Mode. |
6 | 6 | ||
7 | This is based on similar code in the ARM virt machine. | 7 | Better exit in that case to not confuse the user. |
8 | 8 | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de> |
10 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | 10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
11 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 11 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> |
12 | Message-Id: <20220427234146.1130752-2-alistair.francis@opensource.wdc.com> | 12 | Reviewed-by: Anup Patel <anup@brainfault.org> |
13 | Message-Id: <20220401121842.2791796-1-ralf.ramsauer@oth-regensburg.de> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
14 | --- | 15 | --- |
15 | include/hw/riscv/virt.h | 1 + | 16 | hw/riscv/virt.c | 14 ++++++++++---- |
16 | hw/riscv/virt.c | 191 +++++++++++++++++++++------------------- | 17 | 1 file changed, 10 insertions(+), 4 deletions(-) |
17 | 2 files changed, 102 insertions(+), 90 deletions(-) | ||
18 | 18 | ||
19 | diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h | ||
20 | index XXXXXXX..XXXXXXX 100644 | ||
21 | --- a/include/hw/riscv/virt.h | ||
22 | +++ b/include/hw/riscv/virt.h | ||
23 | @@ -XXX,XX +XXX,XX @@ struct RISCVVirtState { | ||
24 | MachineState parent; | ||
25 | |||
26 | /*< public >*/ | ||
27 | + Notifier machine_done; | ||
28 | RISCVHartArrayState soc[VIRT_SOCKETS_MAX]; | ||
29 | DeviceState *irqchip[VIRT_SOCKETS_MAX]; | ||
30 | PFlashCFI01 *flash[2]; | ||
31 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 19 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
32 | index XXXXXXX..XXXXXXX 100644 | 20 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/hw/riscv/virt.c | 21 | --- a/hw/riscv/virt.c |
34 | +++ b/hw/riscv/virt.c | 22 | +++ b/hw/riscv/virt.c |
35 | @@ -XXX,XX +XXX,XX @@ static DeviceState *virt_create_aia(RISCVVirtAIAType aia_type, int aia_guests, | 23 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) |
36 | return aplic_m; | 24 | |
37 | } | 25 | /* |
38 | 26 | * Only direct boot kernel is currently supported for KVM VM, | |
39 | +static void virt_machine_done(Notifier *notifier, void *data) | 27 | - * so the "-bios" parameter is ignored and treated like "-bios none" |
40 | +{ | 28 | - * when KVM is enabled. |
41 | + RISCVVirtState *s = container_of(notifier, RISCVVirtState, | ||
42 | + machine_done); | ||
43 | + const MemMapEntry *memmap = virt_memmap; | ||
44 | + MachineState *machine = MACHINE(s); | ||
45 | + target_ulong start_addr = memmap[VIRT_DRAM].base; | ||
46 | + target_ulong firmware_end_addr, kernel_start_addr; | ||
47 | + uint32_t fdt_load_addr; | ||
48 | + uint64_t kernel_entry; | ||
49 | + | ||
50 | + /* | ||
51 | + * Only direct boot kernel is currently supported for KVM VM, | ||
52 | + * so the "-bios" parameter is not supported when KVM is enabled. | 29 | + * so the "-bios" parameter is not supported when KVM is enabled. |
53 | + */ | 30 | */ |
54 | + if (kvm_enabled()) { | 31 | if (kvm_enabled()) { |
32 | - g_free(machine->firmware); | ||
33 | - machine->firmware = g_strdup("none"); | ||
55 | + if (machine->firmware) { | 34 | + if (machine->firmware) { |
56 | + if (strcmp(machine->firmware, "none")) { | 35 | + if (strcmp(machine->firmware, "none")) { |
57 | + error_report("Machine mode firmware is not supported in " | 36 | + error_report("Machine mode firmware is not supported in " |
58 | + "combination with KVM."); | 37 | + "combination with KVM."); |
59 | + exit(1); | 38 | + exit(1); |
60 | + } | 39 | + } |
61 | + } else { | 40 | + } else { |
62 | + machine->firmware = g_strdup("none"); | 41 | + machine->firmware = g_strdup("none"); |
63 | + } | 42 | + } |
64 | + } | ||
65 | + | ||
66 | + if (riscv_is_32bit(&s->soc[0])) { | ||
67 | + firmware_end_addr = riscv_find_and_load_firmware(machine, | ||
68 | + RISCV32_BIOS_BIN, start_addr, NULL); | ||
69 | + } else { | ||
70 | + firmware_end_addr = riscv_find_and_load_firmware(machine, | ||
71 | + RISCV64_BIOS_BIN, start_addr, NULL); | ||
72 | + } | ||
73 | + | ||
74 | + if (machine->kernel_filename) { | ||
75 | + kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0], | ||
76 | + firmware_end_addr); | ||
77 | + | ||
78 | + kernel_entry = riscv_load_kernel(machine->kernel_filename, | ||
79 | + kernel_start_addr, NULL); | ||
80 | + | ||
81 | + if (machine->initrd_filename) { | ||
82 | + hwaddr start; | ||
83 | + hwaddr end = riscv_load_initrd(machine->initrd_filename, | ||
84 | + machine->ram_size, kernel_entry, | ||
85 | + &start); | ||
86 | + qemu_fdt_setprop_cell(machine->fdt, "/chosen", | ||
87 | + "linux,initrd-start", start); | ||
88 | + qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end", | ||
89 | + end); | ||
90 | + } | ||
91 | + } else { | ||
92 | + /* | ||
93 | + * If dynamic firmware is used, it doesn't know where is the next mode | ||
94 | + * if kernel argument is not set. | ||
95 | + */ | ||
96 | + kernel_entry = 0; | ||
97 | + } | ||
98 | + | ||
99 | + if (drive_get(IF_PFLASH, 0, 0)) { | ||
100 | + /* | ||
101 | + * Pflash was supplied, let's overwrite the address we jump to after | ||
102 | + * reset to the base of the flash. | ||
103 | + */ | ||
104 | + start_addr = virt_memmap[VIRT_FLASH].base; | ||
105 | + } | ||
106 | + | ||
107 | + /* | ||
108 | + * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device | ||
109 | + * tree cannot be altered and we get FDT_ERR_NOSPACE. | ||
110 | + */ | ||
111 | + s->fw_cfg = create_fw_cfg(machine); | ||
112 | + rom_set_fw(s->fw_cfg); | ||
113 | + | ||
114 | + /* Compute the fdt load address in dram */ | ||
115 | + fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base, | ||
116 | + machine->ram_size, machine->fdt); | ||
117 | + /* load the reset vector */ | ||
118 | + riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr, | ||
119 | + virt_memmap[VIRT_MROM].base, | ||
120 | + virt_memmap[VIRT_MROM].size, kernel_entry, | ||
121 | + fdt_load_addr, machine->fdt); | ||
122 | + | ||
123 | + /* | ||
124 | + * Only direct boot kernel is currently supported for KVM VM, | ||
125 | + * So here setup kernel start address and fdt address. | ||
126 | + * TODO:Support firmware loading and integrate to TCG start | ||
127 | + */ | ||
128 | + if (kvm_enabled()) { | ||
129 | + riscv_setup_direct_kernel(kernel_entry, fdt_load_addr); | ||
130 | + } | ||
131 | +} | ||
132 | + | ||
133 | static void virt_machine_init(MachineState *machine) | ||
134 | { | ||
135 | const MemMapEntry *memmap = virt_memmap; | ||
136 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) | ||
137 | MemoryRegion *system_memory = get_system_memory(); | ||
138 | MemoryRegion *mask_rom = g_new(MemoryRegion, 1); | ||
139 | char *soc_name; | ||
140 | - target_ulong start_addr = memmap[VIRT_DRAM].base; | ||
141 | - target_ulong firmware_end_addr, kernel_start_addr; | ||
142 | - uint32_t fdt_load_addr; | ||
143 | - uint64_t kernel_entry; | ||
144 | DeviceState *mmio_irqchip, *virtio_irqchip, *pcie_irqchip; | ||
145 | int i, base_hartid, hart_count; | ||
146 | |||
147 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) | ||
148 | memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base, | ||
149 | machine->ram); | ||
150 | |||
151 | - /* create device tree */ | ||
152 | - create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline, | ||
153 | - riscv_is_32bit(&s->soc[0])); | ||
154 | - | ||
155 | /* boot rom */ | ||
156 | memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom", | ||
157 | memmap[VIRT_MROM].size, &error_fatal); | ||
158 | memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base, | ||
159 | mask_rom); | ||
160 | |||
161 | - /* | ||
162 | - * Only direct boot kernel is currently supported for KVM VM, | ||
163 | - * so the "-bios" parameter is not supported when KVM is enabled. | ||
164 | - */ | ||
165 | - if (kvm_enabled()) { | ||
166 | - if (machine->firmware) { | ||
167 | - if (strcmp(machine->firmware, "none")) { | ||
168 | - error_report("Machine mode firmware is not supported in " | ||
169 | - "combination with KVM."); | ||
170 | - exit(1); | ||
171 | - } | ||
172 | - } else { | ||
173 | - machine->firmware = g_strdup("none"); | ||
174 | - } | ||
175 | - } | ||
176 | - | ||
177 | - if (riscv_is_32bit(&s->soc[0])) { | ||
178 | - firmware_end_addr = riscv_find_and_load_firmware(machine, | ||
179 | - RISCV32_BIOS_BIN, start_addr, NULL); | ||
180 | - } else { | ||
181 | - firmware_end_addr = riscv_find_and_load_firmware(machine, | ||
182 | - RISCV64_BIOS_BIN, start_addr, NULL); | ||
183 | - } | ||
184 | - | ||
185 | - if (machine->kernel_filename) { | ||
186 | - kernel_start_addr = riscv_calc_kernel_start_addr(&s->soc[0], | ||
187 | - firmware_end_addr); | ||
188 | - | ||
189 | - kernel_entry = riscv_load_kernel(machine->kernel_filename, | ||
190 | - kernel_start_addr, NULL); | ||
191 | - | ||
192 | - if (machine->initrd_filename) { | ||
193 | - hwaddr start; | ||
194 | - hwaddr end = riscv_load_initrd(machine->initrd_filename, | ||
195 | - machine->ram_size, kernel_entry, | ||
196 | - &start); | ||
197 | - qemu_fdt_setprop_cell(machine->fdt, "/chosen", | ||
198 | - "linux,initrd-start", start); | ||
199 | - qemu_fdt_setprop_cell(machine->fdt, "/chosen", "linux,initrd-end", | ||
200 | - end); | ||
201 | - } | ||
202 | - } else { | ||
203 | - /* | ||
204 | - * If dynamic firmware is used, it doesn't know where is the next mode | ||
205 | - * if kernel argument is not set. | ||
206 | - */ | ||
207 | - kernel_entry = 0; | ||
208 | - } | ||
209 | - | ||
210 | - if (drive_get(IF_PFLASH, 0, 0)) { | ||
211 | - /* | ||
212 | - * Pflash was supplied, let's overwrite the address we jump to after | ||
213 | - * reset to the base of the flash. | ||
214 | - */ | ||
215 | - start_addr = virt_memmap[VIRT_FLASH].base; | ||
216 | - } | ||
217 | - | ||
218 | - /* | ||
219 | - * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the device | ||
220 | - * tree cannot be altered and we get FDT_ERR_NOSPACE. | ||
221 | - */ | ||
222 | - s->fw_cfg = create_fw_cfg(machine); | ||
223 | - rom_set_fw(s->fw_cfg); | ||
224 | - | ||
225 | - /* Compute the fdt load address in dram */ | ||
226 | - fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base, | ||
227 | - machine->ram_size, machine->fdt); | ||
228 | - /* load the reset vector */ | ||
229 | - riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr, | ||
230 | - virt_memmap[VIRT_MROM].base, | ||
231 | - virt_memmap[VIRT_MROM].size, kernel_entry, | ||
232 | - fdt_load_addr, machine->fdt); | ||
233 | - | ||
234 | - /* | ||
235 | - * Only direct boot kernel is currently supported for KVM VM, | ||
236 | - * So here setup kernel start address and fdt address. | ||
237 | - * TODO:Support firmware loading and integrate to TCG start | ||
238 | - */ | ||
239 | - if (kvm_enabled()) { | ||
240 | - riscv_setup_direct_kernel(kernel_entry, fdt_load_addr); | ||
241 | - } | ||
242 | - | ||
243 | /* SiFive Test MMIO device */ | ||
244 | sifive_test_create(memmap[VIRT_TEST].base); | ||
245 | |||
246 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_init(MachineState *machine) | ||
247 | drive_get(IF_PFLASH, 0, i)); | ||
248 | } | 43 | } |
249 | virt_flash_map(s, system_memory); | 44 | |
250 | + | 45 | if (riscv_is_32bit(&s->soc[0])) { |
251 | + /* create device tree */ | ||
252 | + create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline, | ||
253 | + riscv_is_32bit(&s->soc[0])); | ||
254 | + | ||
255 | + s->machine_done.notify = virt_machine_done; | ||
256 | + qemu_add_machine_init_done_notifier(&s->machine_done); | ||
257 | } | ||
258 | |||
259 | static void virt_machine_instance_init(Object *obj) | ||
260 | -- | 46 | -- |
261 | 2.35.1 | 47 | 2.35.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Nicolas Pitre <nico@fluxnic.net> | ||
1 | 2 | ||
3 | There is an overflow with the current code where a pmpaddr value of | ||
4 | 0x1fffffff is decoded as sa=0 and ea=0 whereas it should be sa=0 and | ||
5 | ea=0xffffffff. | ||
6 | |||
7 | Fix that by simplifying the computation. There is in fact no need for | ||
8 | ctz64() nor special case for -1 to achieve proper results. | ||
9 | |||
10 | Signed-off-by: Nicolas Pitre <nico@fluxnic.net> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-Id: <rq81o86n-17ps-92no-p65o-79o88476266@syhkavp.arg> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | target/riscv/pmp.c | 14 +++----------- | ||
16 | 1 file changed, 3 insertions(+), 11 deletions(-) | ||
17 | |||
18 | diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/target/riscv/pmp.c | ||
21 | +++ b/target/riscv/pmp.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static void pmp_decode_napot(target_ulong a, target_ulong *sa, target_ulong *ea) | ||
23 | 0111...1111 2^(XLEN+2)-byte NAPOT range | ||
24 | 1111...1111 Reserved | ||
25 | */ | ||
26 | - if (a == -1) { | ||
27 | - *sa = 0u; | ||
28 | - *ea = -1; | ||
29 | - return; | ||
30 | - } else { | ||
31 | - target_ulong t1 = ctz64(~a); | ||
32 | - target_ulong base = (a & ~(((target_ulong)1 << t1) - 1)) << 2; | ||
33 | - target_ulong range = ((target_ulong)1 << (t1 + 3)) - 1; | ||
34 | - *sa = base; | ||
35 | - *ea = base + range; | ||
36 | - } | ||
37 | + a = (a << 2) | 0x3; | ||
38 | + *sa = a & (a + 1); | ||
39 | + *ea = a | (a + 1); | ||
40 | } | ||
41 | |||
42 | void pmp_update_rule_addr(CPURISCVState *env, uint32_t pmp_index) | ||
43 | -- | ||
44 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Niklas Cassel <niklas.cassel@wdc.com> |
---|---|---|---|
2 | 2 | ||
3 | Similar to the ARM virt machine add support for adding device tree | 3 | The device tree property "mmu-type" is currently exported as either |
4 | entries for dynamically created devices. | 4 | "riscv,sv32" or "riscv,sv48". |
5 | 5 | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 6 | However, the riscv cpu device tree binding [1] has a specific value |
7 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | 7 | "riscv,none" for a HART without a MMU. |
8 | Message-Id: <20220427234146.1130752-5-alistair.francis@opensource.wdc.com> | 8 | |
9 | Set the device tree property "mmu-type" to "riscv,none" when the CPU mmu | ||
10 | option is disabled using rv32,mmu=off or rv64,mmu=off. | ||
11 | |||
12 | [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/riscv/cpus.yaml?h=v5.17 | ||
13 | |||
14 | Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> | ||
15 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
16 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
17 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | Message-Id: <20220414155510.1364147-1-niklas.cassel@wdc.com> | ||
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 19 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
10 | --- | 20 | --- |
11 | hw/riscv/virt.c | 19 +++++++++++++++++++ | 21 | hw/riscv/virt.c | 10 ++++++++-- |
12 | 1 file changed, 19 insertions(+) | 22 | 1 file changed, 8 insertions(+), 2 deletions(-) |
13 | 23 | ||
14 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 24 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c |
15 | index XXXXXXX..XXXXXXX 100644 | 25 | index XXXXXXX..XXXXXXX 100644 |
16 | --- a/hw/riscv/virt.c | 26 | --- a/hw/riscv/virt.c |
17 | +++ b/hw/riscv/virt.c | 27 | +++ b/hw/riscv/virt.c |
18 | @@ -XXX,XX +XXX,XX @@ | 28 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, |
19 | #include "hw/qdev-properties.h" | 29 | cpu_name = g_strdup_printf("/cpus/cpu@%d", |
20 | #include "hw/char/serial.h" | 30 | s->soc[socket].hartid_base + cpu); |
21 | #include "target/riscv/cpu.h" | 31 | qemu_fdt_add_subnode(mc->fdt, cpu_name); |
22 | +#include "hw/core/sysbus-fdt.h" | 32 | - qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type", |
23 | #include "hw/riscv/riscv_hart.h" | 33 | - (is_32_bit) ? "riscv,sv32" : "riscv,sv48"); |
24 | #include "hw/riscv/virt.h" | 34 | + if (riscv_feature(&s->soc[socket].harts[cpu].env, |
25 | #include "hw/riscv/boot.h" | 35 | + RISCV_FEATURE_MMU)) { |
26 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_plic(RISCVVirtState *s, | 36 | + qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type", |
27 | riscv_socket_fdt_write_id(mc, mc->fdt, plic_name, socket); | 37 | + (is_32_bit) ? "riscv,sv32" : "riscv,sv48"); |
28 | qemu_fdt_setprop_cell(mc->fdt, plic_name, "phandle", | 38 | + } else { |
29 | plic_phandles[socket]); | 39 | + qemu_fdt_setprop_string(mc->fdt, cpu_name, "mmu-type", |
30 | + | 40 | + "riscv,none"); |
31 | + platform_bus_add_all_fdt_nodes(mc->fdt, plic_name, | 41 | + } |
32 | + memmap[VIRT_PLATFORM_BUS].base, | 42 | name = riscv_isa_string(&s->soc[socket].harts[cpu]); |
33 | + memmap[VIRT_PLATFORM_BUS].size, | 43 | qemu_fdt_setprop_string(mc->fdt, cpu_name, "riscv,isa", name); |
34 | + VIRT_PLATFORM_BUS_IRQ); | 44 | g_free(name); |
35 | + | ||
36 | g_free(plic_name); | ||
37 | |||
38 | g_free(plic_cells); | ||
39 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, | ||
40 | IMSIC_MMIO_GROUP_MIN_SHIFT); | ||
41 | } | ||
42 | qemu_fdt_setprop_cell(mc->fdt, imsic_name, "phandle", *msi_m_phandle); | ||
43 | + | ||
44 | + platform_bus_add_all_fdt_nodes(mc->fdt, imsic_name, | ||
45 | + memmap[VIRT_PLATFORM_BUS].base, | ||
46 | + memmap[VIRT_PLATFORM_BUS].size, | ||
47 | + VIRT_PLATFORM_BUS_IRQ); | ||
48 | + | ||
49 | g_free(imsic_name); | ||
50 | |||
51 | /* S-level IMSIC node */ | ||
52 | @@ -XXX,XX +XXX,XX @@ static void create_fdt_socket_aplic(RISCVVirtState *s, | ||
53 | VIRT_IRQCHIP_NUM_SOURCES); | ||
54 | riscv_socket_fdt_write_id(mc, mc->fdt, aplic_name, socket); | ||
55 | qemu_fdt_setprop_cell(mc->fdt, aplic_name, "phandle", aplic_s_phandle); | ||
56 | + | ||
57 | + platform_bus_add_all_fdt_nodes(mc->fdt, aplic_name, | ||
58 | + memmap[VIRT_PLATFORM_BUS].base, | ||
59 | + memmap[VIRT_PLATFORM_BUS].size, | ||
60 | + VIRT_PLATFORM_BUS_IRQ); | ||
61 | + | ||
62 | g_free(aplic_name); | ||
63 | |||
64 | g_free(aplic_cells); | ||
65 | -- | 45 | -- |
66 | 2.35.1 | 46 | 2.35.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | If device's MemoryRegion doesn't have .impl.[min|max]_access_size | ||
4 | declaration, the default access_size_min would be 1 byte and | ||
5 | access_size_max would be 4 bytes (see: softmmu/memory.c). | ||
6 | This will cause a 64-bit memory access to ACLINT to be splitted into | ||
7 | two 32-bit memory accesses. | ||
8 | |||
9 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
10 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Reviewed-by: Jim Shu <jim.shu@sifive.com> | ||
12 | Message-Id: <20220420080901.14655-2-frank.chang@sifive.com> | ||
13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
14 | --- | ||
15 | hw/intc/riscv_aclint.c | 4 ++++ | ||
16 | 1 file changed, 4 insertions(+) | ||
17 | |||
18 | diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/hw/intc/riscv_aclint.c | ||
21 | +++ b/hw/intc/riscv_aclint.c | ||
22 | @@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps riscv_aclint_mtimer_ops = { | ||
23 | .valid = { | ||
24 | .min_access_size = 4, | ||
25 | .max_access_size = 8 | ||
26 | + }, | ||
27 | + .impl = { | ||
28 | + .min_access_size = 4, | ||
29 | + .max_access_size = 8, | ||
30 | } | ||
31 | }; | ||
32 | |||
33 | -- | ||
34 | 2.35.1 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | From: Frank Chang <frank.chang@sifive.com> | ||
1 | 2 | ||
3 | RISC-V privilege spec defines that: | ||
4 | |||
5 | * In RV32, memory-mapped writes to mtimecmp modify only one 32-bit part | ||
6 | of the register. | ||
7 | * For RV64, naturally aligned 64-bit memory accesses to the mtime and | ||
8 | mtimecmp registers are additionally supported and are atomic. | ||
9 | |||
10 | It's possible to perform both 32/64-bit read/write accesses to both | ||
11 | mtimecmp and mtime registers. | ||
12 | |||
13 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
14 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
15 | Reviewed-by: Jim Shu <jim.shu@sifive.com> | ||
16 | Message-Id: <20220420080901.14655-3-frank.chang@sifive.com> | ||
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | ||
18 | --- | ||
19 | hw/intc/riscv_aclint.c | 42 +++++++++++++++++++++++++++--------------- | ||
20 | 1 file changed, 27 insertions(+), 15 deletions(-) | ||
21 | |||
22 | diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c | ||
23 | index XXXXXXX..XXXXXXX 100644 | ||
24 | --- a/hw/intc/riscv_aclint.c | ||
25 | +++ b/hw/intc/riscv_aclint.c | ||
26 | @@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, | ||
27 | qemu_log_mask(LOG_GUEST_ERROR, | ||
28 | "aclint-mtimer: invalid hartid: %zu", hartid); | ||
29 | } else if ((addr & 0x7) == 0) { | ||
30 | - /* timecmp_lo */ | ||
31 | + /* timecmp_lo for RV32/RV64 or timecmp for RV64 */ | ||
32 | uint64_t timecmp = env->timecmp; | ||
33 | - return timecmp & 0xFFFFFFFF; | ||
34 | + return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp; | ||
35 | } else if ((addr & 0x7) == 4) { | ||
36 | /* timecmp_hi */ | ||
37 | uint64_t timecmp = env->timecmp; | ||
38 | @@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, | ||
39 | return 0; | ||
40 | } | ||
41 | } else if (addr == mtimer->time_base) { | ||
42 | - /* time_lo */ | ||
43 | - return cpu_riscv_read_rtc(mtimer->timebase_freq) & 0xFFFFFFFF; | ||
44 | + /* time_lo for RV32/RV64 or timecmp for RV64 */ | ||
45 | + uint64_t rtc = cpu_riscv_read_rtc(mtimer->timebase_freq); | ||
46 | + return (size == 4) ? (rtc & 0xFFFFFFFF) : rtc; | ||
47 | } else if (addr == mtimer->time_base + 4) { | ||
48 | /* time_hi */ | ||
49 | return (cpu_riscv_read_rtc(mtimer->timebase_freq) >> 32) & 0xFFFFFFFF; | ||
50 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
51 | qemu_log_mask(LOG_GUEST_ERROR, | ||
52 | "aclint-mtimer: invalid hartid: %zu", hartid); | ||
53 | } else if ((addr & 0x7) == 0) { | ||
54 | - /* timecmp_lo */ | ||
55 | - uint64_t timecmp_hi = env->timecmp >> 32; | ||
56 | - riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
57 | - timecmp_hi << 32 | (value & 0xFFFFFFFF), | ||
58 | - mtimer->timebase_freq); | ||
59 | - return; | ||
60 | + if (size == 4) { | ||
61 | + /* timecmp_lo for RV32/RV64 */ | ||
62 | + uint64_t timecmp_hi = env->timecmp >> 32; | ||
63 | + riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
64 | + timecmp_hi << 32 | (value & 0xFFFFFFFF), | ||
65 | + mtimer->timebase_freq); | ||
66 | + } else { | ||
67 | + /* timecmp for RV64 */ | ||
68 | + riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
69 | + value, mtimer->timebase_freq); | ||
70 | + } | ||
71 | } else if ((addr & 0x7) == 4) { | ||
72 | - /* timecmp_hi */ | ||
73 | - uint64_t timecmp_lo = env->timecmp; | ||
74 | - riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
75 | - value << 32 | (timecmp_lo & 0xFFFFFFFF), | ||
76 | - mtimer->timebase_freq); | ||
77 | + if (size == 4) { | ||
78 | + /* timecmp_hi for RV32/RV64 */ | ||
79 | + uint64_t timecmp_lo = env->timecmp; | ||
80 | + riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
81 | + value << 32 | (timecmp_lo & 0xFFFFFFFF), | ||
82 | + mtimer->timebase_freq); | ||
83 | + } else { | ||
84 | + qemu_log_mask(LOG_GUEST_ERROR, | ||
85 | + "aclint-mtimer: invalid timecmp_hi write: %08x", | ||
86 | + (uint32_t)addr); | ||
87 | + } | ||
88 | } else { | ||
89 | qemu_log_mask(LOG_UNIMP, | ||
90 | "aclint-mtimer: invalid timecmp write: %08x", | ||
91 | -- | ||
92 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Frank Chang <frank.chang@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Co-authored-by: Ruibo Lu <luruibo2000@163.com> | 3 | RISC-V privilege spec defines that mtime is exposed as a memory-mapped |
4 | Co-authored-by: Zewen Ye <lustrew@foxmail.com> | 4 | machine-mode read-write register. However, as QEMU uses host monotonic |
5 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 5 | timer as timer source, this makes mtime to be read-only in RISC-V |
6 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 6 | ACLINT. |
7 | |||
8 | This patch makes mtime to be writable by recording the time delta value | ||
9 | between the mtime value to be written and the timer value at the time | ||
10 | mtime is written. Time delta value is then added back whenever the timer | ||
11 | value is retrieved. | ||
12 | |||
13 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
14 | Reviewed-by: Jim Shu <jim.shu@sifive.com> | ||
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
8 | Message-Id: <20220423023510.30794-14-liweiwei@iscas.ac.cn> | 16 | Message-Id: <20220420080901.14655-4-frank.chang@sifive.com> |
9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
10 | --- | 18 | --- |
11 | disas/riscv.c | 173 +++++++++++++++++++++++++++++++++++++++++++++++++- | 19 | include/hw/intc/riscv_aclint.h | 1 + |
12 | 1 file changed, 172 insertions(+), 1 deletion(-) | 20 | target/riscv/cpu.h | 8 ++-- |
13 | 21 | hw/intc/riscv_aclint.c | 71 ++++++++++++++++++++++++---------- | |
14 | diff --git a/disas/riscv.c b/disas/riscv.c | 22 | target/riscv/cpu_helper.c | 4 +- |
15 | index XXXXXXX..XXXXXXX 100644 | 23 | 4 files changed, 57 insertions(+), 27 deletions(-) |
16 | --- a/disas/riscv.c | 24 | |
17 | +++ b/disas/riscv.c | 25 | diff --git a/include/hw/intc/riscv_aclint.h b/include/hw/intc/riscv_aclint.h |
18 | @@ -XXX,XX +XXX,XX @@ typedef enum { | 26 | index XXXXXXX..XXXXXXX 100644 |
19 | rv_codec_css_swsp, | 27 | --- a/include/hw/intc/riscv_aclint.h |
20 | rv_codec_css_sdsp, | 28 | +++ b/include/hw/intc/riscv_aclint.h |
21 | rv_codec_css_sqsp, | 29 | @@ -XXX,XX +XXX,XX @@ |
22 | + rv_codec_k_bs, | 30 | typedef struct RISCVAclintMTimerState { |
23 | + rv_codec_k_rnum, | 31 | /*< private >*/ |
24 | } rv_codec; | 32 | SysBusDevice parent_obj; |
25 | 33 | + uint64_t time_delta; | |
26 | typedef enum { | 34 | |
27 | @@ -XXX,XX +XXX,XX @@ typedef enum { | 35 | /*< public >*/ |
28 | rv_op_bclr = 359, | 36 | MemoryRegion mmio; |
29 | rv_op_binv = 360, | 37 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
30 | rv_op_bext = 361, | 38 | index XXXXXXX..XXXXXXX 100644 |
31 | + rv_op_aes32esmi = 362, | 39 | --- a/target/riscv/cpu.h |
32 | + rv_op_aes32esi = 363, | 40 | +++ b/target/riscv/cpu.h |
33 | + rv_op_aes32dsmi = 364, | 41 | @@ -XXX,XX +XXX,XX @@ struct CPUArchState { |
34 | + rv_op_aes32dsi = 365, | 42 | type2_trigger_t type2_trig[TRIGGER_TYPE2_NUM]; |
35 | + rv_op_aes64ks1i = 366, | 43 | |
36 | + rv_op_aes64ks2 = 367, | 44 | /* machine specific rdtime callback */ |
37 | + rv_op_aes64im = 368, | 45 | - uint64_t (*rdtime_fn)(uint32_t); |
38 | + rv_op_aes64esm = 369, | 46 | - uint32_t rdtime_fn_arg; |
39 | + rv_op_aes64es = 370, | 47 | + uint64_t (*rdtime_fn)(void *); |
40 | + rv_op_aes64dsm = 371, | 48 | + void *rdtime_fn_arg; |
41 | + rv_op_aes64ds = 372, | 49 | |
42 | + rv_op_sha256sig0 = 373, | 50 | /* machine specific AIA ireg read-modify-write callback */ |
43 | + rv_op_sha256sig1 = 374, | 51 | #define AIA_MAKE_IREG(__isel, __priv, __virt, __vgein, __xlen) \ |
44 | + rv_op_sha256sum0 = 375, | 52 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_swap_hypervisor_regs(CPURISCVState *env); |
45 | + rv_op_sha256sum1 = 376, | 53 | int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint64_t interrupts); |
46 | + rv_op_sha512sig0 = 377, | 54 | uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value); |
47 | + rv_op_sha512sig1 = 378, | 55 | #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */ |
48 | + rv_op_sha512sum0 = 379, | 56 | -void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t), |
49 | + rv_op_sha512sum1 = 380, | 57 | - uint32_t arg); |
50 | + rv_op_sha512sum0r = 381, | 58 | +void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *), |
51 | + rv_op_sha512sum1r = 382, | 59 | + void *arg); |
52 | + rv_op_sha512sig0l = 383, | 60 | void riscv_cpu_set_aia_ireg_rmw_fn(CPURISCVState *env, uint32_t priv, |
53 | + rv_op_sha512sig0h = 384, | 61 | int (*rmw_fn)(void *arg, |
54 | + rv_op_sha512sig1l = 385, | 62 | target_ulong reg, |
55 | + rv_op_sha512sig1h = 386, | 63 | diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c |
56 | + rv_op_sm3p0 = 387, | 64 | index XXXXXXX..XXXXXXX 100644 |
57 | + rv_op_sm3p1 = 388, | 65 | --- a/hw/intc/riscv_aclint.c |
58 | + rv_op_sm4ed = 389, | 66 | +++ b/hw/intc/riscv_aclint.c |
59 | + rv_op_sm4ks = 390, | 67 | @@ -XXX,XX +XXX,XX @@ typedef struct riscv_aclint_mtimer_callback { |
60 | + rv_op_brev8 = 391, | 68 | int num; |
61 | + rv_op_pack = 392, | 69 | } riscv_aclint_mtimer_callback; |
62 | + rv_op_packh = 393, | 70 | |
63 | + rv_op_packw = 394, | 71 | -static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq) |
64 | + rv_op_unzip = 395, | 72 | +static uint64_t cpu_riscv_read_rtc_raw(uint32_t timebase_freq) |
65 | + rv_op_zip = 396, | 73 | { |
66 | + rv_op_xperm4 = 397, | 74 | return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), |
67 | + rv_op_xperm8 = 398, | 75 | timebase_freq, NANOSECONDS_PER_SECOND); |
68 | } rv_op; | ||
69 | |||
70 | /* structures */ | ||
71 | @@ -XXX,XX +XXX,XX @@ typedef struct { | ||
72 | uint8_t succ; | ||
73 | uint8_t aq; | ||
74 | uint8_t rl; | ||
75 | + uint8_t bs; | ||
76 | + uint8_t rnum; | ||
77 | } rv_decode; | ||
78 | |||
79 | typedef struct { | ||
80 | @@ -XXX,XX +XXX,XX @@ static const char rv_freg_name_sym[32][5] = { | ||
81 | #define rv_fmt_rd_rs2 "O\t0,2" | ||
82 | #define rv_fmt_rs1_offset "O\t1,o" | ||
83 | #define rv_fmt_rs2_offset "O\t2,o" | ||
84 | +#define rv_fmt_rs1_rs2_bs "O\t1,2,b" | ||
85 | +#define rv_fmt_rd_rs1_rnum "O\t0,1,n" | ||
86 | |||
87 | /* pseudo-instruction constraints */ | ||
88 | |||
89 | @@ -XXX,XX +XXX,XX @@ static const rv_comp_data rvcp_csrrw[] = { | ||
90 | { rv_op_illegal, NULL } | ||
91 | }; | ||
92 | |||
93 | + | ||
94 | static const rv_comp_data rvcp_csrrs[] = { | ||
95 | { rv_op_rdcycle, rvcc_rdcycle }, | ||
96 | { rv_op_rdtime, rvcc_rdtime }, | ||
97 | @@ -XXX,XX +XXX,XX @@ const rv_opcode_data opcode_data[] = { | ||
98 | { "bclr", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
99 | { "binv", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
100 | { "bext", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
101 | + { "aes32esmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, | ||
102 | + { "aes32esi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, | ||
103 | + { "aes32dsmi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, | ||
104 | + { "aes32dsi", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, | ||
105 | + { "aes64ks1i", rv_codec_k_rnum, rv_fmt_rd_rs1_rnum, NULL, 0, 0, 0 }, | ||
106 | + { "aes64ks2", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
107 | + { "aes64im", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, | ||
108 | + { "aes64esm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
109 | + { "aes64es", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
110 | + { "aes64dsm", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
111 | + { "aes64ds", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
112 | + { "sha256sig0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, | ||
113 | + { "sha256sig1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, | ||
114 | + { "sha256sum0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, | ||
115 | + { "sha256sum1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, | ||
116 | + { "sha512sig0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
117 | + { "sha512sig1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
118 | + { "sha512sum0", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
119 | + { "sha512sum1", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
120 | + { "sha512sum0r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
121 | + { "sha512sum1r", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
122 | + { "sha512sig0l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
123 | + { "sha512sig0h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
124 | + { "sha512sig1l", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
125 | + { "sha512sig1h", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
126 | + { "sm3p0", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, | ||
127 | + { "sm3p1", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0 }, | ||
128 | + { "sm4ed", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, | ||
129 | + { "sm4ks", rv_codec_k_bs, rv_fmt_rs1_rs2_bs, NULL, 0, 0, 0 }, | ||
130 | + { "brev8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | ||
131 | + { "pack", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
132 | + { "packh", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
133 | + { "packw", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
134 | + { "unzip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | ||
135 | + { "zip", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 }, | ||
136 | + { "xperm4", rv_codec_r, rv_fmt_rd_rs1_rs2, NULL, 0, 0, 0 }, | ||
137 | + { "xperm8", rv_codec_r, rv_fmt_rd_rs1, NULL, 0, 0, 0 } | ||
138 | }; | ||
139 | |||
140 | /* CSR names */ | ||
141 | @@ -XXX,XX +XXX,XX @@ static const char *csr_name(int csrno) | ||
142 | case 0x0003: return "fcsr"; | ||
143 | case 0x0004: return "uie"; | ||
144 | case 0x0005: return "utvec"; | ||
145 | + case 0x0015: return "seed"; | ||
146 | case 0x0040: return "uscratch"; | ||
147 | case 0x0041: return "uepc"; | ||
148 | case 0x0042: return "ucause"; | ||
149 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
150 | case 1: | ||
151 | switch (((inst >> 27) & 0b11111)) { | ||
152 | case 0b00000: op = rv_op_slli; break; | ||
153 | + case 0b00001: | ||
154 | + switch (((inst >> 20) & 0b1111111)) { | ||
155 | + case 0b0001111: op = rv_op_zip; break; | ||
156 | + } | ||
157 | + break; | ||
158 | + case 0b00010: | ||
159 | + switch (((inst >> 20) & 0b1111111)) { | ||
160 | + case 0b0000000: op = rv_op_sha256sum0; break; | ||
161 | + case 0b0000001: op = rv_op_sha256sum1; break; | ||
162 | + case 0b0000010: op = rv_op_sha256sig0; break; | ||
163 | + case 0b0000011: op = rv_op_sha256sig1; break; | ||
164 | + case 0b0000100: op = rv_op_sha512sum0; break; | ||
165 | + case 0b0000101: op = rv_op_sha512sum1; break; | ||
166 | + case 0b0000110: op = rv_op_sha512sig0; break; | ||
167 | + case 0b0000111: op = rv_op_sha512sig1; break; | ||
168 | + case 0b0001000: op = rv_op_sm3p0; break; | ||
169 | + case 0b0001001: op = rv_op_sm3p1; break; | ||
170 | + } | ||
171 | + break; | ||
172 | case 0b00101: op = rv_op_bseti; break; | ||
173 | + case 0b00110: | ||
174 | + switch (((inst >> 20) & 0b1111111)) { | ||
175 | + case 0b0000000: op = rv_op_aes64im; break; | ||
176 | + default: | ||
177 | + if (((inst >> 24) & 0b0111) == 0b001) { | ||
178 | + op = rv_op_aes64ks1i; | ||
179 | + } | ||
180 | + break; | ||
181 | + } | ||
182 | + break; | ||
183 | case 0b01001: op = rv_op_bclri; break; | ||
184 | case 0b01101: op = rv_op_binvi; break; | ||
185 | case 0b01100: | ||
186 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
187 | case 5: | ||
188 | switch (((inst >> 27) & 0b11111)) { | ||
189 | case 0b00000: op = rv_op_srli; break; | ||
190 | + case 0b00001: | ||
191 | + switch (((inst >> 20) & 0b1111111)) { | ||
192 | + case 0b0001111: op = rv_op_unzip; break; | ||
193 | + } | ||
194 | + break; | ||
195 | case 0b00101: op = rv_op_orc_b; break; | ||
196 | case 0b01000: op = rv_op_srai; break; | ||
197 | case 0b01001: op = rv_op_bexti; break; | ||
198 | case 0b01100: op = rv_op_rori; break; | ||
199 | case 0b01101: | ||
200 | switch ((inst >> 20) & 0b1111111) { | ||
201 | + case 0b0011000: op = rv_op_rev8; break; | ||
202 | case 0b0111000: op = rv_op_rev8; break; | ||
203 | + case 0b0000111: op = rv_op_brev8; break; | ||
204 | } | ||
205 | break; | ||
206 | } | ||
207 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
208 | case 36: | ||
209 | switch ((inst >> 20) & 0b11111) { | ||
210 | case 0: op = rv_op_zext_h; break; | ||
211 | + default: op = rv_op_pack; break; | ||
212 | } | ||
213 | break; | ||
214 | + case 39: op = rv_op_packh; break; | ||
215 | + | ||
216 | case 41: op = rv_op_clmul; break; | ||
217 | case 42: op = rv_op_clmulr; break; | ||
218 | case 43: op = rv_op_clmulh; break; | ||
219 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
220 | case 132: op = rv_op_sh2add; break; | ||
221 | case 134: op = rv_op_sh3add; break; | ||
222 | case 161: op = rv_op_bset; break; | ||
223 | + case 162: op = rv_op_xperm4; break; | ||
224 | + case 164: op = rv_op_xperm8; break; | ||
225 | + case 200: op = rv_op_aes64es; break; | ||
226 | + case 216: op = rv_op_aes64esm; break; | ||
227 | + case 232: op = rv_op_aes64ds; break; | ||
228 | + case 248: op = rv_op_aes64dsm; break; | ||
229 | case 256: op = rv_op_sub; break; | ||
230 | case 260: op = rv_op_xnor; break; | ||
231 | case 261: op = rv_op_sra; break; | ||
232 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
233 | case 263: op = rv_op_andn; break; | ||
234 | case 289: op = rv_op_bclr; break; | ||
235 | case 293: op = rv_op_bext; break; | ||
236 | + case 320: op = rv_op_sha512sum0r; break; | ||
237 | + case 328: op = rv_op_sha512sum1r; break; | ||
238 | + case 336: op = rv_op_sha512sig0l; break; | ||
239 | + case 344: op = rv_op_sha512sig1l; break; | ||
240 | + case 368: op = rv_op_sha512sig0h; break; | ||
241 | + case 376: op = rv_op_sha512sig1h; break; | ||
242 | case 385: op = rv_op_rol; break; | ||
243 | - case 386: op = rv_op_ror; break; | ||
244 | + case 389: op = rv_op_ror; break; | ||
245 | case 417: op = rv_op_binv; break; | ||
246 | + case 504: op = rv_op_aes64ks2; break; | ||
247 | + } | ||
248 | + switch ((inst >> 25) & 0b0011111) { | ||
249 | + case 17: op = rv_op_aes32esi; break; | ||
250 | + case 19: op = rv_op_aes32esmi; break; | ||
251 | + case 21: op = rv_op_aes32dsi; break; | ||
252 | + case 23: op = rv_op_aes32dsmi; break; | ||
253 | + case 24: op = rv_op_sm4ed; break; | ||
254 | + case 26: op = rv_op_sm4ks; break; | ||
255 | } | ||
256 | break; | ||
257 | case 13: op = rv_op_lui; break; | ||
258 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) | ||
259 | case 36: | ||
260 | switch ((inst >> 20) & 0b11111) { | ||
261 | case 0: op = rv_op_zext_h; break; | ||
262 | + default: op = rv_op_packw; break; | ||
263 | } | ||
264 | break; | ||
265 | case 130: op = rv_op_sh1add_uw; break; | ||
266 | @@ -XXX,XX +XXX,XX @@ static uint32_t operand_cimmq(rv_inst inst) | ||
267 | ((inst << 57) >> 62) << 6; | ||
268 | } | 76 | } |
269 | 77 | ||
270 | +static uint32_t operand_bs(rv_inst inst) | 78 | +static uint64_t cpu_riscv_read_rtc(void *opaque) |
271 | +{ | 79 | +{ |
272 | + return (inst << 32) >> 62; | 80 | + RISCVAclintMTimerState *mtimer = opaque; |
81 | + return cpu_riscv_read_rtc_raw(mtimer->timebase_freq) + mtimer->time_delta; | ||
273 | +} | 82 | +} |
274 | + | 83 | + |
275 | +static uint32_t operand_rnum(rv_inst inst) | 84 | /* |
276 | +{ | 85 | * Called when timecmp is written to update the QEMU timer or immediately |
277 | + return (inst << 40) >> 60; | 86 | * trigger timer interrupt if mtimecmp <= current timer value. |
278 | +} | 87 | @@ -XXX,XX +XXX,XX @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq) |
88 | static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, | ||
89 | RISCVCPU *cpu, | ||
90 | int hartid, | ||
91 | - uint64_t value, | ||
92 | - uint32_t timebase_freq) | ||
93 | + uint64_t value) | ||
94 | { | ||
95 | + uint32_t timebase_freq = mtimer->timebase_freq; | ||
96 | uint64_t next; | ||
97 | uint64_t diff; | ||
98 | |||
99 | - uint64_t rtc_r = cpu_riscv_read_rtc(timebase_freq); | ||
100 | + uint64_t rtc_r = cpu_riscv_read_rtc(mtimer); | ||
101 | |||
102 | cpu->env.timecmp = value; | ||
103 | if (cpu->env.timecmp <= rtc_r) { | ||
104 | @@ -XXX,XX +XXX,XX @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, | ||
105 | } | ||
106 | } else if (addr == mtimer->time_base) { | ||
107 | /* time_lo for RV32/RV64 or timecmp for RV64 */ | ||
108 | - uint64_t rtc = cpu_riscv_read_rtc(mtimer->timebase_freq); | ||
109 | + uint64_t rtc = cpu_riscv_read_rtc(mtimer); | ||
110 | return (size == 4) ? (rtc & 0xFFFFFFFF) : rtc; | ||
111 | } else if (addr == mtimer->time_base + 4) { | ||
112 | /* time_hi */ | ||
113 | - return (cpu_riscv_read_rtc(mtimer->timebase_freq) >> 32) & 0xFFFFFFFF; | ||
114 | + return (cpu_riscv_read_rtc(mtimer) >> 32) & 0xFFFFFFFF; | ||
115 | } | ||
116 | |||
117 | qemu_log_mask(LOG_UNIMP, | ||
118 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
119 | uint64_t value, unsigned size) | ||
120 | { | ||
121 | RISCVAclintMTimerState *mtimer = opaque; | ||
122 | + int i; | ||
123 | |||
124 | if (addr >= mtimer->timecmp_base && | ||
125 | addr < (mtimer->timecmp_base + (mtimer->num_harts << 3))) { | ||
126 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
127 | /* timecmp_lo for RV32/RV64 */ | ||
128 | uint64_t timecmp_hi = env->timecmp >> 32; | ||
129 | riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
130 | - timecmp_hi << 32 | (value & 0xFFFFFFFF), | ||
131 | - mtimer->timebase_freq); | ||
132 | + timecmp_hi << 32 | (value & 0xFFFFFFFF)); | ||
133 | } else { | ||
134 | /* timecmp for RV64 */ | ||
135 | riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
136 | - value, mtimer->timebase_freq); | ||
137 | + value); | ||
138 | } | ||
139 | } else if ((addr & 0x7) == 4) { | ||
140 | if (size == 4) { | ||
141 | /* timecmp_hi for RV32/RV64 */ | ||
142 | uint64_t timecmp_lo = env->timecmp; | ||
143 | riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, | ||
144 | - value << 32 | (timecmp_lo & 0xFFFFFFFF), | ||
145 | - mtimer->timebase_freq); | ||
146 | + value << 32 | (timecmp_lo & 0xFFFFFFFF)); | ||
147 | } else { | ||
148 | qemu_log_mask(LOG_GUEST_ERROR, | ||
149 | "aclint-mtimer: invalid timecmp_hi write: %08x", | ||
150 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, | ||
151 | (uint32_t)addr); | ||
152 | } | ||
153 | return; | ||
154 | - } else if (addr == mtimer->time_base) { | ||
155 | - /* time_lo */ | ||
156 | - qemu_log_mask(LOG_UNIMP, | ||
157 | - "aclint-mtimer: time_lo write not implemented"); | ||
158 | - return; | ||
159 | - } else if (addr == mtimer->time_base + 4) { | ||
160 | - /* time_hi */ | ||
161 | - qemu_log_mask(LOG_UNIMP, | ||
162 | - "aclint-mtimer: time_hi write not implemented"); | ||
163 | + } else if (addr == mtimer->time_base || addr == mtimer->time_base + 4) { | ||
164 | + uint64_t rtc_r = cpu_riscv_read_rtc_raw(mtimer->timebase_freq); | ||
279 | + | 165 | + |
280 | /* decode operands */ | 166 | + if (addr == mtimer->time_base) { |
281 | 167 | + if (size == 4) { | |
282 | static void decode_inst_operands(rv_decode *dec) | 168 | + /* time_lo for RV32/RV64 */ |
283 | @@ -XXX,XX +XXX,XX @@ static void decode_inst_operands(rv_decode *dec) | 169 | + mtimer->time_delta = ((rtc_r & ~0xFFFFFFFFULL) | value) - rtc_r; |
284 | dec->rs2 = operand_crs2(inst); | 170 | + } else { |
285 | dec->imm = operand_cimmsqsp(inst); | 171 | + /* time for RV64 */ |
286 | break; | 172 | + mtimer->time_delta = value - rtc_r; |
287 | + case rv_codec_k_bs: | 173 | + } |
288 | + dec->rs1 = operand_rs1(inst); | 174 | + } else { |
289 | + dec->rs2 = operand_rs2(inst); | 175 | + if (size == 4) { |
290 | + dec->bs = operand_bs(inst); | 176 | + /* time_hi for RV32/RV64 */ |
291 | + break; | 177 | + mtimer->time_delta = (value << 32 | (rtc_r & 0xFFFFFFFF)) - rtc_r; |
292 | + case rv_codec_k_rnum: | 178 | + } else { |
293 | + dec->rd = operand_rd(inst); | 179 | + qemu_log_mask(LOG_GUEST_ERROR, |
294 | + dec->rs1 = operand_rs1(inst); | 180 | + "aclint-mtimer: invalid time_hi write: %08x", |
295 | + dec->rnum = operand_rnum(inst); | 181 | + (uint32_t)addr); |
296 | + break; | 182 | + return; |
297 | }; | 183 | + } |
184 | + } | ||
185 | + | ||
186 | + /* Check if timer interrupt is triggered for each hart. */ | ||
187 | + for (i = 0; i < mtimer->num_harts; i++) { | ||
188 | + CPUState *cpu = qemu_get_cpu(mtimer->hartid_base + i); | ||
189 | + CPURISCVState *env = cpu ? cpu->env_ptr : NULL; | ||
190 | + if (!env) { | ||
191 | + continue; | ||
192 | + } | ||
193 | + riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), | ||
194 | + i, env->timecmp); | ||
195 | + } | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | @@ -XXX,XX +XXX,XX @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, | ||
200 | continue; | ||
201 | } | ||
202 | if (provide_rdtime) { | ||
203 | - riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq); | ||
204 | + riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev); | ||
205 | } | ||
206 | |||
207 | cb->s = RISCV_ACLINT_MTIMER(dev); | ||
208 | diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c | ||
209 | index XXXXXXX..XXXXXXX 100644 | ||
210 | --- a/target/riscv/cpu_helper.c | ||
211 | +++ b/target/riscv/cpu_helper.c | ||
212 | @@ -XXX,XX +XXX,XX @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t mask, uint64_t value) | ||
213 | return old; | ||
298 | } | 214 | } |
299 | 215 | ||
300 | @@ -XXX,XX +XXX,XX @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec) | 216 | -void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(uint32_t), |
301 | case ')': | 217 | - uint32_t arg) |
302 | append(buf, ")", buflen); | 218 | +void riscv_cpu_set_rdtime_fn(CPURISCVState *env, uint64_t (*fn)(void *), |
303 | break; | 219 | + void *arg) |
304 | + case 'b': | 220 | { |
305 | + snprintf(tmp, sizeof(tmp), "%d", dec->bs); | 221 | env->rdtime_fn = fn; |
306 | + append(buf, tmp, buflen); | 222 | env->rdtime_fn_arg = arg; |
307 | + break; | ||
308 | + case 'n': | ||
309 | + snprintf(tmp, sizeof(tmp), "%d", dec->rnum); | ||
310 | + append(buf, tmp, buflen); | ||
311 | + break; | ||
312 | case '0': | ||
313 | append(buf, rv_ireg_name_sym[dec->rd], buflen); | ||
314 | break; | ||
315 | -- | 223 | -- |
316 | 2.35.1 | 224 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Alistair Francis <alistair.francis@wdc.com> | 1 | From: Jim Shu <jim.shu@sifive.com> |
---|---|---|---|
2 | 2 | ||
3 | Add support for plugging in devices, this was tested with the TPM | 3 | This commit implements reset function of all ACLINT devices. |
4 | device. | 4 | ACLINT device reset will clear MTIME and MSIP register to 0. |
5 | 5 | ||
6 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 6 | Depend on RISC-V ACLINT spec v1.0-rc4: |
7 | Reviewed-by: Edgar E. Iglesias <edgar.iglesias@amd.com> | 7 | https://github.com/riscv/riscv-aclint/blob/v1.0-rc4/riscv-aclint.adoc |
8 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 8 | |
9 | Message-Id: <20220427234146.1130752-6-alistair.francis@opensource.wdc.com> | 9 | Signed-off-by: Jim Shu <jim.shu@sifive.com> |
10 | Reviewed-by: Frank Chang <frank.chang@sifive.com> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
12 | Message-Id: <20220420080901.14655-5-frank.chang@sifive.com> | ||
10 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 13 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
11 | --- | 14 | --- |
12 | hw/riscv/virt.c | 35 +++++++++++++++++++++++++++++++++++ | 15 | hw/intc/riscv_aclint.c | 39 +++++++++++++++++++++++++++++++++++++++ |
13 | 1 file changed, 35 insertions(+) | 16 | 1 file changed, 39 insertions(+) |
14 | 17 | ||
15 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | 18 | diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c |
16 | index XXXXXXX..XXXXXXX 100644 | 19 | index XXXXXXX..XXXXXXX 100644 |
17 | --- a/hw/riscv/virt.c | 20 | --- a/hw/intc/riscv_aclint.c |
18 | +++ b/hw/riscv/virt.c | 21 | +++ b/hw/intc/riscv_aclint.c |
19 | @@ -XXX,XX +XXX,XX @@ static void virt_set_aclint(Object *obj, bool value, Error **errp) | 22 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) |
20 | s->have_aclint = value; | 23 | } |
21 | } | 24 | } |
22 | 25 | ||
23 | +static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, | 26 | +static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type) |
24 | + DeviceState *dev) | ||
25 | +{ | 27 | +{ |
26 | + MachineClass *mc = MACHINE_GET_CLASS(machine); | 28 | + /* |
29 | + * According to RISC-V ACLINT spec: | ||
30 | + * - On MTIMER device reset, the MTIME register is cleared to zero. | ||
31 | + * - On MTIMER device reset, the MTIMECMP registers are in unknown state. | ||
32 | + */ | ||
33 | + RISCVAclintMTimerState *mtimer = RISCV_ACLINT_MTIMER(obj); | ||
27 | + | 34 | + |
28 | + if (device_is_dynamic_sysbus(mc, dev)) { | 35 | + /* |
29 | + return HOTPLUG_HANDLER(machine); | 36 | + * Clear mtime register by writing to 0 it. |
30 | + } | 37 | + * Pending mtime interrupts will also be cleared at the same time. |
31 | + return NULL; | 38 | + */ |
39 | + riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8); | ||
32 | +} | 40 | +} |
33 | + | 41 | + |
34 | +static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, | 42 | static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) |
35 | + DeviceState *dev, Error **errp) | 43 | { |
44 | DeviceClass *dc = DEVICE_CLASS(klass); | ||
45 | dc->realize = riscv_aclint_mtimer_realize; | ||
46 | device_class_set_props(dc, riscv_aclint_mtimer_properties); | ||
47 | + ResettableClass *rc = RESETTABLE_CLASS(klass); | ||
48 | + rc->phases.enter = riscv_aclint_mtimer_reset_enter; | ||
49 | } | ||
50 | |||
51 | static const TypeInfo riscv_aclint_mtimer_info = { | ||
52 | @@ -XXX,XX +XXX,XX @@ static void riscv_aclint_swi_realize(DeviceState *dev, Error **errp) | ||
53 | } | ||
54 | } | ||
55 | |||
56 | +static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type) | ||
36 | +{ | 57 | +{ |
37 | + RISCVVirtState *s = RISCV_VIRT_MACHINE(hotplug_dev); | 58 | + /* |
59 | + * According to RISC-V ACLINT spec: | ||
60 | + * - On MSWI device reset, each MSIP register is cleared to zero. | ||
61 | + * | ||
62 | + * p.s. SSWI device reset does nothing since SETSIP register always reads 0. | ||
63 | + */ | ||
64 | + RISCVAclintSwiState *swi = RISCV_ACLINT_SWI(obj); | ||
65 | + int i; | ||
38 | + | 66 | + |
39 | + if (s->platform_bus_dev) { | 67 | + if (!swi->sswi) { |
40 | + MachineClass *mc = MACHINE_GET_CLASS(s); | 68 | + for (i = 0; i < swi->num_harts; i++) { |
41 | + | 69 | + /* Clear MSIP registers by lowering software interrupts. */ |
42 | + if (device_is_dynamic_sysbus(mc, dev)) { | 70 | + qemu_irq_lower(swi->soft_irqs[i]); |
43 | + platform_bus_link_device(PLATFORM_BUS_DEVICE(s->platform_bus_dev), | ||
44 | + SYS_BUS_DEVICE(dev)); | ||
45 | + } | 71 | + } |
46 | + } | 72 | + } |
47 | +} | 73 | +} |
48 | + | 74 | + |
49 | static void virt_machine_class_init(ObjectClass *oc, void *data) | 75 | static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data) |
50 | { | 76 | { |
51 | char str[128]; | 77 | DeviceClass *dc = DEVICE_CLASS(klass); |
52 | MachineClass *mc = MACHINE_CLASS(oc); | 78 | dc->realize = riscv_aclint_swi_realize; |
53 | + HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); | 79 | device_class_set_props(dc, riscv_aclint_swi_properties); |
54 | 80 | + ResettableClass *rc = RESETTABLE_CLASS(klass); | |
55 | mc->desc = "RISC-V VirtIO board"; | 81 | + rc->phases.enter = riscv_aclint_swi_reset_enter; |
56 | mc->init = virt_machine_init; | 82 | } |
57 | @@ -XXX,XX +XXX,XX @@ static void virt_machine_class_init(ObjectClass *oc, void *data) | 83 | |
58 | mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id; | 84 | static const TypeInfo riscv_aclint_swi_info = { |
59 | mc->numa_mem_supported = true; | ||
60 | mc->default_ram_id = "riscv_virt_board.ram"; | ||
61 | + assert(!mc->get_hotplug_handler); | ||
62 | + mc->get_hotplug_handler = virt_machine_get_hotplug_handler; | ||
63 | + | ||
64 | + hc->plug = virt_machine_device_plug_cb; | ||
65 | |||
66 | machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); | ||
67 | |||
68 | @@ -XXX,XX +XXX,XX @@ static const TypeInfo virt_machine_typeinfo = { | ||
69 | .class_init = virt_machine_class_init, | ||
70 | .instance_init = virt_machine_instance_init, | ||
71 | .instance_size = sizeof(RISCVVirtState), | ||
72 | + .interfaces = (InterfaceInfo[]) { | ||
73 | + { TYPE_HOTPLUG_HANDLER }, | ||
74 | + { } | ||
75 | + }, | ||
76 | }; | ||
77 | |||
78 | static void virt_machine_init_register_types(void) | ||
79 | -- | 85 | -- |
80 | 2.35.1 | 86 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Bin Meng <bin.meng@windriver.com> |
---|---|---|---|
2 | 2 | ||
3 | - add aes64dsm, aes64ds, aes64im, aes64es, aes64esm, aes64ks2, aes64ks1i instructions | 3 | Implement .debug_excp_handler, .debug_check_{breakpoint, watchpoint} |
4 | TCGCPUOps and hook them into riscv_tcg_ops. | ||
4 | 5 | ||
5 | Co-authored-by: Ruibo Lu <luruibo2000@163.com> | 6 | Signed-off-by: Bin Meng <bin.meng@windriver.com> |
6 | Co-authored-by: Zewen Ye <lustrew@foxmail.com> | 7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
7 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 8 | Message-Id: <20220421003324.1134983-2-bmeng.cn@gmail.com> |
8 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | ||
9 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
10 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | ||
11 | Message-Id: <20220423023510.30794-8-liweiwei@iscas.ac.cn> | ||
12 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
13 | --- | 10 | --- |
14 | target/riscv/helper.h | 8 ++ | 11 | target/riscv/debug.h | 4 +++ |
15 | target/riscv/insn32.decode | 12 ++ | 12 | target/riscv/cpu.c | 3 ++ |
16 | target/riscv/crypto_helper.c | 169 ++++++++++++++++++++++++ | 13 | target/riscv/debug.c | 75 ++++++++++++++++++++++++++++++++++++++++++++ |
17 | target/riscv/insn_trans/trans_rvk.c.inc | 54 ++++++++ | 14 | 3 files changed, 82 insertions(+) |
18 | 4 files changed, 243 insertions(+) | ||
19 | 15 | ||
20 | diff --git a/target/riscv/helper.h b/target/riscv/helper.h | 16 | diff --git a/target/riscv/debug.h b/target/riscv/debug.h |
21 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
22 | --- a/target/riscv/helper.h | 18 | --- a/target/riscv/debug.h |
23 | +++ b/target/riscv/helper.h | 19 | +++ b/target/riscv/debug.h |
24 | @@ -XXX,XX +XXX,XX @@ DEF_HELPER_FLAGS_3(aes32esmi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 20 | @@ -XXX,XX +XXX,XX @@ void tselect_csr_write(CPURISCVState *env, target_ulong val); |
25 | DEF_HELPER_FLAGS_3(aes32esi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 21 | target_ulong tdata_csr_read(CPURISCVState *env, int tdata_index); |
26 | DEF_HELPER_FLAGS_3(aes32dsmi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 22 | void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val); |
27 | DEF_HELPER_FLAGS_3(aes32dsi, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl) | 23 | |
24 | +void riscv_cpu_debug_excp_handler(CPUState *cs); | ||
25 | +bool riscv_cpu_debug_check_breakpoint(CPUState *cs); | ||
26 | +bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp); | ||
28 | + | 27 | + |
29 | +DEF_HELPER_FLAGS_2(aes64esm, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 28 | #endif /* RISCV_DEBUG_H */ |
30 | +DEF_HELPER_FLAGS_2(aes64es, TCG_CALL_NO_RWG_SE, tl, tl, tl) | 29 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
31 | +DEF_HELPER_FLAGS_2(aes64ds, TCG_CALL_NO_RWG_SE, tl, tl, tl) | ||
32 | +DEF_HELPER_FLAGS_2(aes64dsm, TCG_CALL_NO_RWG_SE, tl, tl, tl) | ||
33 | +DEF_HELPER_FLAGS_2(aes64ks2, TCG_CALL_NO_RWG_SE, tl, tl, tl) | ||
34 | +DEF_HELPER_FLAGS_2(aes64ks1i, TCG_CALL_NO_RWG_SE, tl, tl, tl) | ||
35 | +DEF_HELPER_FLAGS_1(aes64im, TCG_CALL_NO_RWG_SE, tl, tl) | ||
36 | diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode | ||
37 | index XXXXXXX..XXXXXXX 100644 | 30 | index XXXXXXX..XXXXXXX 100644 |
38 | --- a/target/riscv/insn32.decode | 31 | --- a/target/riscv/cpu.c |
39 | +++ b/target/riscv/insn32.decode | 32 | +++ b/target/riscv/cpu.c |
40 | @@ -XXX,XX +XXX,XX @@ | 33 | @@ -XXX,XX +XXX,XX @@ static const struct TCGCPUOps riscv_tcg_ops = { |
41 | %imm_j 31:s1 12:8 20:1 21:10 !function=ex_shift_1 | 34 | .do_interrupt = riscv_cpu_do_interrupt, |
42 | %imm_u 12:s20 !function=ex_shift_12 | 35 | .do_transaction_failed = riscv_cpu_do_transaction_failed, |
43 | %imm_bs 30:2 !function=ex_shift_3 | 36 | .do_unaligned_access = riscv_cpu_do_unaligned_access, |
44 | +%imm_rnum 20:4 | 37 | + .debug_excp_handler = riscv_cpu_debug_excp_handler, |
45 | 38 | + .debug_check_breakpoint = riscv_cpu_debug_check_breakpoint, | |
46 | # Argument sets: | 39 | + .debug_check_watchpoint = riscv_cpu_debug_check_watchpoint, |
47 | &empty | 40 | #endif /* !CONFIG_USER_ONLY */ |
48 | @@ -XXX,XX +XXX,XX @@ | 41 | }; |
49 | @sfence_vm ....... ..... ..... ... ..... ....... %rs1 | 42 | |
50 | 43 | diff --git a/target/riscv/debug.c b/target/riscv/debug.c | |
51 | @k_aes .. ..... ..... ..... ... ..... ....... &k_aes shamt=%imm_bs %rs2 %rs1 %rd | ||
52 | +@i_aes .. ..... ..... ..... ... ..... ....... &i imm=%imm_rnum %rs1 %rd | ||
53 | |||
54 | # Formats 64: | ||
55 | @sh5 ....... ..... ..... ... ..... ....... &shift shamt=%sh5 %rs1 %rd | ||
56 | @@ -XXX,XX +XXX,XX @@ hinval_gvma 0110011 ..... ..... 000 00000 1110011 @hfence_gvma | ||
57 | # *** RV32 Zknd Standard Extension *** | ||
58 | aes32dsmi .. 10111 ..... ..... 000 ..... 0110011 @k_aes | ||
59 | aes32dsi .. 10101 ..... ..... 000 ..... 0110011 @k_aes | ||
60 | +# *** RV64 Zknd Standard Extension *** | ||
61 | +aes64dsm 00 11111 ..... ..... 000 ..... 0110011 @r | ||
62 | +aes64ds 00 11101 ..... ..... 000 ..... 0110011 @r | ||
63 | +aes64im 00 11000 00000 ..... 001 ..... 0010011 @r2 | ||
64 | # *** RV32 Zkne Standard Extension *** | ||
65 | aes32esmi .. 10011 ..... ..... 000 ..... 0110011 @k_aes | ||
66 | aes32esi .. 10001 ..... ..... 000 ..... 0110011 @k_aes | ||
67 | +# *** RV64 Zkne Standard Extension *** | ||
68 | +aes64es 00 11001 ..... ..... 000 ..... 0110011 @r | ||
69 | +aes64esm 00 11011 ..... ..... 000 ..... 0110011 @r | ||
70 | +# *** RV64 Zkne/zknd Standard Extension *** | ||
71 | +aes64ks2 01 11111 ..... ..... 000 ..... 0110011 @r | ||
72 | +aes64ks1i 00 11000 1.... ..... 001 ..... 0010011 @i_aes | ||
73 | diff --git a/target/riscv/crypto_helper.c b/target/riscv/crypto_helper.c | ||
74 | index XXXXXXX..XXXXXXX 100644 | 44 | index XXXXXXX..XXXXXXX 100644 |
75 | --- a/target/riscv/crypto_helper.c | 45 | --- a/target/riscv/debug.c |
76 | +++ b/target/riscv/crypto_helper.c | 46 | +++ b/target/riscv/debug.c |
77 | @@ -XXX,XX +XXX,XX @@ target_ulong HELPER(aes32dsi)(target_ulong rs1, target_ulong rs2, | 47 | @@ -XXX,XX +XXX,XX @@ void tdata_csr_write(CPURISCVState *env, int tdata_index, target_ulong val) |
78 | { | 48 | |
79 | return aes32_operation(shamt, rs1, rs2, false, false); | 49 | return write_func(env, env->trigger_cur, tdata_index, val); |
80 | } | 50 | } |
81 | + | 51 | + |
82 | +#define BY(X, I) ((X >> (8 * I)) & 0xFF) | 52 | +void riscv_cpu_debug_excp_handler(CPUState *cs) |
53 | +{ | ||
54 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
55 | + CPURISCVState *env = &cpu->env; | ||
83 | + | 56 | + |
84 | +#define AES_SHIFROWS_LO(RS1, RS2) ( \ | 57 | + if (cs->watchpoint_hit) { |
85 | + (((RS1 >> 24) & 0xFF) << 56) | (((RS2 >> 48) & 0xFF) << 48) | \ | 58 | + if (cs->watchpoint_hit->flags & BP_CPU) { |
86 | + (((RS2 >> 8) & 0xFF) << 40) | (((RS1 >> 32) & 0xFF) << 32) | \ | 59 | + cs->watchpoint_hit = NULL; |
87 | + (((RS2 >> 56) & 0xFF) << 24) | (((RS2 >> 16) & 0xFF) << 16) | \ | 60 | + riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0); |
88 | + (((RS1 >> 40) & 0xFF) << 8) | (((RS1 >> 0) & 0xFF) << 0)) | ||
89 | + | ||
90 | +#define AES_INVSHIFROWS_LO(RS1, RS2) ( \ | ||
91 | + (((RS2 >> 24) & 0xFF) << 56) | (((RS2 >> 48) & 0xFF) << 48) | \ | ||
92 | + (((RS1 >> 8) & 0xFF) << 40) | (((RS1 >> 32) & 0xFF) << 32) | \ | ||
93 | + (((RS1 >> 56) & 0xFF) << 24) | (((RS2 >> 16) & 0xFF) << 16) | \ | ||
94 | + (((RS2 >> 40) & 0xFF) << 8) | (((RS1 >> 0) & 0xFF) << 0)) | ||
95 | + | ||
96 | +#define AES_MIXBYTE(COL, B0, B1, B2, B3) ( \ | ||
97 | + BY(COL, B3) ^ BY(COL, B2) ^ AES_GFMUL(BY(COL, B1), 3) ^ \ | ||
98 | + AES_GFMUL(BY(COL, B0), 2)) | ||
99 | + | ||
100 | +#define AES_MIXCOLUMN(COL) ( \ | ||
101 | + AES_MIXBYTE(COL, 3, 0, 1, 2) << 24 | \ | ||
102 | + AES_MIXBYTE(COL, 2, 3, 0, 1) << 16 | \ | ||
103 | + AES_MIXBYTE(COL, 1, 2, 3, 0) << 8 | AES_MIXBYTE(COL, 0, 1, 2, 3) << 0) | ||
104 | + | ||
105 | +#define AES_INVMIXBYTE(COL, B0, B1, B2, B3) ( \ | ||
106 | + AES_GFMUL(BY(COL, B3), 0x9) ^ AES_GFMUL(BY(COL, B2), 0xd) ^ \ | ||
107 | + AES_GFMUL(BY(COL, B1), 0xb) ^ AES_GFMUL(BY(COL, B0), 0xe)) | ||
108 | + | ||
109 | +#define AES_INVMIXCOLUMN(COL) ( \ | ||
110 | + AES_INVMIXBYTE(COL, 3, 0, 1, 2) << 24 | \ | ||
111 | + AES_INVMIXBYTE(COL, 2, 3, 0, 1) << 16 | \ | ||
112 | + AES_INVMIXBYTE(COL, 1, 2, 3, 0) << 8 | \ | ||
113 | + AES_INVMIXBYTE(COL, 0, 1, 2, 3) << 0) | ||
114 | + | ||
115 | +static inline target_ulong aes64_operation(target_ulong rs1, target_ulong rs2, | ||
116 | + bool enc, bool mix) | ||
117 | +{ | ||
118 | + uint64_t RS1 = rs1; | ||
119 | + uint64_t RS2 = rs2; | ||
120 | + uint64_t result; | ||
121 | + uint64_t temp; | ||
122 | + uint32_t col_0; | ||
123 | + uint32_t col_1; | ||
124 | + | ||
125 | + if (enc) { | ||
126 | + temp = AES_SHIFROWS_LO(RS1, RS2); | ||
127 | + temp = (((uint64_t)AES_sbox[(temp >> 0) & 0xFF] << 0) | | ||
128 | + ((uint64_t)AES_sbox[(temp >> 8) & 0xFF] << 8) | | ||
129 | + ((uint64_t)AES_sbox[(temp >> 16) & 0xFF] << 16) | | ||
130 | + ((uint64_t)AES_sbox[(temp >> 24) & 0xFF] << 24) | | ||
131 | + ((uint64_t)AES_sbox[(temp >> 32) & 0xFF] << 32) | | ||
132 | + ((uint64_t)AES_sbox[(temp >> 40) & 0xFF] << 40) | | ||
133 | + ((uint64_t)AES_sbox[(temp >> 48) & 0xFF] << 48) | | ||
134 | + ((uint64_t)AES_sbox[(temp >> 56) & 0xFF] << 56)); | ||
135 | + if (mix) { | ||
136 | + col_0 = temp & 0xFFFFFFFF; | ||
137 | + col_1 = temp >> 32; | ||
138 | + | ||
139 | + col_0 = AES_MIXCOLUMN(col_0); | ||
140 | + col_1 = AES_MIXCOLUMN(col_1); | ||
141 | + | ||
142 | + result = ((uint64_t)col_1 << 32) | col_0; | ||
143 | + } else { | ||
144 | + result = temp; | ||
145 | + } | 61 | + } |
146 | + } else { | 62 | + } else { |
147 | + temp = AES_INVSHIFROWS_LO(RS1, RS2); | 63 | + if (cpu_breakpoint_test(cs, env->pc, BP_CPU)) { |
148 | + temp = (((uint64_t)AES_isbox[(temp >> 0) & 0xFF] << 0) | | 64 | + riscv_raise_exception(env, RISCV_EXCP_BREAKPOINT, 0); |
149 | + ((uint64_t)AES_isbox[(temp >> 8) & 0xFF] << 8) | | 65 | + } |
150 | + ((uint64_t)AES_isbox[(temp >> 16) & 0xFF] << 16) | | 66 | + } |
151 | + ((uint64_t)AES_isbox[(temp >> 24) & 0xFF] << 24) | | 67 | +} |
152 | + ((uint64_t)AES_isbox[(temp >> 32) & 0xFF] << 32) | | ||
153 | + ((uint64_t)AES_isbox[(temp >> 40) & 0xFF] << 40) | | ||
154 | + ((uint64_t)AES_isbox[(temp >> 48) & 0xFF] << 48) | | ||
155 | + ((uint64_t)AES_isbox[(temp >> 56) & 0xFF] << 56)); | ||
156 | + if (mix) { | ||
157 | + col_0 = temp & 0xFFFFFFFF; | ||
158 | + col_1 = temp >> 32; | ||
159 | + | 68 | + |
160 | + col_0 = AES_INVMIXCOLUMN(col_0); | 69 | +bool riscv_cpu_debug_check_breakpoint(CPUState *cs) |
161 | + col_1 = AES_INVMIXCOLUMN(col_1); | 70 | +{ |
71 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
72 | + CPURISCVState *env = &cpu->env; | ||
73 | + CPUBreakpoint *bp; | ||
74 | + target_ulong ctrl; | ||
75 | + target_ulong pc; | ||
76 | + int i; | ||
162 | + | 77 | + |
163 | + result = ((uint64_t)col_1 << 32) | col_0; | 78 | + QTAILQ_FOREACH(bp, &cs->breakpoints, entry) { |
164 | + } else { | 79 | + for (i = 0; i < TRIGGER_TYPE2_NUM; i++) { |
165 | + result = temp; | 80 | + ctrl = env->type2_trig[i].mcontrol; |
81 | + pc = env->type2_trig[i].maddress; | ||
82 | + | ||
83 | + if ((ctrl & TYPE2_EXEC) && (bp->pc == pc)) { | ||
84 | + /* check U/S/M bit against current privilege level */ | ||
85 | + if ((ctrl >> 3) & BIT(env->priv)) { | ||
86 | + return true; | ||
87 | + } | ||
88 | + } | ||
166 | + } | 89 | + } |
167 | + } | 90 | + } |
168 | + | 91 | + |
169 | + return result; | 92 | + return false; |
170 | +} | 93 | +} |
171 | + | 94 | + |
172 | +target_ulong HELPER(aes64esm)(target_ulong rs1, target_ulong rs2) | 95 | +bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) |
173 | +{ | 96 | +{ |
174 | + return aes64_operation(rs1, rs2, true, true); | 97 | + RISCVCPU *cpu = RISCV_CPU(cs); |
175 | +} | 98 | + CPURISCVState *env = &cpu->env; |
99 | + target_ulong ctrl; | ||
100 | + target_ulong addr; | ||
101 | + int flags; | ||
102 | + int i; | ||
176 | + | 103 | + |
177 | +target_ulong HELPER(aes64es)(target_ulong rs1, target_ulong rs2) | 104 | + for (i = 0; i < TRIGGER_TYPE2_NUM; i++) { |
178 | +{ | 105 | + ctrl = env->type2_trig[i].mcontrol; |
179 | + return aes64_operation(rs1, rs2, true, false); | 106 | + addr = env->type2_trig[i].maddress; |
180 | +} | 107 | + flags = 0; |
181 | + | 108 | + |
182 | +target_ulong HELPER(aes64ds)(target_ulong rs1, target_ulong rs2) | 109 | + if (ctrl & TYPE2_LOAD) { |
183 | +{ | 110 | + flags |= BP_MEM_READ; |
184 | + return aes64_operation(rs1, rs2, false, false); | 111 | + } |
185 | +} | 112 | + if (ctrl & TYPE2_STORE) { |
113 | + flags |= BP_MEM_WRITE; | ||
114 | + } | ||
186 | + | 115 | + |
187 | +target_ulong HELPER(aes64dsm)(target_ulong rs1, target_ulong rs2) | 116 | + if ((wp->flags & flags) && (wp->vaddr == addr)) { |
188 | +{ | 117 | + /* check U/S/M bit against current privilege level */ |
189 | + return aes64_operation(rs1, rs2, false, true); | 118 | + if ((ctrl >> 3) & BIT(env->priv)) { |
190 | +} | 119 | + return true; |
191 | + | 120 | + } |
192 | +target_ulong HELPER(aes64ks2)(target_ulong rs1, target_ulong rs2) | 121 | + } |
193 | +{ | ||
194 | + uint64_t RS1 = rs1; | ||
195 | + uint64_t RS2 = rs2; | ||
196 | + uint32_t rs1_hi = RS1 >> 32; | ||
197 | + uint32_t rs2_lo = RS2; | ||
198 | + uint32_t rs2_hi = RS2 >> 32; | ||
199 | + | ||
200 | + uint32_t r_lo = (rs1_hi ^ rs2_lo); | ||
201 | + uint32_t r_hi = (rs1_hi ^ rs2_lo ^ rs2_hi); | ||
202 | + target_ulong result = ((uint64_t)r_hi << 32) | r_lo; | ||
203 | + | ||
204 | + return result; | ||
205 | +} | ||
206 | + | ||
207 | +target_ulong HELPER(aes64ks1i)(target_ulong rs1, target_ulong rnum) | ||
208 | +{ | ||
209 | + uint64_t RS1 = rs1; | ||
210 | + static const uint8_t round_consts[10] = { | ||
211 | + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 | ||
212 | + }; | ||
213 | + | ||
214 | + uint8_t enc_rnum = rnum; | ||
215 | + uint32_t temp = (RS1 >> 32) & 0xFFFFFFFF; | ||
216 | + uint8_t rcon_ = 0; | ||
217 | + target_ulong result; | ||
218 | + | ||
219 | + if (enc_rnum != 0xA) { | ||
220 | + temp = ror32(temp, 8); /* Rotate right by 8 */ | ||
221 | + rcon_ = round_consts[enc_rnum]; | ||
222 | + } | 122 | + } |
223 | + | 123 | + |
224 | + temp = ((uint32_t)AES_sbox[(temp >> 24) & 0xFF] << 24) | | 124 | + return false; |
225 | + ((uint32_t)AES_sbox[(temp >> 16) & 0xFF] << 16) | | ||
226 | + ((uint32_t)AES_sbox[(temp >> 8) & 0xFF] << 8) | | ||
227 | + ((uint32_t)AES_sbox[(temp >> 0) & 0xFF] << 0); | ||
228 | + | ||
229 | + temp ^= rcon_; | ||
230 | + | ||
231 | + result = ((uint64_t)temp << 32) | temp; | ||
232 | + | ||
233 | + return result; | ||
234 | +} | ||
235 | + | ||
236 | +target_ulong HELPER(aes64im)(target_ulong rs1) | ||
237 | +{ | ||
238 | + uint64_t RS1 = rs1; | ||
239 | + uint32_t col_0 = RS1 & 0xFFFFFFFF; | ||
240 | + uint32_t col_1 = RS1 >> 32; | ||
241 | + target_ulong result; | ||
242 | + | ||
243 | + col_0 = AES_INVMIXCOLUMN(col_0); | ||
244 | + col_1 = AES_INVMIXCOLUMN(col_1); | ||
245 | + | ||
246 | + result = ((uint64_t)col_1 << 32) | col_0; | ||
247 | + | ||
248 | + return result; | ||
249 | +} | ||
250 | #undef sext32_xlen | ||
251 | diff --git a/target/riscv/insn_trans/trans_rvk.c.inc b/target/riscv/insn_trans/trans_rvk.c.inc | ||
252 | index XXXXXXX..XXXXXXX 100644 | ||
253 | --- a/target/riscv/insn_trans/trans_rvk.c.inc | ||
254 | +++ b/target/riscv/insn_trans/trans_rvk.c.inc | ||
255 | @@ -XXX,XX +XXX,XX @@ static bool trans_aes32dsi(DisasContext *ctx, arg_aes32dsi *a) | ||
256 | REQUIRE_ZKND(ctx); | ||
257 | return gen_aes32_sm4(ctx, a, gen_helper_aes32dsi); | ||
258 | } | ||
259 | + | ||
260 | +static bool trans_aes64es(DisasContext *ctx, arg_aes64es *a) | ||
261 | +{ | ||
262 | + REQUIRE_64BIT(ctx); | ||
263 | + REQUIRE_ZKNE(ctx); | ||
264 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_aes64es, NULL); | ||
265 | +} | ||
266 | + | ||
267 | +static bool trans_aes64esm(DisasContext *ctx, arg_aes64esm *a) | ||
268 | +{ | ||
269 | + REQUIRE_64BIT(ctx); | ||
270 | + REQUIRE_ZKNE(ctx); | ||
271 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_aes64esm, NULL); | ||
272 | +} | ||
273 | + | ||
274 | +static bool trans_aes64ds(DisasContext *ctx, arg_aes64ds *a) | ||
275 | +{ | ||
276 | + REQUIRE_64BIT(ctx); | ||
277 | + REQUIRE_ZKND(ctx); | ||
278 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_aes64ds, NULL); | ||
279 | +} | ||
280 | + | ||
281 | +static bool trans_aes64dsm(DisasContext *ctx, arg_aes64dsm *a) | ||
282 | +{ | ||
283 | + REQUIRE_64BIT(ctx); | ||
284 | + REQUIRE_ZKND(ctx); | ||
285 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_aes64dsm, NULL); | ||
286 | +} | ||
287 | + | ||
288 | +static bool trans_aes64ks2(DisasContext *ctx, arg_aes64ks2 *a) | ||
289 | +{ | ||
290 | + REQUIRE_64BIT(ctx); | ||
291 | + REQUIRE_EITHER_EXT(ctx, zknd, zkne); | ||
292 | + return gen_arith(ctx, a, EXT_NONE, gen_helper_aes64ks2, NULL); | ||
293 | +} | ||
294 | + | ||
295 | +static bool trans_aes64ks1i(DisasContext *ctx, arg_aes64ks1i *a) | ||
296 | +{ | ||
297 | + REQUIRE_64BIT(ctx); | ||
298 | + REQUIRE_EITHER_EXT(ctx, zknd, zkne); | ||
299 | + | ||
300 | + if (a->imm > 0xA) { | ||
301 | + return false; | ||
302 | + } | ||
303 | + | ||
304 | + return gen_arith_imm_tl(ctx, a, EXT_NONE, gen_helper_aes64ks1i, NULL); | ||
305 | +} | ||
306 | + | ||
307 | +static bool trans_aes64im(DisasContext *ctx, arg_aes64im *a) | ||
308 | +{ | ||
309 | + REQUIRE_64BIT(ctx); | ||
310 | + REQUIRE_ZKND(ctx); | ||
311 | + return gen_unary(ctx, a, EXT_NONE, gen_helper_aes64im); | ||
312 | +} | 125 | +} |
313 | -- | 126 | -- |
314 | 2.35.1 | 127 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Bin Meng <bin.meng@windriver.com> |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 3 | Add a config option to enable support for native M-mode debug. |
4 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 4 | This is disabled by default and can be enabled with 'debug=true'. |
5 | Acked-by: Alistair Francis <alistair.francis@wdc.com> | 5 | |
6 | Message-Id: <20220423023510.30794-2-liweiwei@iscas.ac.cn> | 6 | Signed-off-by: Bin Meng <bin.meng@windriver.com> |
7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | ||
8 | Message-Id: <20220421003324.1134983-3-bmeng.cn@gmail.com> | ||
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
8 | --- | 10 | --- |
9 | target/riscv/cpu.h | 13 +++++++++++++ | 11 | target/riscv/cpu.h | 4 +++- |
10 | target/riscv/cpu.c | 23 +++++++++++++++++++++++ | 12 | target/riscv/cpu.c | 5 +++++ |
11 | 2 files changed, 36 insertions(+) | 13 | 2 files changed, 8 insertions(+), 1 deletion(-) |
12 | 14 | ||
13 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 15 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h |
14 | index XXXXXXX..XXXXXXX 100644 | 16 | index XXXXXXX..XXXXXXX 100644 |
15 | --- a/target/riscv/cpu.h | 17 | --- a/target/riscv/cpu.h |
16 | +++ b/target/riscv/cpu.h | 18 | +++ b/target/riscv/cpu.h |
19 | @@ -XXX,XX +XXX,XX @@ enum { | ||
20 | RISCV_FEATURE_PMP, | ||
21 | RISCV_FEATURE_EPMP, | ||
22 | RISCV_FEATURE_MISA, | ||
23 | - RISCV_FEATURE_AIA | ||
24 | + RISCV_FEATURE_AIA, | ||
25 | + RISCV_FEATURE_DEBUG | ||
26 | }; | ||
27 | |||
28 | /* Privileged specification version */ | ||
17 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | 29 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { |
18 | bool ext_zba; | 30 | bool pmp; |
19 | bool ext_zbb; | 31 | bool epmp; |
20 | bool ext_zbc; | 32 | bool aia; |
21 | + bool ext_zbkb; | 33 | + bool debug; |
22 | + bool ext_zbkc; | 34 | uint64_t resetvec; |
23 | + bool ext_zbkx; | 35 | }; |
24 | bool ext_zbs; | 36 | |
25 | + bool ext_zk; | ||
26 | + bool ext_zkn; | ||
27 | + bool ext_zknd; | ||
28 | + bool ext_zkne; | ||
29 | + bool ext_zknh; | ||
30 | + bool ext_zkr; | ||
31 | + bool ext_zks; | ||
32 | + bool ext_zksed; | ||
33 | + bool ext_zksh; | ||
34 | + bool ext_zkt; | ||
35 | bool ext_counters; | ||
36 | bool ext_ifencei; | ||
37 | bool ext_icsr; | ||
38 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 37 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
39 | index XXXXXXX..XXXXXXX 100644 | 38 | index XXXXXXX..XXXXXXX 100644 |
40 | --- a/target/riscv/cpu.c | 39 | --- a/target/riscv/cpu.c |
41 | +++ b/target/riscv/cpu.c | 40 | +++ b/target/riscv/cpu.c |
42 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) | 41 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp) |
43 | cpu->cfg.ext_zfinx = true; | 42 | riscv_set_feature(env, RISCV_FEATURE_AIA); |
44 | } | 43 | } |
45 | 44 | ||
46 | + if (cpu->cfg.ext_zk) { | 45 | + if (cpu->cfg.debug) { |
47 | + cpu->cfg.ext_zkn = true; | 46 | + riscv_set_feature(env, RISCV_FEATURE_DEBUG); |
48 | + cpu->cfg.ext_zkr = true; | 47 | + } |
49 | + cpu->cfg.ext_zkt = true; | ||
50 | + } | ||
51 | + | 48 | + |
52 | + if (cpu->cfg.ext_zkn) { | 49 | set_resetvec(env, cpu->cfg.resetvec); |
53 | + cpu->cfg.ext_zbkb = true; | 50 | |
54 | + cpu->cfg.ext_zbkc = true; | 51 | /* Validate that MISA_MXL is set properly. */ |
55 | + cpu->cfg.ext_zbkx = true; | 52 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { |
56 | + cpu->cfg.ext_zkne = true; | 53 | DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false), |
57 | + cpu->cfg.ext_zknd = true; | 54 | DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), |
58 | + cpu->cfg.ext_zknh = true; | 55 | DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), |
59 | + } | 56 | + DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false), |
60 | + | 57 | |
61 | + if (cpu->cfg.ext_zks) { | 58 | DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), |
62 | + cpu->cfg.ext_zbkb = true; | 59 | DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), |
63 | + cpu->cfg.ext_zbkc = true; | ||
64 | + cpu->cfg.ext_zbkx = true; | ||
65 | + cpu->cfg.ext_zksed = true; | ||
66 | + cpu->cfg.ext_zksh = true; | ||
67 | + } | ||
68 | + | ||
69 | /* Set the ISA extensions, checks should have happened above */ | ||
70 | if (cpu->cfg.ext_i) { | ||
71 | ext |= RVI; | ||
72 | -- | 60 | -- |
73 | 2.35.1 | 61 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Frank Chang <frank.chang@sifive.com> | 1 | From: Bin Meng <bin.meng@windriver.com> |
---|---|---|---|
2 | 2 | ||
3 | Allow user to set core's marchid, mvendorid, mipid CSRs through | 3 | This adds debug CSR read/write support to the RISC-V CSR RW table. |
4 | -cpu command line option. | ||
5 | 4 | ||
6 | The default values of marchid and mipid are built with QEMU's version | 5 | Signed-off-by: Bin Meng <bin.meng@windriver.com> |
7 | numbers. | ||
8 | |||
9 | Signed-off-by: Frank Chang <frank.chang@sifive.com> | ||
10 | Reviewed-by: Jim Shu <jim.shu@sifive.com> | ||
11 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
12 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | 7 | Message-Id: <20220421003324.1134983-4-bmeng.cn@gmail.com> |
13 | Message-Id: <20220422040436.2233-1-frank.chang@sifive.com> | ||
14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
15 | --- | 9 | --- |
16 | target/riscv/cpu.h | 4 ++++ | 10 | target/riscv/debug.h | 2 ++ |
17 | target/riscv/cpu.c | 9 +++++++++ | 11 | target/riscv/cpu.c | 4 ++++ |
18 | target/riscv/csr.c | 38 ++++++++++++++++++++++++++++++++++---- | 12 | target/riscv/csr.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ |
19 | 3 files changed, 47 insertions(+), 4 deletions(-) | 13 | target/riscv/debug.c | 27 +++++++++++++++++++++ |
14 | 4 files changed, 90 insertions(+) | ||
20 | 15 | ||
21 | diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h | 16 | diff --git a/target/riscv/debug.h b/target/riscv/debug.h |
22 | index XXXXXXX..XXXXXXX 100644 | 17 | index XXXXXXX..XXXXXXX 100644 |
23 | --- a/target/riscv/cpu.h | 18 | --- a/target/riscv/debug.h |
24 | +++ b/target/riscv/cpu.h | 19 | +++ b/target/riscv/debug.h |
25 | @@ -XXX,XX +XXX,XX @@ struct RISCVCPUConfig { | 20 | @@ -XXX,XX +XXX,XX @@ void riscv_cpu_debug_excp_handler(CPUState *cs); |
26 | bool ext_zve32f; | 21 | bool riscv_cpu_debug_check_breakpoint(CPUState *cs); |
27 | bool ext_zve64f; | 22 | bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp); |
28 | 23 | ||
29 | + uint32_t mvendorid; | 24 | +void riscv_trigger_init(CPURISCVState *env); |
30 | + uint64_t marchid; | ||
31 | + uint64_t mipid; | ||
32 | + | 25 | + |
33 | /* Vendor-specific custom extensions */ | 26 | #endif /* RISCV_DEBUG_H */ |
34 | bool ext_XVentanaCondOps; | ||
35 | |||
36 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 27 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
37 | index XXXXXXX..XXXXXXX 100644 | 28 | index XXXXXXX..XXXXXXX 100644 |
38 | --- a/target/riscv/cpu.c | 29 | --- a/target/riscv/cpu.c |
39 | +++ b/target/riscv/cpu.c | 30 | +++ b/target/riscv/cpu.c |
40 | @@ -XXX,XX +XXX,XX @@ | 31 | @@ -XXX,XX +XXX,XX @@ static void riscv_cpu_reset(DeviceState *dev) |
41 | 32 | set_default_nan_mode(1, &env->fp_status); | |
42 | /* RISC-V CPU definitions */ | 33 | |
43 | 34 | #ifndef CONFIG_USER_ONLY | |
44 | +#define RISCV_CPU_MARCHID ((QEMU_VERSION_MAJOR << 16) | \ | 35 | + if (riscv_feature(env, RISCV_FEATURE_DEBUG)) { |
45 | + (QEMU_VERSION_MINOR << 8) | \ | 36 | + riscv_trigger_init(env); |
46 | + (QEMU_VERSION_MICRO)) | 37 | + } |
47 | +#define RISCV_CPU_MIPID RISCV_CPU_MARCHID | ||
48 | + | 38 | + |
49 | static const char riscv_single_letter_exts[] = "IEMAFDQCPVH"; | 39 | if (kvm_enabled()) { |
50 | 40 | kvm_riscv_reset_vcpu(cpu); | |
51 | struct isa_ext_data { | 41 | } |
52 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | ||
53 | DEFINE_PROP_UINT16("vlen", RISCVCPU, cfg.vlen, 128), | ||
54 | DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64), | ||
55 | |||
56 | + DEFINE_PROP_UINT32("mvendorid", RISCVCPU, cfg.mvendorid, 0), | ||
57 | + DEFINE_PROP_UINT64("marchid", RISCVCPU, cfg.marchid, RISCV_CPU_MARCHID), | ||
58 | + DEFINE_PROP_UINT64("mipid", RISCVCPU, cfg.mipid, RISCV_CPU_MIPID), | ||
59 | + | ||
60 | DEFINE_PROP_BOOL("svinval", RISCVCPU, cfg.ext_svinval, false), | ||
61 | DEFINE_PROP_BOOL("svnapot", RISCVCPU, cfg.ext_svnapot, false), | ||
62 | DEFINE_PROP_BOOL("svpbmt", RISCVCPU, cfg.ext_svpbmt, false), | ||
63 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c | 42 | diff --git a/target/riscv/csr.c b/target/riscv/csr.c |
64 | index XXXXXXX..XXXXXXX 100644 | 43 | index XXXXXXX..XXXXXXX 100644 |
65 | --- a/target/riscv/csr.c | 44 | --- a/target/riscv/csr.c |
66 | +++ b/target/riscv/csr.c | 45 | +++ b/target/riscv/csr.c |
67 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_ignore(CPURISCVState *env, int csrno, | 46 | @@ -XXX,XX +XXX,XX @@ static RISCVException epmp(CPURISCVState *env, int csrno) |
47 | |||
48 | return RISCV_EXCP_ILLEGAL_INST; | ||
49 | } | ||
50 | + | ||
51 | +static RISCVException debug(CPURISCVState *env, int csrno) | ||
52 | +{ | ||
53 | + if (riscv_feature(env, RISCV_FEATURE_DEBUG)) { | ||
54 | + return RISCV_EXCP_NONE; | ||
55 | + } | ||
56 | + | ||
57 | + return RISCV_EXCP_ILLEGAL_INST; | ||
58 | +} | ||
59 | #endif | ||
60 | |||
61 | /* User Floating-Point CSRs */ | ||
62 | @@ -XXX,XX +XXX,XX @@ static RISCVException write_pmpaddr(CPURISCVState *env, int csrno, | ||
68 | return RISCV_EXCP_NONE; | 63 | return RISCV_EXCP_NONE; |
69 | } | 64 | } |
70 | 65 | ||
71 | +static RISCVException read_mvendorid(CPURISCVState *env, int csrno, | 66 | +static RISCVException read_tselect(CPURISCVState *env, int csrno, |
72 | + target_ulong *val) | 67 | + target_ulong *val) |
73 | +{ | 68 | +{ |
74 | + CPUState *cs = env_cpu(env); | 69 | + *val = tselect_csr_read(env); |
75 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
76 | + | ||
77 | + *val = cpu->cfg.mvendorid; | ||
78 | + return RISCV_EXCP_NONE; | 70 | + return RISCV_EXCP_NONE; |
79 | +} | 71 | +} |
80 | + | 72 | + |
81 | +static RISCVException read_marchid(CPURISCVState *env, int csrno, | 73 | +static RISCVException write_tselect(CPURISCVState *env, int csrno, |
82 | + target_ulong *val) | 74 | + target_ulong val) |
83 | +{ | 75 | +{ |
84 | + CPUState *cs = env_cpu(env); | 76 | + tselect_csr_write(env, val); |
85 | + RISCVCPU *cpu = RISCV_CPU(cs); | ||
86 | + | ||
87 | + *val = cpu->cfg.marchid; | ||
88 | + return RISCV_EXCP_NONE; | 77 | + return RISCV_EXCP_NONE; |
89 | +} | 78 | +} |
90 | + | 79 | + |
91 | +static RISCVException read_mipid(CPURISCVState *env, int csrno, | 80 | +static RISCVException read_tdata(CPURISCVState *env, int csrno, |
92 | + target_ulong *val) | 81 | + target_ulong *val) |
93 | +{ | 82 | +{ |
94 | + CPUState *cs = env_cpu(env); | 83 | + /* return 0 in tdata1 to end the trigger enumeration */ |
95 | + RISCVCPU *cpu = RISCV_CPU(cs); | 84 | + if (env->trigger_cur >= TRIGGER_NUM && csrno == CSR_TDATA1) { |
85 | + *val = 0; | ||
86 | + return RISCV_EXCP_NONE; | ||
87 | + } | ||
96 | + | 88 | + |
97 | + *val = cpu->cfg.mipid; | 89 | + if (!tdata_available(env, csrno - CSR_TDATA1)) { |
90 | + return RISCV_EXCP_ILLEGAL_INST; | ||
91 | + } | ||
92 | + | ||
93 | + *val = tdata_csr_read(env, csrno - CSR_TDATA1); | ||
98 | + return RISCV_EXCP_NONE; | 94 | + return RISCV_EXCP_NONE; |
99 | +} | 95 | +} |
100 | + | 96 | + |
101 | static RISCVException read_mhartid(CPURISCVState *env, int csrno, | 97 | +static RISCVException write_tdata(CPURISCVState *env, int csrno, |
102 | target_ulong *val) | 98 | + target_ulong val) |
103 | { | 99 | +{ |
100 | + if (!tdata_available(env, csrno - CSR_TDATA1)) { | ||
101 | + return RISCV_EXCP_ILLEGAL_INST; | ||
102 | + } | ||
103 | + | ||
104 | + tdata_csr_write(env, csrno - CSR_TDATA1, val); | ||
105 | + return RISCV_EXCP_NONE; | ||
106 | +} | ||
107 | + | ||
108 | /* | ||
109 | * Functions to access Pointer Masking feature registers | ||
110 | * We have to check if current priv lvl could modify | ||
104 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { | 111 | @@ -XXX,XX +XXX,XX @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = { |
105 | [CSR_MINSTRETH] = { "minstreth", any32, read_instreth }, | 112 | [CSR_PMPADDR14] = { "pmpaddr14", pmp, read_pmpaddr, write_pmpaddr }, |
106 | 113 | [CSR_PMPADDR15] = { "pmpaddr15", pmp, read_pmpaddr, write_pmpaddr }, | |
107 | /* Machine Information Registers */ | 114 | |
108 | - [CSR_MVENDORID] = { "mvendorid", any, read_zero }, | 115 | + /* Debug CSRs */ |
109 | - [CSR_MARCHID] = { "marchid", any, read_zero }, | 116 | + [CSR_TSELECT] = { "tselect", debug, read_tselect, write_tselect }, |
110 | - [CSR_MIMPID] = { "mimpid", any, read_zero }, | 117 | + [CSR_TDATA1] = { "tdata1", debug, read_tdata, write_tdata }, |
111 | - [CSR_MHARTID] = { "mhartid", any, read_mhartid }, | 118 | + [CSR_TDATA2] = { "tdata2", debug, read_tdata, write_tdata }, |
112 | + [CSR_MVENDORID] = { "mvendorid", any, read_mvendorid }, | 119 | + [CSR_TDATA3] = { "tdata3", debug, read_tdata, write_tdata }, |
113 | + [CSR_MARCHID] = { "marchid", any, read_marchid }, | 120 | + |
114 | + [CSR_MIMPID] = { "mimpid", any, read_mipid }, | 121 | /* User Pointer Masking */ |
115 | + [CSR_MHARTID] = { "mhartid", any, read_mhartid }, | 122 | [CSR_UMTE] = { "umte", pointer_masking, read_umte, write_umte }, |
116 | 123 | [CSR_UPMMASK] = { "upmmask", pointer_masking, read_upmmask, write_upmmask }, | |
117 | [CSR_MCONFIGPTR] = { "mconfigptr", any, read_zero, | 124 | diff --git a/target/riscv/debug.c b/target/riscv/debug.c |
118 | .min_priv_ver = PRIV_VERSION_1_12_0 }, | 125 | index XXXXXXX..XXXXXXX 100644 |
126 | --- a/target/riscv/debug.c | ||
127 | +++ b/target/riscv/debug.c | ||
128 | @@ -XXX,XX +XXX,XX @@ bool riscv_cpu_debug_check_watchpoint(CPUState *cs, CPUWatchpoint *wp) | ||
129 | |||
130 | return false; | ||
131 | } | ||
132 | + | ||
133 | +void riscv_trigger_init(CPURISCVState *env) | ||
134 | +{ | ||
135 | + target_ulong type2 = trigger_type(env, TRIGGER_TYPE_AD_MATCH); | ||
136 | + int i; | ||
137 | + | ||
138 | + /* type 2 triggers */ | ||
139 | + for (i = 0; i < TRIGGER_TYPE2_NUM; i++) { | ||
140 | + /* | ||
141 | + * type = TRIGGER_TYPE_AD_MATCH | ||
142 | + * dmode = 0 (both debug and M-mode can write tdata) | ||
143 | + * maskmax = 0 (unimplemented, always 0) | ||
144 | + * sizehi = 0 (match against any size, RV64 only) | ||
145 | + * hit = 0 (unimplemented, always 0) | ||
146 | + * select = 0 (always 0, perform match on address) | ||
147 | + * timing = 0 (always 0, trigger before instruction) | ||
148 | + * sizelo = 0 (match against any size) | ||
149 | + * action = 0 (always 0, raise a breakpoint exception) | ||
150 | + * chain = 0 (unimplemented, always 0) | ||
151 | + * match = 0 (always 0, when any compare value equals tdata2) | ||
152 | + */ | ||
153 | + env->type2_trig[i].mcontrol = type2; | ||
154 | + env->type2_trig[i].maddress = 0; | ||
155 | + env->type2_trig[i].bp = NULL; | ||
156 | + env->type2_trig[i].wp = NULL; | ||
157 | + } | ||
158 | +} | ||
119 | -- | 159 | -- |
120 | 2.35.1 | 160 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Bin Meng <bin.meng@windriver.com> | 1 | From: Bin Meng <bin.meng@windriver.com> |
---|---|---|---|
2 | 2 | ||
3 | Commit 7c28f4da20e5 ("RISC-V: Don't add NULL bootargs to device-tree") | 3 | Add a subsection to machine.c to migrate debug CSR state. |
4 | tried to avoid adding *NULL* bootargs to device tree, but unfortunately | ||
5 | the changes were entirely useless, due to MachineState::kernel_cmdline | ||
6 | can't be NULL at all as the default value is given as an empty string. | ||
7 | (see hw/core/machine.c::machine_initfn()). | ||
8 | 4 | ||
9 | Note the wording of *NULL* bootargs is wrong. It can't be NULL otherwise | ||
10 | a segfault had already been observed by dereferencing the NULL pointer. | ||
11 | It should be worded as *empty" bootargs. | ||
12 | |||
13 | Fixes: 7c28f4da20e5 ("RISC-V: Don't add NULL bootargs to device-tree") | ||
14 | Signed-off-by: Bin Meng <bin.meng@windriver.com> | 5 | Signed-off-by: Bin Meng <bin.meng@windriver.com> |
15 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
16 | Message-Id: <20220421055629.1177285-2-bmeng.cn@gmail.com> | 7 | Message-Id: <20220421003324.1134983-5-bmeng.cn@gmail.com> |
17 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
18 | --- | 9 | --- |
19 | hw/riscv/microchip_pfsoc.c | 2 +- | 10 | target/riscv/machine.c | 32 ++++++++++++++++++++++++++++++++ |
20 | hw/riscv/sifive_u.c | 2 +- | 11 | 1 file changed, 32 insertions(+) |
21 | hw/riscv/spike.c | 2 +- | ||
22 | hw/riscv/virt.c | 2 +- | ||
23 | 4 files changed, 4 insertions(+), 4 deletions(-) | ||
24 | 12 | ||
25 | diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c | 13 | diff --git a/target/riscv/machine.c b/target/riscv/machine.c |
26 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
27 | --- a/hw/riscv/microchip_pfsoc.c | 15 | --- a/target/riscv/machine.c |
28 | +++ b/hw/riscv/microchip_pfsoc.c | 16 | +++ b/target/riscv/machine.c |
29 | @@ -XXX,XX +XXX,XX @@ static void microchip_icicle_kit_machine_init(MachineState *machine) | 17 | @@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_kvmtimer = { |
30 | "linux,initrd-end", end); | 18 | VMSTATE_UINT64(env.kvm_timer_time, RISCVCPU), |
31 | } | 19 | VMSTATE_UINT64(env.kvm_timer_compare, RISCVCPU), |
32 | 20 | VMSTATE_UINT64(env.kvm_timer_state, RISCVCPU), | |
33 | - if (machine->kernel_cmdline) { | 21 | + VMSTATE_END_OF_LIST() |
34 | + if (machine->kernel_cmdline && *machine->kernel_cmdline) { | 22 | + } |
35 | qemu_fdt_setprop_string(machine->fdt, "/chosen", | 23 | +}; |
36 | "bootargs", machine->kernel_cmdline); | 24 | + |
37 | } | 25 | +static bool debug_needed(void *opaque) |
38 | diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c | 26 | +{ |
39 | index XXXXXXX..XXXXXXX 100644 | 27 | + RISCVCPU *cpu = opaque; |
40 | --- a/hw/riscv/sifive_u.c | 28 | + CPURISCVState *env = &cpu->env; |
41 | +++ b/hw/riscv/sifive_u.c | 29 | + |
42 | @@ -XXX,XX +XXX,XX @@ static void create_fdt(SiFiveUState *s, const MemMapEntry *memmap, | 30 | + return riscv_feature(env, RISCV_FEATURE_DEBUG); |
43 | g_free(nodename); | 31 | +} |
44 | 32 | ||
45 | update_bootargs: | 33 | +static const VMStateDescription vmstate_debug_type2 = { |
46 | - if (cmdline) { | 34 | + .name = "cpu/debug/type2", |
47 | + if (cmdline && *cmdline) { | 35 | + .version_id = 1, |
48 | qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline); | 36 | + .minimum_version_id = 1, |
37 | + .fields = (VMStateField[]) { | ||
38 | + VMSTATE_UINTTL(mcontrol, type2_trigger_t), | ||
39 | + VMSTATE_UINTTL(maddress, type2_trigger_t), | ||
40 | + VMSTATE_END_OF_LIST() | ||
41 | + } | ||
42 | +}; | ||
43 | + | ||
44 | +static const VMStateDescription vmstate_debug = { | ||
45 | + .name = "cpu/debug", | ||
46 | + .version_id = 1, | ||
47 | + .minimum_version_id = 1, | ||
48 | + .needed = debug_needed, | ||
49 | + .fields = (VMStateField[]) { | ||
50 | + VMSTATE_UINTTL(env.trigger_cur, RISCVCPU), | ||
51 | + VMSTATE_STRUCT_ARRAY(env.type2_trig, RISCVCPU, TRIGGER_TYPE2_NUM, | ||
52 | + 0, vmstate_debug_type2, type2_trigger_t), | ||
53 | VMSTATE_END_OF_LIST() | ||
49 | } | 54 | } |
50 | } | 55 | }; |
51 | diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c | 56 | @@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_riscv_cpu = { |
52 | index XXXXXXX..XXXXXXX 100644 | 57 | &vmstate_rv128, |
53 | --- a/hw/riscv/spike.c | 58 | &vmstate_kvmtimer, |
54 | +++ b/hw/riscv/spike.c | 59 | &vmstate_envcfg, |
55 | @@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap, | 60 | + &vmstate_debug, |
56 | qemu_fdt_add_subnode(fdt, "/chosen"); | 61 | NULL |
57 | qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif"); | ||
58 | |||
59 | - if (cmdline) { | ||
60 | + if (cmdline && *cmdline) { | ||
61 | qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline); | ||
62 | } | 62 | } |
63 | } | 63 | }; |
64 | diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c | ||
65 | index XXXXXXX..XXXXXXX 100644 | ||
66 | --- a/hw/riscv/virt.c | ||
67 | +++ b/hw/riscv/virt.c | ||
68 | @@ -XXX,XX +XXX,XX @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, | ||
69 | create_fdt_flash(s, memmap); | ||
70 | |||
71 | update_bootargs: | ||
72 | - if (cmdline) { | ||
73 | + if (cmdline && *cmdline) { | ||
74 | qemu_fdt_setprop_string(mc->fdt, "/chosen", "bootargs", cmdline); | ||
75 | } | ||
76 | } | ||
77 | -- | 64 | -- |
78 | 2.35.1 | 65 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Weiwei Li <liweiwei@iscas.ac.cn> | 1 | From: Bin Meng <bin.meng@windriver.com> |
---|---|---|---|
2 | 2 | ||
3 | Signed-off-by: Weiwei Li <liweiwei@iscas.ac.cn> | 3 | Turn on native debug feature by default for all CPUs. |
4 | Signed-off-by: Junqiang Wang <wangjunqiang@iscas.ac.cn> | 4 | |
5 | Signed-off-by: Bin Meng <bin.meng@windriver.com> | ||
5 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 6 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
6 | Message-Id: <20220423023510.30794-15-liweiwei@iscas.ac.cn> | 7 | Message-Id: <20220421003324.1134983-6-bmeng.cn@gmail.com> |
7 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 8 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
8 | --- | 9 | --- |
9 | target/riscv/cpu.c | 13 +++++++++++++ | 10 | target/riscv/cpu.c | 2 +- |
10 | 1 file changed, 13 insertions(+) | 11 | 1 file changed, 1 insertion(+), 1 deletion(-) |
11 | 12 | ||
12 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c | 13 | diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c |
13 | index XXXXXXX..XXXXXXX 100644 | 14 | index XXXXXXX..XXXXXXX 100644 |
14 | --- a/target/riscv/cpu.c | 15 | --- a/target/riscv/cpu.c |
15 | +++ b/target/riscv/cpu.c | 16 | +++ b/target/riscv/cpu.c |
16 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { | 17 | @@ -XXX,XX +XXX,XX @@ static Property riscv_cpu_properties[] = { |
17 | DEFINE_PROP_BOOL("zba", RISCVCPU, cfg.ext_zba, true), | 18 | DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false), |
18 | DEFINE_PROP_BOOL("zbb", RISCVCPU, cfg.ext_zbb, true), | 19 | DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true), |
19 | DEFINE_PROP_BOOL("zbc", RISCVCPU, cfg.ext_zbc, true), | 20 | DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true), |
20 | + DEFINE_PROP_BOOL("zbkb", RISCVCPU, cfg.ext_zbkb, false), | 21 | - DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, false), |
21 | + DEFINE_PROP_BOOL("zbkc", RISCVCPU, cfg.ext_zbkc, false), | 22 | + DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true), |
22 | + DEFINE_PROP_BOOL("zbkx", RISCVCPU, cfg.ext_zbkx, false), | 23 | |
23 | DEFINE_PROP_BOOL("zbs", RISCVCPU, cfg.ext_zbs, true), | 24 | DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec), |
24 | + DEFINE_PROP_BOOL("zk", RISCVCPU, cfg.ext_zk, false), | 25 | DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec), |
25 | + DEFINE_PROP_BOOL("zkn", RISCVCPU, cfg.ext_zkn, false), | ||
26 | + DEFINE_PROP_BOOL("zknd", RISCVCPU, cfg.ext_zknd, false), | ||
27 | + DEFINE_PROP_BOOL("zkne", RISCVCPU, cfg.ext_zkne, false), | ||
28 | + DEFINE_PROP_BOOL("zknh", RISCVCPU, cfg.ext_zknh, false), | ||
29 | + DEFINE_PROP_BOOL("zkr", RISCVCPU, cfg.ext_zkr, false), | ||
30 | + DEFINE_PROP_BOOL("zks", RISCVCPU, cfg.ext_zks, false), | ||
31 | + DEFINE_PROP_BOOL("zksed", RISCVCPU, cfg.ext_zksed, false), | ||
32 | + DEFINE_PROP_BOOL("zksh", RISCVCPU, cfg.ext_zksh, false), | ||
33 | + DEFINE_PROP_BOOL("zkt", RISCVCPU, cfg.ext_zkt, false), | ||
34 | |||
35 | DEFINE_PROP_BOOL("zdinx", RISCVCPU, cfg.ext_zdinx, false), | ||
36 | DEFINE_PROP_BOOL("zfinx", RISCVCPU, cfg.ext_zfinx, false), | ||
37 | -- | 26 | -- |
38 | 2.35.1 | 27 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Bin Meng <bin.meng@windriver.com> | 1 | From: Bin Meng <bin.meng@windriver.com> |
---|---|---|---|
2 | 2 | ||
3 | At present the adding '/chosen/stdout-path' property in device tree | 3 | This is now used by RISC-V as well. Update the comments. |
4 | is determined by whether a kernel command line is provided, which is | ||
5 | wrong. It should be added unconditionally. | ||
6 | 4 | ||
7 | Fixes: 8d8897accb1c ("hw/riscv: spike: Allow using binary firmware as bios") | ||
8 | Signed-off-by: Bin Meng <bin.meng@windriver.com> | 5 | Signed-off-by: Bin Meng <bin.meng@windriver.com> |
6 | Reviewed-by: Richard Henderson <richard.henderson@linaro.org> | ||
9 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 7 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
10 | Message-Id: <20220421055629.1177285-1-bmeng.cn@gmail.com> | 8 | Message-Id: <20220421003324.1134983-7-bmeng.cn@gmail.com> |
11 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 9 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
12 | --- | 10 | --- |
13 | hw/riscv/spike.c | 5 +++-- | 11 | include/hw/core/tcg-cpu-ops.h | 1 + |
14 | 1 file changed, 3 insertions(+), 2 deletions(-) | 12 | 1 file changed, 1 insertion(+) |
15 | 13 | ||
16 | diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c | 14 | diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h |
17 | index XXXXXXX..XXXXXXX 100644 | 15 | index XXXXXXX..XXXXXXX 100644 |
18 | --- a/hw/riscv/spike.c | 16 | --- a/include/hw/core/tcg-cpu-ops.h |
19 | +++ b/hw/riscv/spike.c | 17 | +++ b/include/hw/core/tcg-cpu-ops.h |
20 | @@ -XXX,XX +XXX,XX @@ static void create_fdt(SpikeState *s, const MemMapEntry *memmap, | 18 | @@ -XXX,XX +XXX,XX @@ struct TCGCPUOps { |
21 | 19 | /** | |
22 | riscv_socket_fdt_write_distance_matrix(mc, fdt); | 20 | * @debug_check_watchpoint: return true if the architectural |
23 | 21 | * watchpoint whose address has matched should really fire, used by ARM | |
24 | + qemu_fdt_add_subnode(fdt, "/chosen"); | 22 | + * and RISC-V |
25 | + qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif"); | 23 | */ |
26 | + | 24 | bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp); |
27 | if (cmdline) { | ||
28 | - qemu_fdt_add_subnode(fdt, "/chosen"); | ||
29 | qemu_fdt_setprop_string(fdt, "/chosen", "bootargs", cmdline); | ||
30 | - qemu_fdt_setprop_string(fdt, "/chosen", "stdout-path", "/htif"); | ||
31 | } | ||
32 | } | ||
33 | 25 | ||
34 | -- | 26 | -- |
35 | 2.35.1 | 27 | 2.35.1 | diff view generated by jsdifflib |
1 | From: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de> | 1 | From: Dylan Jhong <dylan@andestech.com> |
---|---|---|---|
2 | 2 | ||
3 | Two non-subsequent PTEs can be mapped to subsequent paddrs. In this | 3 | The current riscv_load_fdt() forces fdt_load_addr to be placed at a dram address within 3GB, |
4 | case, walk_pte will erroneously merge them. | 4 | but not all platforms have dram_base within 3GB. |
5 | 5 | ||
6 | Enforce the split up, by tracking the virtual base address. | 6 | This patch adds an exception for dram base not within 3GB, |
7 | which will place fdt at dram_end align 16MB. | ||
7 | 8 | ||
8 | Let's say we have the mapping: | 9 | riscv_setup_rom_reset_vec() also needs to be modified |
9 | 0x81200000 -> 0x89623000 (4K) | ||
10 | 0x8120f000 -> 0x89624000 (4K) | ||
11 | 10 | ||
12 | Before, walk_pte would have shown: | 11 | Signed-off-by: Dylan Jhong <dylan@andestech.com> |
13 | |||
14 | vaddr paddr size attr | ||
15 | ---------------- ---------------- ---------------- ------- | ||
16 | 0000000081200000 0000000089623000 0000000000002000 rwxu-ad | ||
17 | |||
18 | as it only checks for subsequent paddrs. With this patch, it becomes: | ||
19 | |||
20 | vaddr paddr size attr | ||
21 | ---------------- ---------------- ---------------- ------- | ||
22 | 0000000081200000 0000000089623000 0000000000001000 rwxu-ad | ||
23 | 000000008120f000 0000000089624000 0000000000001000 rwxu-ad | ||
24 | |||
25 | Signed-off-by: Ralf Ramsauer <ralf.ramsauer@oth-regensburg.de> | ||
26 | Reviewed-by: Bin Meng <bmeng.cn@gmail.com> | ||
27 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> | 12 | Reviewed-by: Alistair Francis <alistair.francis@wdc.com> |
28 | Message-Id: <20220423215907.673663-1-ralf.ramsauer@oth-regensburg.de> | 13 | Message-Id: <20220419115945.37945-1-dylan@andestech.com> |
29 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> | 14 | Signed-off-by: Alistair Francis <alistair.francis@wdc.com> |
30 | --- | 15 | --- |
31 | target/riscv/monitor.c | 11 +++++++---- | 16 | include/hw/riscv/boot.h | 4 ++-- |
32 | 1 file changed, 7 insertions(+), 4 deletions(-) | 17 | hw/riscv/boot.c | 12 +++++++----- |
18 | 2 files changed, 9 insertions(+), 7 deletions(-) | ||
33 | 19 | ||
34 | diff --git a/target/riscv/monitor.c b/target/riscv/monitor.c | 20 | diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h |
35 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
36 | --- a/target/riscv/monitor.c | 22 | --- a/include/hw/riscv/boot.h |
37 | +++ b/target/riscv/monitor.c | 23 | +++ b/include/hw/riscv/boot.h |
38 | @@ -XXX,XX +XXX,XX @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start, | 24 | @@ -XXX,XX +XXX,XX @@ target_ulong riscv_load_kernel(const char *kernel_filename, |
25 | symbol_fn_t sym_cb); | ||
26 | hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, | ||
27 | uint64_t kernel_entry, hwaddr *start); | ||
28 | -uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); | ||
29 | +uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); | ||
30 | void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, | ||
31 | hwaddr saddr, | ||
32 | hwaddr rom_base, hwaddr rom_size, | ||
33 | uint64_t kernel_entry, | ||
34 | - uint32_t fdt_load_addr, void *fdt); | ||
35 | + uint64_t fdt_load_addr, void *fdt); | ||
36 | void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base, | ||
37 | hwaddr rom_size, | ||
38 | uint32_t reset_vec_size, | ||
39 | diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c | ||
40 | index XXXXXXX..XXXXXXX 100644 | ||
41 | --- a/hw/riscv/boot.c | ||
42 | +++ b/hw/riscv/boot.c | ||
43 | @@ -XXX,XX +XXX,XX @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, | ||
44 | return *start + size; | ||
45 | } | ||
46 | |||
47 | -uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) | ||
48 | +uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) | ||
39 | { | 49 | { |
40 | hwaddr pte_addr; | 50 | - uint32_t temp, fdt_addr; |
41 | hwaddr paddr; | 51 | + uint64_t temp, fdt_addr; |
42 | + target_ulong last_start = -1; | 52 | hwaddr dram_end = dram_base + mem_size; |
43 | target_ulong pgsize; | 53 | int ret, fdtsize = fdt_totalsize(fdt); |
44 | target_ulong pte; | 54 | |
45 | int ptshift; | 55 | @@ -XXX,XX +XXX,XX @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) |
46 | @@ -XXX,XX +XXX,XX @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start, | 56 | * Thus, put it at an 16MB aligned address that less than fdt size from the |
47 | * A leaf PTE has been found | 57 | * end of dram or 3GB whichever is lesser. |
48 | * | 58 | */ |
49 | * If current PTE's permission bits differ from the last one, | 59 | - temp = MIN(dram_end, 3072 * MiB); |
50 | - * or current PTE's ppn does not make a contiguous physical | 60 | + temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; |
51 | - * address block together with the last one, print out the last | 61 | fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB); |
52 | - * contiguous mapped block details. | 62 | |
53 | + * or the current PTE breaks up a contiguous virtual or | 63 | ret = fdt_pack(fdt); |
54 | + * physical mapping, address block together with the last one, | 64 | @@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts |
55 | + * print out the last contiguous mapped block details. | 65 | hwaddr start_addr, |
56 | */ | 66 | hwaddr rom_base, hwaddr rom_size, |
57 | if ((*last_attr != attr) || | 67 | uint64_t kernel_entry, |
58 | - (*last_paddr + *last_size != paddr)) { | 68 | - uint32_t fdt_load_addr, void *fdt) |
59 | + (*last_paddr + *last_size != paddr) || | 69 | + uint64_t fdt_load_addr, void *fdt) |
60 | + (last_start + *last_size != start)) { | 70 | { |
61 | print_pte(mon, va_bits, *vbase, *pbase, | 71 | int i; |
62 | *last_paddr + *last_size - *pbase, *last_attr); | 72 | uint32_t start_addr_hi32 = 0x00000000; |
63 | 73 | + uint32_t fdt_load_addr_hi32 = 0x00000000; | |
64 | @@ -XXX,XX +XXX,XX @@ static void walk_pte(Monitor *mon, hwaddr base, target_ulong start, | 74 | |
65 | *last_attr = attr; | 75 | if (!riscv_is_32bit(harts)) { |
66 | } | 76 | start_addr_hi32 = start_addr >> 32; |
67 | 77 | + fdt_load_addr_hi32 = fdt_load_addr >> 32; | |
68 | + last_start = start; | 78 | } |
69 | *last_paddr = paddr; | 79 | /* reset vector */ |
70 | *last_size = pgsize; | 80 | uint32_t reset_vec[10] = { |
71 | } else { | 81 | @@ -XXX,XX +XXX,XX @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts |
82 | start_addr, /* start: .dword */ | ||
83 | start_addr_hi32, | ||
84 | fdt_load_addr, /* fdt_laddr: .dword */ | ||
85 | - 0x00000000, | ||
86 | + fdt_load_addr_hi32, | ||
87 | /* fw_dyn: */ | ||
88 | }; | ||
89 | if (riscv_is_32bit(harts)) { | ||
72 | -- | 90 | -- |
73 | 2.35.1 | 91 | 2.35.1 | diff view generated by jsdifflib |