1
First arm pullreq for the 2.12 cycle, with all the
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
things that queued up during the release phase.
3
2.11 isn't quite released yet, but might as well put
4
the pullreq on the mailing list :-)
5
2
6
thanks
3
Merge tag 'for_upstream' of https://git.kernel.org/pub/scm/virt/kvm/mst/qemu into staging (2024-02-14 15:45:52 +0000)
7
-- PMM
8
4
9
The following changes since commit 0a0dc59d27527b78a195c2d838d28b7b49e5a639:
5
are available in the Git repository at:
10
6
11
Update version for v2.11.0 release (2017-12-13 14:31:09 +0000)
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
12
8
13
are available in the git repository at:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
14
10
15
git://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20171213
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
16
17
for you to fetch changes up to d3c348b6e3af3598bfcb755d59f8f4de80a2228a:
18
19
xilinx_spips: Use memset instead of a for loop to zero registers (2017-12-13 17:59:26 +0000)
20
12
21
----------------------------------------------------------------
13
----------------------------------------------------------------
22
target-arm queue:
14
target-arm queue:
23
* xilinx_spips: set reset values correctly
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
24
* MAINTAINERS: fix an email address
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
25
* hw/display/tc6393xb: limit irq handler index to TC6393XB_GPIOS
17
* Fix some errors in SVE/SME handling of MTE tags
26
* nvic: Make systick banked for v8M
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
27
* refactor get_phys_addr() so we can return the right format PAR
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
28
for ATS operations
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
29
* implement v8M TT instruction
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
30
* fix some minor v8M bugs
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
31
* Implement reset for GICv3 ITS
23
* Don't assert on vmload/vmsave of M-profile CPUs
32
* xlnx-zcu102: Add support for the ZynqMP QSPI
24
* hw/arm/smmuv3: add support for stage 1 access fault
25
* hw/arm/stellaris: QOM cleanups
26
* Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
27
* Improve Cortex_R52 IMPDEF sysreg modelling
28
* Allow access to SPSR_hyp from hyp mode
29
* New board model mps3-an536 (Cortex-R52)
33
30
34
----------------------------------------------------------------
31
----------------------------------------------------------------
35
Alistair Francis (3):
32
Luc Michel (1):
36
xilinx_spips: Update the QSPI Mod ID reset value
33
hw/arm/smmuv3: add support for stage 1 access fault
37
xilinx_spips: Set all of the reset values
38
xilinx_spips: Use memset instead of a for loop to zero registers
39
34
40
Edgar E. Iglesias (1):
35
Nabih Estefan (1):
41
target/arm: Extend PAR format determination
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
42
37
43
Eric Auger (4):
38
Peter Maydell (22):
44
hw/intc/arm_gicv3_its: Don't call post_load on reset
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
45
hw/intc/arm_gicv3_its: Implement a minimalist reset
40
hw/block/tc58128: Don't emit deprecation warning under qtest
46
linux-headers: update to 4.15-rc1
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
47
hw/intc/arm_gicv3_its: Implement full reset
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
44
tests/qtest/bios-tables-tests: Update virt golden reference
45
hw/arm/npcm7xx: Call qemu_configure_nic_device() for GMAC modules
46
tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
47
target/arm: Don't get MDCR_EL2 in pmu_counter_enabled() before checking ARM_FEATURE_PMU
48
target/arm: Use new CBAR encoding for all v8 CPUs, not all aarch64 CPUs
49
target/arm: The Cortex-R52 has a read-only CBAR
50
target/arm: Add Cortex-R52 IMPDEF sysregs
51
target/arm: Allow access to SPSR_hyp from hyp mode
52
hw/misc/mps2-scc: Fix condition for CFG3 register
53
hw/misc/mps2-scc: Factor out which-board conditionals
54
hw/misc/mps2-scc: Make changes needed for AN536 FPGA image
55
hw/arm/mps3r: Initial skeleton for mps3-an536 board
56
hw/arm/mps3r: Add CPUs, GIC, and per-CPU RAM
57
hw/arm/mps3r: Add UARTs
58
hw/arm/mps3r: Add GPIO, watchdog, dual-timer, I2C devices
59
hw/arm/mps3r: Add remaining devices
60
docs: Add documentation for the mps3-an536 board
48
61
49
Francisco Iglesias (13):
62
Philippe Mathieu-Daudé (5):
50
m25p80: Add support for continuous read out of RDSR and READ_FSR
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
51
m25p80: Add support for SST READ ID 0x90/0xAB commands
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
52
m25p80: Add support for BRRD/BRWR and BULK_ERASE (0x60)
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
53
m25p80: Add support for n25q512a11 and n25q512a13
66
hw/arm/stellaris: Add missing QOM 'machine' parent
54
xilinx_spips: Move FlashCMD, XilinxQSPIPS and XilinxSPIPSClass
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
55
xilinx_spips: Update striping to be big-endian bit order
56
xilinx_spips: Add support for RX discard and RX drain
57
xilinx_spips: Make tx/rx_data_bytes more generic and reusable
58
xilinx_spips: Add support for zero pumping
59
xilinx_spips: Add support for 4 byte addresses in the LQSPI
60
xilinx_spips: Don't set TX FIFO UNDERFLOW at cmd done
61
xilinx_spips: Add support for the ZynqMP Generic QSPI
62
xlnx-zcu102: Add support for the ZynqMP QSPI
63
68
64
Peter Maydell (20):
69
Richard Henderson (6):
65
target/arm: Handle SPSEL and current stack being out of sync in MSP/PSP reads
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
66
target/arm: Allow explicit writes to CONTROL.SPSEL in Handler mode
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
67
target/arm: Add missing M profile case to regime_is_user()
72
target/arm: Adjust and validate mtedesc sizem1
68
target/arm: Split M profile MNegPri mmu index into user and priv
73
target/arm: Split out make_svemte_desc
69
target/arm: Create new arm_v7m_mmu_idx_for_secstate_and_priv()
74
target/arm: Handle mte in do_ldrq, do_ldro
70
target/arm: Factor MPU lookup code out of get_phys_addr_pmsav8()
75
target/arm: Fix SVE/SME gross MTE suppression checks
71
target/arm: Implement TT instruction
72
target/arm: Provide fault type enum and FSR conversion functions
73
target/arm: Remove fsr argument from arm_ld*_ptw()
74
target/arm: Convert get_phys_addr_v5() to not return FSC values
75
target/arm: Convert get_phys_addr_v6() to not return FSC values
76
target/arm: Convert get_phys_addr_lpae() to not return FSC values
77
target/arm: Convert get_phys_addr_pmsav5() to not return FSC values
78
target/arm: Convert get_phys_addr_pmsav7() to not return FSC values
79
target/arm: Convert get_phys_addr_pmsav8() to not return FSC values
80
target/arm: Use ARMMMUFaultInfo in deliver_fault()
81
target/arm: Ignore fsr from get_phys_addr() in do_ats_write()
82
target/arm: Remove fsr argument from get_phys_addr() and arm_tlb_fill()
83
nvic: Make nvic_sysreg_ns_ops work with any MemoryRegion
84
nvic: Make systick banked
85
76
86
Prasad J Pandit (1):
77
MAINTAINERS | 3 +-
87
hw/display/tc6393xb: limit irq handler index to TC6393XB_GPIOS
78
docs/system/arm/mps2.rst | 37 +-
79
configs/devices/arm-softmmu/default.mak | 1 +
80
hw/arm/smmuv3-internal.h | 1 +
81
include/hw/arm/smmu-common.h | 1 +
82
include/hw/arm/virt.h | 2 +
83
include/hw/misc/mps2-scc.h | 1 +
84
linux-user/aarch64/target_prctl.h | 29 +-
85
target/arm/internals.h | 2 +-
86
target/arm/tcg/translate-a64.h | 2 +
87
hw/arm/mps3r.c | 640 ++++++++++++++++++++++++++++++++
88
hw/arm/npcm7xx.c | 1 +
89
hw/arm/smmu-common.c | 11 +
90
hw/arm/smmuv3.c | 1 +
91
hw/arm/stellaris.c | 47 ++-
92
hw/arm/virt-acpi-build.c | 20 +-
93
hw/arm/virt.c | 60 ++-
94
hw/arm/xilinx_zynq.c | 2 +
95
hw/block/tc58128.c | 4 +-
96
hw/misc/mps2-scc.c | 138 ++++++-
97
hw/pci-host/raven.c | 1 +
98
target/arm/helper.c | 14 +-
99
target/arm/tcg/cpu32.c | 109 ++++++
100
target/arm/tcg/op_helper.c | 43 ++-
101
target/arm/tcg/sme_helper.c | 8 +-
102
target/arm/tcg/sve_helper.c | 12 +-
103
target/arm/tcg/translate-sme.c | 15 +-
104
target/arm/tcg/translate-sve.c | 83 +++--
105
target/arm/tcg/translate.c | 19 +-
106
tests/qtest/npcm7xx_emc-test.c | 5 +-
107
tests/qtest/npcm_gmac-test.c | 84 +----
108
hw/arm/Kconfig | 5 +
109
hw/arm/meson.build | 1 +
110
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
111
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
112
tests/qtest/meson.build | 4 +-
113
36 files changed, 1184 insertions(+), 222 deletions(-)
114
create mode 100644 hw/arm/mps3r.c
88
115
89
Zhaoshenglong (1):
90
MAINTAINERS: replace the unavailable email address
91
92
include/hw/arm/xlnx-zynqmp.h | 5 +
93
include/hw/intc/armv7m_nvic.h | 4 +-
94
include/hw/ssi/xilinx_spips.h | 74 +-
95
include/standard-headers/asm-s390/virtio-ccw.h | 1 +
96
include/standard-headers/asm-x86/hyperv.h | 394 +--------
97
include/standard-headers/linux/input-event-codes.h | 2 +
98
include/standard-headers/linux/input.h | 1 +
99
include/standard-headers/linux/pci_regs.h | 45 +-
100
linux-headers/asm-arm/kvm.h | 8 +
101
linux-headers/asm-arm/kvm_para.h | 1 +
102
linux-headers/asm-arm/unistd.h | 2 +
103
linux-headers/asm-arm64/kvm.h | 8 +
104
linux-headers/asm-arm64/unistd.h | 1 +
105
linux-headers/asm-powerpc/epapr_hcalls.h | 1 +
106
linux-headers/asm-powerpc/kvm.h | 1 +
107
linux-headers/asm-powerpc/kvm_para.h | 1 +
108
linux-headers/asm-powerpc/unistd.h | 1 +
109
linux-headers/asm-s390/kvm.h | 1 +
110
linux-headers/asm-s390/kvm_para.h | 1 +
111
linux-headers/asm-s390/unistd.h | 4 +-
112
linux-headers/asm-x86/kvm.h | 1 +
113
linux-headers/asm-x86/kvm_para.h | 2 +-
114
linux-headers/asm-x86/unistd.h | 1 +
115
linux-headers/linux/kvm.h | 2 +
116
linux-headers/linux/kvm_para.h | 1 +
117
linux-headers/linux/psci.h | 1 +
118
linux-headers/linux/userfaultfd.h | 1 +
119
linux-headers/linux/vfio.h | 1 +
120
linux-headers/linux/vfio_ccw.h | 1 +
121
linux-headers/linux/vhost.h | 1 +
122
target/arm/cpu.h | 73 +-
123
target/arm/helper.h | 2 +
124
target/arm/internals.h | 193 ++++-
125
hw/arm/xlnx-zcu102.c | 23 +
126
hw/arm/xlnx-zynqmp.c | 26 +
127
hw/block/m25p80.c | 80 +-
128
hw/display/tc6393xb.c | 1 +
129
hw/intc/arm_gicv3_its_common.c | 2 -
130
hw/intc/arm_gicv3_its_kvm.c | 53 +-
131
hw/intc/armv7m_nvic.c | 100 ++-
132
hw/ssi/xilinx_spips.c | 928 +++++++++++++++++----
133
target/arm/helper.c | 489 +++++++----
134
target/arm/op_helper.c | 82 +-
135
target/arm/translate.c | 37 +-
136
MAINTAINERS | 2 +-
137
default-configs/arm-softmmu.mak | 2 +-
138
46 files changed, 1833 insertions(+), 828 deletions(-)
139
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add support for Micron (Numonyx) n25q512a11 and n25q512a13 flashes.
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
connect FIQ output of the GIC CPU interfaces to the CPU.
4
5
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Acked-by: Marcin Krzemiński <mar.krzeminski@gmail.com>
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20171126231634.9531-5-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
10
---
13
hw/block/m25p80.c | 2 ++
11
hw/arm/xilinx_zynq.c | 2 ++
14
1 file changed, 2 insertions(+)
12
1 file changed, 2 insertions(+)
15
13
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
17
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
16
--- a/hw/arm/xilinx_zynq.c
19
+++ b/hw/block/m25p80.c
17
+++ b/hw/arm/xilinx_zynq.c
20
@@ -XXX,XX +XXX,XX @@ static const FlashPartInfo known_devices[] = {
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
21
{ INFO("n25q128a13", 0x20ba18, 0, 64 << 10, 256, ER_4K) },
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
22
{ INFO("n25q256a11", 0x20bb19, 0, 64 << 10, 512, ER_4K) },
20
sysbus_connect_irq(busdev, 0,
23
{ INFO("n25q256a13", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
24
+ { INFO("n25q512a11", 0x20bb20, 0, 64 << 10, 1024, ER_4K) },
22
+ sysbus_connect_irq(busdev, 1,
25
+ { INFO("n25q512a13", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
26
{ INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) },
24
27
{ INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512, ER_4K) },
25
for (n = 0; n < 64; n++) {
28
{ INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
26
pic[n] = qdev_get_gpio_in(dev, n);
29
--
27
--
30
2.7.4
28
2.34.1
31
29
32
30
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Use memset() instead of a for loop to zero all of the registers.
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
4
6
5
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
7
Cc: qemu-stable@nongnu.org
6
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: c076e907f355923864cb1afde31b938ffb677778.1513104804.git.alistair.francis@xilinx.com
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Message-id: 20240207025210.8837-2-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
hw/ssi/xilinx_spips.c | 11 +++--------
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
12
1 file changed, 3 insertions(+), 8 deletions(-)
15
1 file changed, 17 insertions(+), 12 deletions(-)
13
16
14
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/xilinx_spips.c
19
--- a/linux-user/aarch64/target_prctl.h
17
+++ b/hw/ssi/xilinx_spips.c
20
+++ b/linux-user/aarch64/target_prctl.h
18
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
19
{
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
20
XilinxSPIPS *s = XILINX_SPIPS(d);
23
21
24
if (cpu_isar_feature(aa64_mte, cpu)) {
22
- int i;
25
- switch (arg2 & PR_MTE_TCF_MASK) {
23
- for (i = 0; i < XLNX_SPIPS_R_MAX; i++) {
26
- case PR_MTE_TCF_NONE:
24
- s->regs[i] = 0;
27
- case PR_MTE_TCF_SYNC:
25
- }
28
- case PR_MTE_TCF_ASYNC:
26
+ memset(s->regs, 0, sizeof(s->regs));
29
- break;
27
30
- default:
28
fifo8_reset(&s->rx_fifo);
31
- return -EINVAL;
29
fifo8_reset(&s->rx_fifo);
32
- }
30
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
33
-
31
static void xlnx_zynqmp_qspips_reset(DeviceState *d)
34
/*
32
{
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
33
XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(d);
36
- * Note that the syscall values are consistent with hw.
34
- int i;
37
+ *
35
38
+ * The kernel has a per-cpu configuration for the sysadmin,
36
xilinx_spips_reset(d);
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
37
40
+ * which qemu does not implement.
38
- for (i = 0; i < XLNX_ZYNQMP_SPIPS_R_MAX; i++) {
41
+ *
39
- s->regs[i] = 0;
42
+ * Because there is no performance difference between the modes, and
40
- }
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
41
+ memset(s->regs, 0, sizeof(s->regs));
44
+ * as the preferred mode. With this preference, and the way the API
42
+
45
+ * uses only two bits, there is no way for the program to select
43
fifo8_reset(&s->rx_fifo_g);
46
+ * ASYMM mode.
44
fifo8_reset(&s->rx_fifo_g);
47
*/
45
fifo32_reset(&s->fifo_g);
48
- env->cp15.sctlr_el[1] =
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
50
+ unsigned tcf = 0;
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
52
+ tcf = 1;
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
54
+ tcf = 2;
55
+ }
56
+ env->cp15.sctlr_el[1] = deposit64(env->cp15.sctlr_el[1], 38, 2, tcf);
57
58
/*
59
* Write PR_MTE_TAG to GCR_EL1[Exclude].
46
--
60
--
47
2.7.4
61
2.34.1
48
49
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
At the moment the ITS is not properly reset and this causes
3
The field is encoded as [0-3], which is convenient for
4
various bugs on save/restore. We implement a minimalist reset
4
indexing our array of function pointers, but the true
5
through individual register writes but for kernel versions
5
value is [1-4]. Adjust before calling do_mem_zpa.
6
before v4.15 this fails voiding the vITS cache. We cannot
7
claim we have a comprehensive reset (hence the error message)
8
but that's better than nothing.
9
6
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
7
Add an assert, and move the comment re passing ZT to
8
the helper back next to the relevant code.
9
10
Cc: qemu-stable@nongnu.org
11
Fixes: 206adacfb8d ("target/arm: Add mte helpers for sve scalar + int loads")
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 1511883692-11511-3-git-send-email-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
17
---
15
hw/intc/arm_gicv3_its_kvm.c | 42 ++++++++++++++++++++++++++++++++++++++++++
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
16
1 file changed, 42 insertions(+)
19
1 file changed, 8 insertions(+), 8 deletions(-)
17
20
18
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
19
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gicv3_its_kvm.c
23
--- a/target/arm/tcg/translate-sve.c
21
+++ b/hw/intc/arm_gicv3_its_kvm.c
24
+++ b/target/arm/tcg/translate-sve.c
22
@@ -XXX,XX +XXX,XX @@
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
23
26
TCGv_ptr t_pg;
24
#define TYPE_KVM_ARM_ITS "arm-its-kvm"
27
int desc = 0;
25
#define KVM_ARM_ITS(obj) OBJECT_CHECK(GICv3ITSState, (obj), TYPE_KVM_ARM_ITS)
28
26
+#define KVM_ARM_ITS_CLASS(klass) \
29
- /*
27
+ OBJECT_CLASS_CHECK(KVMARMITSClass, (klass), TYPE_KVM_ARM_ITS)
30
- * For e.g. LD4, there are not enough arguments to pass all 4
28
+#define KVM_ARM_ITS_GET_CLASS(obj) \
31
- * registers as pointers, so encode the regno into the data field.
29
+ OBJECT_GET_CLASS(KVMARMITSClass, (obj), TYPE_KVM_ARM_ITS)
32
- * For consistency, do this even for LD1.
30
+
33
- */
31
+typedef struct KVMARMITSClass {
34
+ assert(mte_n >= 1 && mte_n <= 4);
32
+ GICv3ITSCommonClass parent_class;
35
if (s->mte_active[0]) {
33
+ void (*parent_reset)(DeviceState *dev);
36
int msz = dtype_msz(dtype);
34
+} KVMARMITSClass;
37
35
+
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
36
39
addr = clean_data_tbi(s, addr);
37
static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid)
40
}
38
{
41
39
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
42
+ /*
40
GITS_CTLR, &s->ctlr, true, &error_abort);
43
+ * For e.g. LD4, there are not enough arguments to pass all 4
44
+ * registers as pointers, so encode the regno into the data field.
45
+ * For consistency, do this even for LD1.
46
+ */
47
desc = simd_desc(vsz, vsz, zt | desc);
48
t_pg = tcg_temp_new_ptr();
49
50
@@ -XXX,XX +XXX,XX @@ static void do_ld_zpa(DisasContext *s, int zt, int pg,
51
* accessible via the instruction encoding.
52
*/
53
assert(fn != NULL);
54
- do_mem_zpa(s, zt, pg, addr, dtype, nreg, false, fn);
55
+ do_mem_zpa(s, zt, pg, addr, dtype, nreg + 1, false, fn);
41
}
56
}
42
57
43
+static void kvm_arm_its_reset(DeviceState *dev)
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
44
+{
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
45
+ GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev);
60
if (nreg == 0) {
46
+ KVMARMITSClass *c = KVM_ARM_ITS_GET_CLASS(s);
61
/* ST1 */
47
+ int i;
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
48
+
63
- nreg = 1;
49
+ c->parent_reset(dev);
64
} else {
50
+
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
51
+ error_report("ITS KVM: full reset is not supported by QEMU");
66
assert(msz == esz);
52
+
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
53
+ if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
68
}
54
+ GITS_CTLR)) {
69
assert(fn != NULL);
55
+ return;
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
56
+ }
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
57
+
58
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
59
+ GITS_CTLR, &s->ctlr, true, &error_abort);
60
+
61
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
62
+ GITS_CBASER, &s->cbaser, true, &error_abort);
63
+
64
+ for (i = 0; i < 8; i++) {
65
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
66
+ GITS_BASER + i * 8, &s->baser[i], true,
67
+ &error_abort);
68
+ }
69
+}
70
+
71
static Property kvm_arm_its_props[] = {
72
DEFINE_PROP_LINK("parent-gicv3", GICv3ITSState, gicv3, "kvm-arm-gicv3",
73
GICv3State *),
74
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_class_init(ObjectClass *klass, void *data)
75
{
76
DeviceClass *dc = DEVICE_CLASS(klass);
77
GICv3ITSCommonClass *icc = ARM_GICV3_ITS_COMMON_CLASS(klass);
78
+ KVMARMITSClass *ic = KVM_ARM_ITS_CLASS(klass);
79
80
dc->realize = kvm_arm_its_realize;
81
dc->props = kvm_arm_its_props;
82
+ ic->parent_reset = dc->reset;
83
icc->send_msi = kvm_its_send_msi;
84
icc->pre_save = kvm_arm_its_pre_save;
85
icc->post_load = kvm_arm_its_post_load;
86
+ dc->reset = kvm_arm_its_reset;
87
}
72
}
88
73
89
static const TypeInfo kvm_arm_its_info = {
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
90
@@ -XXX,XX +XXX,XX @@ static const TypeInfo kvm_arm_its_info = {
91
.parent = TYPE_ARM_GICV3_ITS_COMMON,
92
.instance_size = sizeof(GICv3ITSState),
93
.class_init = kvm_arm_its_class_init,
94
+ .class_size = sizeof(KVMARMITSClass),
95
};
96
97
static void kvm_arm_its_register_types(void)
98
--
75
--
99
2.7.4
76
2.34.1
100
101
diff view generated by jsdifflib
1
All of the callers of get_phys_addr() and arm_tlb_fill() now ignore
1
From: Richard Henderson <richard.henderson@linaro.org>
2
the FSR values they return, so we can just remove the argument
3
entirely.
4
2
3
When we added SVE_MTEDESC_SHIFT, we effectively limited the
4
maximum size of MTEDESC. Adjust SIZEM1 to consume the remaining
5
bits (32 - 10 - 5 - 12 == 5). Assert that the data to be stored
6
fits within the field (expecting 8 * 4 - 1 == 31, exact fit).
7
8
Cc: qemu-stable@nongnu.org
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
9
Message-id: 1512503192-2239-12-git-send-email-peter.maydell@linaro.org
10
---
14
---
11
target/arm/internals.h | 2 +-
15
target/arm/internals.h | 2 +-
12
target/arm/helper.c | 45 ++++++++++++++-------------------------------
16
target/arm/tcg/translate-sve.c | 7 ++++---
13
target/arm/op_helper.c | 3 +--
17
2 files changed, 5 insertions(+), 4 deletions(-)
14
3 files changed, 16 insertions(+), 34 deletions(-)
15
18
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
21
--- a/target/arm/internals.h
19
+++ b/target/arm/internals.h
22
+++ b/target/arm/internals.h
20
@@ -XXX,XX +XXX,XX @@ static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
21
/* Do a page table walk and add page to TLB if possible */
24
FIELD(MTEDESC, TCMA, 6, 2)
22
bool arm_tlb_fill(CPUState *cpu, vaddr address,
25
FIELD(MTEDESC, WRITE, 8, 1)
23
MMUAccessType access_type, int mmu_idx,
26
FIELD(MTEDESC, ALIGN, 9, 3)
24
- uint32_t *fsr, ARMMMUFaultInfo *fi);
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
25
+ ARMMMUFaultInfo *fi);
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
26
29
27
/* Return true if the stage 1 translation regime is using LPAE format page
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
28
* tables */
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
29
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
30
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.c
34
--- a/target/arm/tcg/translate-sve.c
32
+++ b/target/arm/helper.c
35
+++ b/target/arm/tcg/translate-sve.c
33
@@ -XXX,XX +XXX,XX @@ typedef struct ARMCacheAttrs {
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
34
static bool get_phys_addr(CPUARMState *env, target_ulong address,
35
MMUAccessType access_type, ARMMMUIdx mmu_idx,
36
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
37
- target_ulong *page_size, uint32_t *fsr,
38
+ target_ulong *page_size,
39
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
40
41
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
42
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
43
hwaddr phys_addr;
44
target_ulong page_size;
45
int prot;
46
- uint32_t fsr_unused;
47
bool ret;
48
uint64_t par64;
49
MemTxAttrs attrs = {};
50
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
51
ARMCacheAttrs cacheattrs = {};
52
53
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
54
- &prot, &page_size, &fsr_unused, &fi, &cacheattrs);
55
+ &prot, &page_size, &fi, &cacheattrs);
56
/* TODO: this is not the correct condition to use to decide whether
57
* to report a PAR in 64-bit or 32-bit format.
58
*/
59
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
60
target_ulong page_size;
61
hwaddr physaddr;
62
int prot;
63
- uint32_t fsr;
64
65
v8m_security_lookup(env, addr, MMU_INST_FETCH, mmu_idx, &sattrs);
66
if (!sattrs.nsc || sattrs.ns) {
67
@@ -XXX,XX +XXX,XX @@ static bool v7m_read_half_insn(ARMCPU *cpu, ARMMMUIdx mmu_idx,
68
return false;
69
}
70
if (get_phys_addr(env, addr, MMU_INST_FETCH, mmu_idx,
71
- &physaddr, &attrs, &prot, &page_size, &fsr, &fi, NULL)) {
72
+ &physaddr, &attrs, &prot, &page_size, &fi, NULL)) {
73
/* the MPU lookup failed */
74
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_IACCVIOL_MASK;
75
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM, env->v7m.secure);
76
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(ARMCacheAttrs s1, ARMCacheAttrs s2)
77
* @attrs: set to the memory transaction attributes to use
78
* @prot: set to the permissions for the page containing phys_ptr
79
* @page_size: set to the size of the page containing phys_ptr
80
- * @fsr: set to the DFSR/IFSR value on failure
81
* @fi: set to fault info if the translation fails
82
* @cacheattrs: (if non-NULL) set to the cacheability/shareability attributes
83
*/
84
static bool get_phys_addr(CPUARMState *env, target_ulong address,
85
MMUAccessType access_type, ARMMMUIdx mmu_idx,
86
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
87
- target_ulong *page_size, uint32_t *fsr,
88
+ target_ulong *page_size,
89
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
90
{
37
{
91
if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
38
unsigned vsz = vec_full_reg_size(s);
92
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
39
TCGv_ptr t_pg;
93
40
+ uint32_t sizem1;
94
ret = get_phys_addr(env, address, access_type,
41
int desc = 0;
95
stage_1_mmu_idx(mmu_idx), &ipa, attrs,
42
96
- prot, page_size, fsr, fi, cacheattrs);
43
assert(mte_n >= 1 && mte_n <= 4);
97
+ prot, page_size, fi, cacheattrs);
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
98
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
99
/* If S1 fails or S2 is disabled, return early. */
46
if (s->mte_active[0]) {
100
if (ret || regime_translation_disabled(env, ARMMMUIdx_S2NS)) {
47
- int msz = dtype_msz(dtype);
101
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
102
phys_ptr, attrs, &s2_prot,
103
page_size, fi,
104
cacheattrs != NULL ? &cacheattrs2 : NULL);
105
- *fsr = arm_fi_to_lfsc(fi);
106
fi->s2addr = ipa;
107
/* Combine the S1 and S2 perms. */
108
*prot &= s2_prot;
109
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
110
/* PMSAv8 */
111
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
112
phys_ptr, attrs, prot, fi);
113
- *fsr = arm_fi_to_sfsc(fi);
114
} else if (arm_feature(env, ARM_FEATURE_V7)) {
115
/* PMSAv7 */
116
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
117
phys_ptr, prot, fi);
118
- *fsr = arm_fi_to_sfsc(fi);
119
} else {
120
/* Pre-v7 MPU */
121
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
122
phys_ptr, prot, fi);
123
- *fsr = arm_fi_to_sfsc(fi);
124
}
125
qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
126
" mmu_idx %u -> %s (prot %c%c%c)\n",
127
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
128
}
129
130
if (regime_using_lpae_format(env, mmu_idx)) {
131
- bool ret = get_phys_addr_lpae(env, address, access_type, mmu_idx,
132
- phys_ptr, attrs, prot, page_size,
133
- fi, cacheattrs);
134
-
48
-
135
- *fsr = arm_fi_to_lfsc(fi);
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
136
- return ret;
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
137
+ return get_phys_addr_lpae(env, address, access_type, mmu_idx,
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
138
+ phys_ptr, attrs, prot, page_size,
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
139
+ fi, cacheattrs);
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
140
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
141
- bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
55
desc <<= SVE_MTEDESC_SHIFT;
142
- phys_ptr, attrs, prot, page_size, fi);
143
-
144
- *fsr = arm_fi_to_sfsc(fi);
145
- return ret;
146
+ return get_phys_addr_v6(env, address, access_type, mmu_idx,
147
+ phys_ptr, attrs, prot, page_size, fi);
148
} else {
56
} else {
149
- bool ret = get_phys_addr_v5(env, address, access_type, mmu_idx,
57
addr = clean_data_tbi(s, addr);
150
+ return get_phys_addr_v5(env, address, access_type, mmu_idx,
151
phys_ptr, prot, page_size, fi);
152
-
153
- *fsr = arm_fi_to_sfsc(fi);
154
- return ret;
155
}
156
}
157
158
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
159
* fsr with ARM DFSR/IFSR fault register format value on failure.
160
*/
161
bool arm_tlb_fill(CPUState *cs, vaddr address,
162
- MMUAccessType access_type, int mmu_idx, uint32_t *fsr,
163
+ MMUAccessType access_type, int mmu_idx,
164
ARMMMUFaultInfo *fi)
165
{
166
ARMCPU *cpu = ARM_CPU(cs);
167
@@ -XXX,XX +XXX,XX @@ bool arm_tlb_fill(CPUState *cs, vaddr address,
168
169
ret = get_phys_addr(env, address, access_type,
170
core_to_arm_mmu_idx(env, mmu_idx), &phys_addr,
171
- &attrs, &prot, &page_size, fsr, fi, NULL);
172
+ &attrs, &prot, &page_size, fi, NULL);
173
if (!ret) {
174
/* Map a single [sub]page. */
175
phys_addr &= TARGET_PAGE_MASK;
176
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
177
target_ulong page_size;
178
int prot;
179
bool ret;
180
- uint32_t fsr;
181
ARMMMUFaultInfo fi = {};
182
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
183
184
*attrs = (MemTxAttrs) {};
185
186
ret = get_phys_addr(env, addr, 0, mmu_idx, &phys_addr,
187
- attrs, &prot, &page_size, &fsr, &fi, NULL);
188
+ attrs, &prot, &page_size, &fi, NULL);
189
190
if (ret) {
191
return -1;
192
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
193
index XXXXXXX..XXXXXXX 100644
194
--- a/target/arm/op_helper.c
195
+++ b/target/arm/op_helper.c
196
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
197
int mmu_idx, uintptr_t retaddr)
198
{
199
bool ret;
200
- uint32_t fsr = 0;
201
ARMMMUFaultInfo fi = {};
202
203
- ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
204
+ ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fi);
205
if (unlikely(ret)) {
206
ARMCPU *cpu = ARM_CPU(cs);
207
208
--
58
--
209
2.7.4
59
2.34.1
210
211
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for zero pumping according to the transfer size register.
3
Share code that creates mtedesc and embeds within simd_desc.
4
4
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20171126231634.9531-10-frasse.iglesias@gmail.com
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
9
Message-id: 20240207025210.8837-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
---
11
include/hw/ssi/xilinx_spips.h | 2 ++
12
target/arm/tcg/translate-a64.h | 2 ++
12
hw/ssi/xilinx_spips.c | 47 ++++++++++++++++++++++++++++++++++++-------
13
target/arm/tcg/translate-sme.c | 15 +++--------
13
2 files changed, 42 insertions(+), 7 deletions(-)
14
target/arm/tcg/translate-sve.c | 47 ++++++++++++++++++----------------
15
3 files changed, 31 insertions(+), 33 deletions(-)
14
16
15
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
17
diff --git a/target/arm/tcg/translate-a64.h b/target/arm/tcg/translate-a64.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/xilinx_spips.h
19
--- a/target/arm/tcg/translate-a64.h
18
+++ b/include/hw/ssi/xilinx_spips.h
20
+++ b/target/arm/tcg/translate-a64.h
19
@@ -XXX,XX +XXX,XX @@ struct XilinxSPIPS {
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
20
uint32_t rx_discard;
22
bool sve_access_check(DisasContext *s);
21
23
bool sme_enabled_check(DisasContext *s);
22
uint32_t regs[XLNX_SPIPS_R_MAX];
24
bool sme_enabled_check_with_svcr(DisasContext *s, unsigned);
25
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
26
+ uint32_t msz, bool is_write, uint32_t data);
27
28
/* This function corresponds to CheckStreamingSVEEnabled. */
29
static inline bool sme_sm_enabled_check(DisasContext *s)
30
diff --git a/target/arm/tcg/translate-sme.c b/target/arm/tcg/translate-sme.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/tcg/translate-sme.c
33
+++ b/target/arm/tcg/translate-sme.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
35
36
TCGv_ptr t_za, t_pg;
37
TCGv_i64 addr;
38
- int svl, desc = 0;
39
+ uint32_t desc;
40
bool be = s->be_data == MO_BE;
41
bool mte = s->mte_active[0];
42
43
@@ -XXX,XX +XXX,XX @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
44
tcg_gen_shli_i64(addr, cpu_reg(s, a->rm), a->esz);
45
tcg_gen_add_i64(addr, addr, cpu_reg_sp(s, a->rn));
46
47
- if (mte) {
48
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
51
- desc = FIELD_DP32(desc, MTEDESC, WRITE, a->st);
52
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << a->esz) - 1);
53
- desc <<= SVE_MTEDESC_SHIFT;
54
- } else {
55
+ if (!mte) {
56
addr = clean_data_tbi(s, addr);
57
}
58
- svl = streaming_vec_reg_size(s);
59
- desc = simd_desc(svl, svl, desc);
23
+
60
+
24
+ bool man_start_com;
61
+ desc = make_svemte_desc(s, streaming_vec_reg_size(s), 1, a->esz, a->st, 0);
62
63
fns[a->esz][be][a->v][mte][a->st](tcg_env, t_za, t_pg, addr,
64
tcg_constant_i32(desc));
65
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/tcg/translate-sve.c
68
+++ b/target/arm/tcg/translate-sve.c
69
@@ -XXX,XX +XXX,XX @@ static const uint8_t dtype_esz[16] = {
70
3, 2, 1, 3
25
};
71
};
26
72
27
typedef struct {
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
28
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
74
- int dtype, uint32_t mte_n, bool is_write,
29
index XXXXXXX..XXXXXXX 100644
75
- gen_helper_gvec_mem *fn)
30
--- a/hw/ssi/xilinx_spips.c
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
31
+++ b/hw/ssi/xilinx_spips.c
77
+ uint32_t msz, bool is_write, uint32_t data)
32
@@ -XXX,XX +XXX,XX @@
78
{
33
FIELD(CMND, DUMMY_CYCLES, 2, 6)
79
- unsigned vsz = vec_full_reg_size(s);
34
#define R_CMND_DMA_EN (1 << 1)
80
- TCGv_ptr t_pg;
35
#define R_CMND_PUSH_WAIT (1 << 0)
81
uint32_t sizem1;
36
+#define R_TRANSFER_SIZE (0xc4 / 4)
82
- int desc = 0;
37
#define R_LQSPI_STS (0xA4 / 4)
83
+ uint32_t desc = 0;
38
#define LQSPI_STS_WR_RECVD (1 << 1)
84
39
85
- assert(mte_n >= 1 && mte_n <= 4);
40
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
41
s->link_state_next_when = 0;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
42
s->snoop_state = SNOOP_CHECKING;
88
+ assert(nregs >= 1 && nregs <= 4);
43
s->cmd_dummies = 0;
89
+ sizem1 = (nregs << msz) - 1;
44
+ s->man_start_com = false;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
45
xilinx_spips_update_ixr(s);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
46
xilinx_spips_update_cs_lines(s);
92
+
47
}
93
if (s->mte_active[0]) {
48
@@ -XXX,XX +XXX,XX @@ static inline void tx_data_bytes(Fifo8 *fifo, uint32_t value, int num, bool be)
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
49
}
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
50
}
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
51
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
52
+static void xilinx_spips_check_zero_pump(XilinxSPIPS *s)
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
53
+{
99
desc <<= SVE_MTEDESC_SHIFT;
54
+ if (!s->regs[R_TRANSFER_SIZE]) {
100
- } else {
55
+ return;
56
+ }
101
+ }
57
+ if (!fifo8_is_empty(&s->tx_fifo) && s->regs[R_CMND] & R_CMND_PUSH_WAIT) {
102
+ return simd_desc(vsz, vsz, desc | data);
58
+ return;
59
+ }
60
+ /*
61
+ * The zero pump must never fill tx fifo such that rx overflow is
62
+ * possible
63
+ */
64
+ while (s->regs[R_TRANSFER_SIZE] &&
65
+ s->rx_fifo.num + s->tx_fifo.num < RXFF_A_Q - 3) {
66
+ /* endianess just doesn't matter when zero pumping */
67
+ tx_data_bytes(&s->tx_fifo, 0, 4, false);
68
+ s->regs[R_TRANSFER_SIZE] &= ~0x03ull;
69
+ s->regs[R_TRANSFER_SIZE] -= 4;
70
+ }
71
+}
103
+}
72
+
104
+
73
+static void xilinx_spips_check_flush(XilinxSPIPS *s)
105
+static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
106
+ int dtype, uint32_t nregs, bool is_write,
107
+ gen_helper_gvec_mem *fn)
74
+{
108
+{
75
+ if (s->man_start_com ||
109
+ TCGv_ptr t_pg;
76
+ (!fifo8_is_empty(&s->tx_fifo) &&
110
+ uint32_t desc;
77
+ !(s->regs[R_CONFIG] & MAN_START_EN))) {
78
+ xilinx_spips_check_zero_pump(s);
79
+ xilinx_spips_flush_txfifo(s);
80
+ }
81
+ if (fifo8_is_empty(&s->tx_fifo) && !s->regs[R_TRANSFER_SIZE]) {
82
+ s->man_start_com = false;
83
+ }
84
+ xilinx_spips_update_ixr(s);
85
+}
86
+
111
+
87
static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
112
+ if (!s->mte_active[0]) {
113
addr = clean_data_tbi(s, addr);
114
}
115
116
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
117
* registers as pointers, so encode the regno into the data field.
118
* For consistency, do this even for LD1.
119
*/
120
- desc = simd_desc(vsz, vsz, zt | desc);
121
+ desc = make_svemte_desc(s, vec_full_reg_size(s), nregs,
122
+ dtype_msz(dtype), is_write, zt);
123
t_pg = tcg_temp_new_ptr();
124
125
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
126
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpz(DisasContext *s, int zt, int pg, int zm,
127
int scale, TCGv_i64 scalar, int msz, bool is_write,
128
gen_helper_gvec_mem_scatter *fn)
88
{
129
{
89
int i;
130
- unsigned vsz = vec_full_reg_size(s);
90
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
91
uint64_t value, unsigned size)
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
92
{
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
93
int mask = ~0;
134
- int desc = 0;
94
- int man_start_com = 0;
135
-
95
XilinxSPIPS *s = opaque;
136
- if (s->mte_active[0]) {
96
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
97
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr, (unsigned)value);
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
98
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
99
switch (addr) {
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
100
case R_CONFIG:
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
101
mask = ~(R_CONFIG_RSVD | MAN_START_COM);
142
- desc <<= SVE_MTEDESC_SHIFT;
102
- if (value & MAN_START_COM) {
103
- man_start_com = 1;
104
+ if ((value & MAN_START_COM) && (s->regs[R_CONFIG] & MAN_START_EN)) {
105
+ s->man_start_com = true;
106
}
107
break;
108
case R_INTR_STATUS:
109
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
110
s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
111
no_reg_update:
112
xilinx_spips_update_cs_lines(s);
113
- if ((man_start_com && s->regs[R_CONFIG] & MAN_START_EN) ||
114
- (fifo8_is_empty(&s->tx_fifo) && s->regs[R_CONFIG] & MAN_START_EN)) {
115
- xilinx_spips_flush_txfifo(s);
116
- }
143
- }
117
+ xilinx_spips_check_flush(s);
144
- desc = simd_desc(vsz, vsz, desc | scale);
118
xilinx_spips_update_cs_lines(s);
145
+ uint32_t desc;
119
xilinx_spips_update_ixr(s);
146
147
tcg_gen_addi_ptr(t_pg, tcg_env, pred_full_reg_offset(s, pg));
148
tcg_gen_addi_ptr(t_zm, tcg_env, vec_full_reg_offset(s, zm));
149
tcg_gen_addi_ptr(t_zt, tcg_env, vec_full_reg_offset(s, zt));
150
+
151
+ desc = make_svemte_desc(s, vec_full_reg_size(s), 1, msz, is_write, scale);
152
fn(tcg_env, t_zt, t_pg, t_zm, scalar, tcg_constant_i32(desc));
120
}
153
}
154
121
--
155
--
122
2.7.4
156
2.34.1
123
124
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Now that do_ats_write() is entirely in control of whether to
3
These functions "use the standard load helpers", but
4
generate a 32-bit PAR or a 64-bit PAR, we can make it use the
4
fail to clean_data_tbi or populate mtedesc.
5
correct (complicated) condition for doing so.
6
5
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Cc: qemu-stable@nongnu.org
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
12
Message-id: 1512503192-2239-13-git-send-email-peter.maydell@linaro.org
13
[PMM: Rebased Edgar's patch on top of get_phys_addr() refactoring;
14
use arm_s1_regime_using_lpae_format() rather than
15
regime_using_lpae_format() because the latter will assert
16
if passed ARMMMUIdx_S12NSE0 or ARMMMUIdx_S12NSE1;
17
updated commit message appropriately]
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
---
12
---
20
target/arm/helper.c | 33 +++++++++++++++++++++++++++++----
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
21
1 file changed, 29 insertions(+), 4 deletions(-)
14
1 file changed, 13 insertions(+), 2 deletions(-)
22
15
23
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/target/arm/helper.c
18
--- a/target/arm/tcg/translate-sve.c
26
+++ b/target/arm/helper.c
19
+++ b/target/arm/tcg/translate-sve.c
27
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
28
int prot;
21
unsigned vsz = vec_full_reg_size(s);
29
bool ret;
22
TCGv_ptr t_pg;
30
uint64_t par64;
23
int poff;
31
+ bool format64 = false;
24
+ uint32_t desc;
32
MemTxAttrs attrs = {};
25
33
ARMMMUFaultInfo fi = {};
26
/* Load the first quadword using the normal predicated load helpers. */
34
ARMCacheAttrs cacheattrs = {};
27
+ if (!s->mte_active[0]) {
35
28
+ addr = clean_data_tbi(s, addr);
36
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
37
&prot, &page_size, &fi, &cacheattrs);
38
- /* TODO: this is not the correct condition to use to decide whether
39
- * to report a PAR in 64-bit or 32-bit format.
40
- */
41
- if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
42
+
43
+ if (is_a64(env)) {
44
+ format64 = true;
45
+ } else if (arm_feature(env, ARM_FEATURE_LPAE)) {
46
+ /*
47
+ * ATS1Cxx:
48
+ * * TTBCR.EAE determines whether the result is returned using the
49
+ * 32-bit or the 64-bit PAR format
50
+ * * Instructions executed in Hyp mode always use the 64bit format
51
+ *
52
+ * ATS1S2NSOxx uses the 64bit format if any of the following is true:
53
+ * * The Non-secure TTBCR.EAE bit is set to 1
54
+ * * The implementation includes EL2, and the value of HCR.VM is 1
55
+ *
56
+ * ATS1Hx always uses the 64bit format (not supported yet).
57
+ */
58
+ format64 = arm_s1_regime_using_lpae_format(env, mmu_idx);
59
+
60
+ if (arm_feature(env, ARM_FEATURE_EL2)) {
61
+ if (mmu_idx == ARMMMUIdx_S12NSE0 || mmu_idx == ARMMMUIdx_S12NSE1) {
62
+ format64 |= env->cp15.hcr_el2 & HCR_VM;
63
+ } else {
64
+ format64 |= arm_current_el(env) == 2;
65
+ }
66
+ }
67
+ }
29
+ }
68
+
30
+
69
+ if (format64) {
31
poff = pred_full_reg_offset(s, pg);
70
/* Create a 64-bit PAR */
32
if (vsz > 16) {
71
par64 = (1 << 11); /* LPAE bit always set */
33
/*
72
if (!ret) {
34
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
35
36
gen_helper_gvec_mem *fn
37
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
38
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(16, 16, zt)));
39
+ desc = make_svemte_desc(s, 16, 1, dtype_msz(dtype), false, zt);
40
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
41
42
/* Replicate that first quadword. */
43
if (vsz > 16) {
44
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
45
unsigned vsz_r32;
46
TCGv_ptr t_pg;
47
int poff, doff;
48
+ uint32_t desc;
49
50
if (vsz < 32) {
51
/*
52
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
53
}
54
55
/* Load the first octaword using the normal predicated load helpers. */
56
+ if (!s->mte_active[0]) {
57
+ addr = clean_data_tbi(s, addr);
58
+ }
59
60
poff = pred_full_reg_offset(s, pg);
61
if (vsz > 32) {
62
@@ -XXX,XX +XXX,XX @@ static void do_ldro(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
63
64
gen_helper_gvec_mem *fn
65
= ldr_fns[s->mte_active[0]][s->be_data == MO_BE][dtype][0];
66
- fn(tcg_env, t_pg, addr, tcg_constant_i32(simd_desc(32, 32, zt)));
67
+ desc = make_svemte_desc(s, 32, 1, dtype_msz(dtype), false, zt);
68
+ fn(tcg_env, t_pg, addr, tcg_constant_i32(desc));
69
70
/*
71
* Replicate that first octaword.
73
--
72
--
74
2.7.4
73
2.34.1
75
76
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Add support for the ZynqMP QSPI (consisting of the Generic QSPI and Legacy
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
QSPI) and connect Numonyx n25q512a11 flashes to it.
5
4
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
5
Cc: qemu-stable@nongnu.org
7
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
11
Message-id: 20171126231634.9531-14-frasse.iglesias@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
11
---
14
include/hw/arm/xlnx-zynqmp.h | 5 +++++
12
target/arm/tcg/sme_helper.c | 8 ++++----
15
hw/arm/xlnx-zcu102.c | 23 +++++++++++++++++++++++
13
target/arm/tcg/sve_helper.c | 12 ++++++------
16
hw/arm/xlnx-zynqmp.c | 26 ++++++++++++++++++++++++++
14
2 files changed, 10 insertions(+), 10 deletions(-)
17
3 files changed, 54 insertions(+)
18
15
19
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
20
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/arm/xlnx-zynqmp.h
18
--- a/target/arm/tcg/sme_helper.c
22
+++ b/include/hw/arm/xlnx-zynqmp.h
19
+++ b/target/arm/tcg/sme_helper.c
23
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
24
#define XLNX_ZYNQMP_NUM_SDHCI 2
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
25
#define XLNX_ZYNQMP_NUM_SPIS 2
22
26
23
/* Perform gross MTE suppression early. */
27
+#define XLNX_ZYNQMP_NUM_QSPI_BUS 2
24
- if (!tbi_check(desc, bit55) ||
28
+#define XLNX_ZYNQMP_NUM_QSPI_BUS_CS 2
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
29
+#define XLNX_ZYNQMP_NUM_QSPI_FLASH 4
26
+ if (!tbi_check(mtedesc, bit55) ||
30
+
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
31
#define XLNX_ZYNQMP_NUM_OCM_BANKS 4
28
mtedesc = 0;
32
#define XLNX_ZYNQMP_OCM_RAM_0_ADDRESS 0xFFFC0000
29
}
33
#define XLNX_ZYNQMP_OCM_RAM_SIZE 0x10000
30
34
@@ -XXX,XX +XXX,XX @@ typedef struct XlnxZynqMPState {
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
35
SysbusAHCIState sata;
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
36
SDHCIState sdhci[XLNX_ZYNQMP_NUM_SDHCI];
33
37
XilinxSPIPS spi[XLNX_ZYNQMP_NUM_SPIS];
34
/* Perform gross MTE suppression early. */
38
+ XlnxZynqMPQSPIPS qspi;
35
- if (!tbi_check(desc, bit55) ||
39
XlnxDPState dp;
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
40
XlnxDPDMAState dpdma;
37
+ if (!tbi_check(mtedesc, bit55) ||
41
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
42
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
39
mtedesc = 0;
40
}
41
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
43
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/arm/xlnx-zcu102.c
44
--- a/target/arm/tcg/sve_helper.c
45
+++ b/hw/arm/xlnx-zcu102.c
45
+++ b/target/arm/tcg/sve_helper.c
46
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(XlnxZCU102 *s, MachineState *machine)
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
47
sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.spi[i]), 1, cs_line);
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
48
49
/* Perform gross MTE suppression early. */
50
- if (!tbi_check(desc, bit55) ||
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
52
+ if (!tbi_check(mtedesc, bit55) ||
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
54
mtedesc = 0;
48
}
55
}
49
56
50
+ for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_FLASH; i++) {
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
51
+ SSIBus *spi_bus;
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
52
+ DeviceState *flash_dev;
59
53
+ qemu_irq cs_line;
60
/* Perform gross MTE suppression early. */
54
+ DriveInfo *dinfo = drive_get_next(IF_MTD);
61
- if (!tbi_check(desc, bit55) ||
55
+ int bus = i / XLNX_ZYNQMP_NUM_QSPI_BUS_CS;
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
56
+ gchar *bus_name = g_strdup_printf("qspi%d", bus);
63
+ if (!tbi_check(mtedesc, bit55) ||
57
+
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
58
+ spi_bus = (SSIBus *)qdev_get_child_bus(DEVICE(&s->soc), bus_name);
65
mtedesc = 0;
59
+ g_free(bus_name);
60
+
61
+ flash_dev = ssi_create_slave_no_init(spi_bus, "n25q512a11");
62
+ if (dinfo) {
63
+ qdev_prop_set_drive(flash_dev, "drive", blk_by_legacy_dinfo(dinfo),
64
+ &error_fatal);
65
+ }
66
+ qdev_init_nofail(flash_dev);
67
+
68
+ cs_line = qdev_get_gpio_in_named(flash_dev, SSI_GPIO_CS, 0);
69
+
70
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->soc.qspi), i + 1, cs_line);
71
+ }
72
+
73
/* TODO create and connect IDE devices for ide_drive_get() */
74
75
xlnx_zcu102_binfo.ram_size = ram_size;
76
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
77
index XXXXXXX..XXXXXXX 100644
78
--- a/hw/arm/xlnx-zynqmp.c
79
+++ b/hw/arm/xlnx-zynqmp.c
80
@@ -XXX,XX +XXX,XX @@
81
#define SATA_ADDR 0xFD0C0000
82
#define SATA_NUM_PORTS 2
83
84
+#define QSPI_ADDR 0xff0f0000
85
+#define LQSPI_ADDR 0xc0000000
86
+#define QSPI_IRQ 15
87
+
88
#define DP_ADDR 0xfd4a0000
89
#define DP_IRQ 113
90
91
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_init(Object *obj)
92
qdev_set_parent_bus(DEVICE(&s->spi[i]), sysbus_get_default());
93
}
66
}
94
67
95
+ object_initialize(&s->qspi, sizeof(s->qspi), TYPE_XLNX_ZYNQMP_QSPIPS);
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
96
+ qdev_set_parent_bus(DEVICE(&s->qspi), sysbus_get_default());
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
97
+
70
98
object_initialize(&s->dp, sizeof(s->dp), TYPE_XLNX_DP);
71
/* Perform gross MTE suppression early. */
99
qdev_set_parent_bus(DEVICE(&s->dp), sysbus_get_default());
72
- if (!tbi_check(desc, bit55) ||
100
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
101
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_realize(DeviceState *dev, Error **errp)
74
+ if (!tbi_check(mtedesc, bit55) ||
102
g_free(bus_name);
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
76
mtedesc = 0;
103
}
77
}
104
78
105
+ object_property_set_bool(OBJECT(&s->qspi), true, "realized", &err);
106
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 0, QSPI_ADDR);
107
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->qspi), 1, LQSPI_ADDR);
108
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->qspi), 0, gic_spi[QSPI_IRQ]);
109
+
110
+ for (i = 0; i < XLNX_ZYNQMP_NUM_QSPI_BUS; i++) {
111
+ gchar *bus_name;
112
+ gchar *target_bus;
113
+
114
+ /* Alias controller SPI bus to the SoC itself */
115
+ bus_name = g_strdup_printf("qspi%d", i);
116
+ target_bus = g_strdup_printf("spi%d", i);
117
+ object_property_add_alias(OBJECT(s), bus_name,
118
+ OBJECT(&s->qspi), target_bus,
119
+ &error_abort);
120
+ g_free(bus_name);
121
+ g_free(target_bus);
122
+ }
123
+
124
object_property_set_bool(OBJECT(&s->dp), true, "realized", &err);
125
if (err) {
126
error_propagate(errp, err);
127
--
79
--
128
2.7.4
80
2.34.1
129
130
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
which sets .valid.unaligned to indicate that it should support
3
unaligned accesses and which does not also set .impl.unaligned to
4
indicate that its read and write functions can do the unaligned
5
handling themselves. This is a problem, because at the moment the
6
core memory system does not implement the support for handling
7
unaligned accesses by doing a series of aligned accesses and
8
combining them (system/memory.c:access_with_adjusted_size() has a
9
TODO comment noting this).
2
10
3
Update the reset value to match the latest ZynqMP register spec.
11
Fortunately raven_io_read() and raven_io_write() will correctly deal
12
with the case of being passed an unaligned address, so we can fix the
13
missing unaligned access support by setting .impl.unaligned in the
14
MemoryRegionOps struct.
4
15
5
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
6
Reviewed-by: KONRAD Frederic <frederic.konrad@adacore.com>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Message-id: c03e51d041db7f055596084891aeb1e856e32b9f.1513104804.git.alistair.francis@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
10
---
21
---
11
hw/ssi/xilinx_spips.c | 1 +
22
hw/pci-host/raven.c | 1 +
12
1 file changed, 1 insertion(+)
23
1 file changed, 1 insertion(+)
13
24
14
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
15
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/ssi/xilinx_spips.c
27
--- a/hw/pci-host/raven.c
17
+++ b/hw/ssi/xilinx_spips.c
28
+++ b/hw/pci-host/raven.c
18
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
19
s->regs[R_GQSPI_RX_THRESH] = 1;
30
.write = raven_io_write,
20
s->regs[R_GQSPI_GFIFO_THRESH] = 1;
31
.endianness = DEVICE_LITTLE_ENDIAN,
21
s->regs[R_GQSPI_IMR] = GQSPI_IXR_MASK;
32
.impl.max_access_size = 4,
22
+ s->regs[R_MOD_ID] = 0x01090101;
33
+ .impl.unaligned = true,
23
s->man_start_com_g = false;
34
.valid.unaligned = true,
24
s->gqspi_irqline = 0;
35
};
25
xlnx_zynqmp_qspips_update_ixr(s);
36
26
--
37
--
27
2.7.4
38
2.34.1
28
39
29
40
diff view generated by jsdifflib
1
Generalize nvic_sysreg_ns_ops so that we can pass it an
1
Suppress the deprecation warning when we're running under qtest,
2
arbitrary MemoryRegion which it will use as the underlying
2
to avoid "make check" including warning messages in its output.
3
register implementation to apply the NS-alias behaviour
4
to. We'll want this so we can do the same with systick.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 1512154296-5652-2-git-send-email-peter.maydell@linaro.org
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
9
---
7
---
10
hw/intc/armv7m_nvic.c | 10 +++++++---
8
hw/block/tc58128.c | 4 +++-
11
1 file changed, 7 insertions(+), 3 deletions(-)
9
1 file changed, 3 insertions(+), 1 deletion(-)
12
10
13
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/intc/armv7m_nvic.c
13
--- a/hw/block/tc58128.c
16
+++ b/hw/intc/armv7m_nvic.c
14
+++ b/hw/block/tc58128.c
17
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_ns_write(void *opaque, hwaddr addr,
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
18
uint64_t value, unsigned size,
16
19
MemTxAttrs attrs)
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
20
{
18
{
21
+ MemoryRegion *mr = opaque;
19
- warn_report_once("The TC58128 flash device is deprecated");
22
+
20
+ if (!qtest_enabled()) {
23
if (attrs.secure) {
21
+ warn_report_once("The TC58128 flash device is deprecated");
24
/* S accesses to the alias act like NS accesses to the real region */
22
+ }
25
attrs.secure = 0;
23
init_dev(&tc58128_devs[0], zone1);
26
- return nvic_sysreg_write(opaque, addr, value, size, attrs);
24
init_dev(&tc58128_devs[1], zone2);
27
+ return memory_region_dispatch_write(mr, addr, value, size, attrs);
25
return sh7750_register_io_device(s, &tc58128);
28
} else {
29
/* NS attrs are RAZ/WI for privileged, and BusFault for user */
30
if (attrs.user) {
31
@@ -XXX,XX +XXX,XX @@ static MemTxResult nvic_sysreg_ns_read(void *opaque, hwaddr addr,
32
uint64_t *data, unsigned size,
33
MemTxAttrs attrs)
34
{
35
+ MemoryRegion *mr = opaque;
36
+
37
if (attrs.secure) {
38
/* S accesses to the alias act like NS accesses to the real region */
39
attrs.secure = 0;
40
- return nvic_sysreg_read(opaque, addr, data, size, attrs);
41
+ return memory_region_dispatch_read(mr, addr, data, size, attrs);
42
} else {
43
/* NS attrs are RAZ/WI for privileged, and BusFault for user */
44
if (attrs.user) {
45
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
46
47
if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
48
memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
49
- &nvic_sysreg_ns_ops, s,
50
+ &nvic_sysreg_ns_ops, &s->sysregmem,
51
"nvic_sysregs_ns", 0x1000);
52
memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
53
}
54
--
26
--
55
2.7.4
27
2.34.1
56
28
57
29
diff view generated by jsdifflib
1
From: Alistair Francis <alistair.francis@xilinx.com>
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
because we already get the coverage of those tests via qtests_arm,
3
and we don't want to use extra CI minutes testing them twice.
2
4
3
Following the ZynqMP register spec let's ensure that all reset values
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
4
are set.
6
that change.
5
7
6
Signed-off-by: Alistair Francis <alistair.francis@xilinx.com>
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Message-id: 19836f3e0a298b13343c5a59c87425355e7fd8bd.1513104804.git.alistair.francis@xilinx.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
10
---
12
---
11
include/hw/ssi/xilinx_spips.h | 2 +-
13
tests/qtest/meson.build | 1 -
12
hw/ssi/xilinx_spips.c | 35 ++++++++++++++++++++++++++++++-----
14
1 file changed, 1 deletion(-)
13
2 files changed, 31 insertions(+), 6 deletions(-)
14
15
15
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
16
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/ssi/xilinx_spips.h
18
--- a/tests/qtest/meson.build
18
+++ b/include/hw/ssi/xilinx_spips.h
19
+++ b/tests/qtest/meson.build
19
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
20
typedef struct XilinxSPIPS XilinxSPIPS;
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
21
22
(config_all_accel.has_key('CONFIG_TCG') and \
22
#define XLNX_SPIPS_R_MAX (0x100 / 4)
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
23
-#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
24
+#define XLNX_ZYNQMP_SPIPS_R_MAX (0x830 / 4)
25
['arm-cpu-features',
25
26
'numa-test',
26
/* Bite off 4k chunks at a time */
27
'boot-serial-test',
27
#define LQSPI_CACHE_SIZE 1024
28
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
29
index XXXXXXX..XXXXXXX 100644
30
--- a/hw/ssi/xilinx_spips.c
31
+++ b/hw/ssi/xilinx_spips.c
32
@@ -XXX,XX +XXX,XX @@
33
34
/* interrupt mechanism */
35
#define R_INTR_STATUS (0x04 / 4)
36
+#define R_INTR_STATUS_RESET (0x104)
37
#define R_INTR_EN (0x08 / 4)
38
#define R_INTR_DIS (0x0C / 4)
39
#define R_INTR_MASK (0x10 / 4)
40
@@ -XXX,XX +XXX,XX @@
41
#define R_SLAVE_IDLE_COUNT (0x24 / 4)
42
#define R_TX_THRES (0x28 / 4)
43
#define R_RX_THRES (0x2C / 4)
44
+#define R_GPIO (0x30 / 4)
45
+#define R_LPBK_DLY_ADJ (0x38 / 4)
46
+#define R_LPBK_DLY_ADJ_RESET (0x33)
47
#define R_TXD1 (0x80 / 4)
48
#define R_TXD2 (0x84 / 4)
49
#define R_TXD3 (0x88 / 4)
50
@@ -XXX,XX +XXX,XX @@
51
#define R_GQSPI_IER (0x108 / 4)
52
#define R_GQSPI_IDR (0x10c / 4)
53
#define R_GQSPI_IMR (0x110 / 4)
54
+#define R_GQSPI_IMR_RESET (0xfbe)
55
#define R_GQSPI_TX_THRESH (0x128 / 4)
56
#define R_GQSPI_RX_THRESH (0x12c / 4)
57
+#define R_GQSPI_GPIO (0x130 / 4)
58
+#define R_GQSPI_LPBK_DLY_ADJ (0x138 / 4)
59
+#define R_GQSPI_LPBK_DLY_ADJ_RESET (0x33)
60
#define R_GQSPI_CNFG (0x100 / 4)
61
FIELD(GQSPI_CNFG, MODE_EN, 30, 2)
62
FIELD(GQSPI_CNFG, GEN_FIFO_START_MODE, 29, 1)
63
@@ -XXX,XX +XXX,XX @@
64
FIELD(GQSPI_GF_SNAPSHOT, EXPONENT, 9, 1)
65
FIELD(GQSPI_GF_SNAPSHOT, DATA_XFER, 8, 1)
66
FIELD(GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA, 0, 8)
67
-#define R_GQSPI_MOD_ID (0x168 / 4)
68
-#define R_GQSPI_MOD_ID_VALUE 0x010A0000
69
+#define R_GQSPI_MOD_ID (0x1fc / 4)
70
+#define R_GQSPI_MOD_ID_RESET (0x10a0000)
71
+
72
+#define R_QSPIDMA_DST_CTRL (0x80c / 4)
73
+#define R_QSPIDMA_DST_CTRL_RESET (0x803ffa00)
74
+#define R_QSPIDMA_DST_I_MASK (0x820 / 4)
75
+#define R_QSPIDMA_DST_I_MASK_RESET (0xfe)
76
+#define R_QSPIDMA_DST_CTRL2 (0x824 / 4)
77
+#define R_QSPIDMA_DST_CTRL2_RESET (0x081bfff8)
78
+
79
/* size of TXRX FIFOs */
80
#define RXFF_A (128)
81
#define TXFF_A (128)
82
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
83
fifo8_reset(&s->rx_fifo_g);
84
fifo8_reset(&s->rx_fifo_g);
85
fifo32_reset(&s->fifo_g);
86
+ s->regs[R_INTR_STATUS] = R_INTR_STATUS_RESET;
87
+ s->regs[R_GPIO] = 1;
88
+ s->regs[R_LPBK_DLY_ADJ] = R_LPBK_DLY_ADJ_RESET;
89
+ s->regs[R_GQSPI_GFIFO_THRESH] = 0x10;
90
+ s->regs[R_MOD_ID] = 0x01090101;
91
+ s->regs[R_GQSPI_IMR] = R_GQSPI_IMR_RESET;
92
s->regs[R_GQSPI_TX_THRESH] = 1;
93
s->regs[R_GQSPI_RX_THRESH] = 1;
94
- s->regs[R_GQSPI_GFIFO_THRESH] = 1;
95
- s->regs[R_GQSPI_IMR] = GQSPI_IXR_MASK;
96
- s->regs[R_MOD_ID] = 0x01090101;
97
+ s->regs[R_GQSPI_GPIO] = 1;
98
+ s->regs[R_GQSPI_LPBK_DLY_ADJ] = R_GQSPI_LPBK_DLY_ADJ_RESET;
99
+ s->regs[R_GQSPI_MOD_ID] = R_GQSPI_MOD_ID_RESET;
100
+ s->regs[R_QSPIDMA_DST_CTRL] = R_QSPIDMA_DST_CTRL_RESET;
101
+ s->regs[R_QSPIDMA_DST_I_MASK] = R_QSPIDMA_DST_I_MASK_RESET;
102
+ s->regs[R_QSPIDMA_DST_CTRL2] = R_QSPIDMA_DST_CTRL2_RESET;
103
s->man_start_com_g = false;
104
s->gqspi_irqline = 0;
105
xlnx_zynqmp_qspips_update_ixr(s);
106
--
28
--
107
2.7.4
29
2.34.1
108
30
109
31
diff view generated by jsdifflib
1
In do_ats_write(), rather than using the FSR value from get_phys_addr(),
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
construct the PAR values using the information in the ARMMMUFaultInfo
2
entry for a new timer to it.
3
struct. This allows us to create a PAR of the correct format regardless
4
of what the translation table format is.
5
6
For the moment we leave the condition for "when should this be a
7
64 bit PAR" as it was previously; this will need to be fixed to
8
properly support AArch32 Hyp mode.
9
3
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
13
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
14
Message-id: 1512503192-2239-11-git-send-email-peter.maydell@linaro.org
15
---
7
---
16
target/arm/helper.c | 16 ++++++++++------
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
17
1 file changed, 10 insertions(+), 6 deletions(-)
9
1 file changed, 2 insertions(+)
18
10
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
20
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
22
+++ b/target/arm/helper.c
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
23
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
15
@@ -1 +1,3 @@
24
hwaddr phys_addr;
16
/* List of comma-separated changed AML files to ignore */
25
target_ulong page_size;
17
+"tests/data/acpi/virt/FACP",
26
int prot;
18
+"tests/data/acpi/virt/GTDT",
27
- uint32_t fsr;
28
+ uint32_t fsr_unused;
29
bool ret;
30
uint64_t par64;
31
MemTxAttrs attrs = {};
32
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
33
ARMCacheAttrs cacheattrs = {};
34
35
ret = get_phys_addr(env, value, access_type, mmu_idx, &phys_addr, &attrs,
36
- &prot, &page_size, &fsr, &fi, &cacheattrs);
37
+ &prot, &page_size, &fsr_unused, &fi, &cacheattrs);
38
+ /* TODO: this is not the correct condition to use to decide whether
39
+ * to report a PAR in 64-bit or 32-bit format.
40
+ */
41
if (arm_s1_regime_using_lpae_format(env, mmu_idx)) {
42
- /* fsr is a DFSR/IFSR value for the long descriptor
43
- * translation table format, but with WnR always clear.
44
- * Convert it to a 64-bit PAR.
45
- */
46
+ /* Create a 64-bit PAR */
47
par64 = (1 << 11); /* LPAE bit always set */
48
if (!ret) {
49
par64 |= phys_addr & ~0xfffULL;
50
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
51
par64 |= (uint64_t)cacheattrs.attrs << 56; /* ATTR */
52
par64 |= cacheattrs.shareability << 7; /* SH */
53
} else {
54
+ uint32_t fsr = arm_fi_to_lfsc(&fi);
55
+
56
par64 |= 1; /* F */
57
par64 |= (fsr & 0x3f) << 1; /* FS */
58
/* Note that S2WLK and FSTAGE are always zero, because we don't
59
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
60
par64 |= (1 << 9); /* NS */
61
}
62
} else {
63
+ uint32_t fsr = arm_fi_to_sfsc(&fi);
64
+
65
par64 = ((fsr & (1 << 10)) >> 5) | ((fsr & (1 << 12)) >> 6) |
66
((fsr & 0xf) << 1) | 1;
67
}
68
--
19
--
69
2.7.4
20
2.34.1
70
71
diff view generated by jsdifflib
1
Make get_phys_addr_v5() return a fault type in the ARMMMUFaultInfo
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
structure, which we convert to the FSC at the callsite.
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
CPU model, but never wired up its IRQ line to the GIC.
4
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
interrupt or not, since it always creates the outbound IRQ line).
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
9
The DTB binding is documented in the kernel's
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
and the ACPI table entries are documented in the ACPI specification
12
version 6.3 or later.
13
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
FADT table rev to show that we might be using 6.3 features.
16
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
versions prior to edk2-stable202311, for users who use the virt board
19
with 'virtualization=on' to enable EL2 emulation and are booting an
20
EDK2 guest BIOS, if that EDK2 has assertions enabled. The effect is
21
that EDK2 will assert on bootup:
22
23
ASSERT [ArmTimerDxe] /home/kraxel/projects/qemu/roms/edk2/ArmVirtPkg/Library/ArmVirtTimerFdtClientLib/ArmVirtTimerFdtClientLib.c(72): PropSize == 36 || PropSize == 48
24
25
If you see that assertion you should do one of:
26
* update your EDK2 binaries to edk2-stable202311 or newer
27
* use the 'virt-8.2' versioned machine type
28
* not use 'virtualization=on'
29
30
(The versions shipped with QEMU itself have the fix.)
3
31
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-4-git-send-email-peter.maydell@linaro.org
9
---
35
---
10
target/arm/helper.c | 33 ++++++++++++++++++---------------
36
include/hw/arm/virt.h | 2 ++
11
1 file changed, 18 insertions(+), 15 deletions(-)
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
12
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
3 files changed, 67 insertions(+), 15 deletions(-)
40
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
14
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
43
--- a/include/hw/arm/virt.h
16
+++ b/target/arm/helper.c
44
+++ b/include/hw/arm/virt.h
17
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
18
static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
47
bool no_cpu_topology;
20
hwaddr *phys_ptr, int *prot,
48
bool no_tcg_lpa2;
21
- target_ulong *page_size, uint32_t *fsr,
49
+ bool no_ns_el2_virt_timer_irq;
22
+ target_ulong *page_size,
50
};
23
ARMMMUFaultInfo *fi)
51
52
struct VirtMachineState {
53
@@ -XXX,XX +XXX,XX @@ struct VirtMachineState {
54
PCIBus *bus;
55
char *oem_id;
56
char *oem_table_id;
57
+ bool ns_el2_virt_timer_irq;
58
};
59
60
#define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM)
61
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
62
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/virt-acpi-build.c
64
+++ b/hw/arm/virt-acpi-build.c
65
@@ -XXX,XX +XXX,XX @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
66
}
67
68
/*
69
- * ACPI spec, Revision 5.1
70
- * 5.2.24 Generic Timer Description Table (GTDT)
71
+ * ACPI spec, Revision 6.5
72
+ * 5.2.25 Generic Timer Description Table (GTDT)
73
*/
74
static void
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
78
1 : /* Interrupt is Edge triggered */
79
0; /* Interrupt is Level triggered */
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
82
.oem_table_id = vms->oem_table_id };
83
84
acpi_table_begin(&table, table_data);
85
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
86
build_append_int_noprefix(table_data, 0, 4);
87
/* Platform Timer Offset */
88
build_append_int_noprefix(table_data, 0, 4);
89
-
90
+ if (vms->ns_el2_virt_timer_irq) {
91
+ /* Virtual EL2 Timer GSIV */
92
+ build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_VIRT_IRQ, 4);
93
+ /* Virtual EL2 Timer Flags */
94
+ build_append_int_noprefix(table_data, irqflags, 4);
95
+ } else {
96
+ build_append_int_noprefix(table_data, 0, 4);
97
+ build_append_int_noprefix(table_data, 0, 4);
98
+ }
99
acpi_table_end(linker, &table);
100
}
101
102
@@ -XXX,XX +XXX,XX @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
103
static void build_fadt_rev6(GArray *table_data, BIOSLinker *linker,
104
VirtMachineState *vms, unsigned dsdt_tbl_offset)
24
{
105
{
25
CPUState *cs = CPU(arm_env_get_cpu(env));
106
- /* ACPI v6.0 */
26
- int code;
107
+ /* ACPI v6.3 */
27
+ int level = 1;
108
AcpiFadtData fadt = {
28
uint32_t table;
109
.rev = 6,
29
uint32_t desc;
110
- .minor_ver = 0,
30
int type;
111
+ .minor_ver = 3,
31
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
32
/* Lookup l1 descriptor. */
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
33
if (!get_level1_table_address(env, mmu_idx, &table, address)) {
114
};
34
/* Section translation fault if page walk is disabled by PD0 or PD1 */
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
35
- code = 5;
116
index XXXXXXX..XXXXXXX 100644
36
+ fi->type = ARMFault_Translation;
117
--- a/hw/arm/virt.c
37
goto do_fault;
118
+++ b/hw/arm/virt.c
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
120
qemu_fdt_setprop(ms->fdt, node, "rng-seed", seed.rng, sizeof(seed.rng));
121
}
122
123
+/*
124
+ * The CPU object always exposes the NS EL2 virt timer IRQ line,
125
+ * but we don't want to advertise it to the guest in the dtb or ACPI
126
+ * table unless it's really going to do something.
127
+ */
128
+static bool ns_el2_virt_timer_present(void)
129
+{
130
+ ARMCPU *cpu = ARM_CPU(qemu_get_cpu(0));
131
+ CPUARMState *env = &cpu->env;
132
+
133
+ return arm_feature(env, ARM_FEATURE_AARCH64) &&
134
+ arm_feature(env, ARM_FEATURE_EL2) && cpu_isar_feature(aa64_vh, cpu);
135
+}
136
+
137
static void create_fdt(VirtMachineState *vms)
138
{
139
MachineState *ms = MACHINE(vms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
141
"arm,armv7-timer");
38
}
142
}
39
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
41
domain_prot = (dacr >> (domain * 2)) & 3;
145
- GIC_FDT_IRQ_TYPE_PPI,
42
if (type == 0) {
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
43
/* Section translation fault. */
147
- GIC_FDT_IRQ_TYPE_PPI,
44
- code = 5;
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
45
+ fi->type = ARMFault_Translation;
149
- GIC_FDT_IRQ_TYPE_PPI,
46
goto do_fault;
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
151
- GIC_FDT_IRQ_TYPE_PPI,
152
- INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
153
+ if (vms->ns_el2_virt_timer_irq) {
154
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
155
+ GIC_FDT_IRQ_TYPE_PPI,
156
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
157
+ GIC_FDT_IRQ_TYPE_PPI,
158
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
159
+ GIC_FDT_IRQ_TYPE_PPI,
160
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
161
+ GIC_FDT_IRQ_TYPE_PPI,
162
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags,
163
+ GIC_FDT_IRQ_TYPE_PPI,
164
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_VIRT_IRQ), irqflags);
165
+ } else {
166
+ qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
167
+ GIC_FDT_IRQ_TYPE_PPI,
168
+ INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
169
+ GIC_FDT_IRQ_TYPE_PPI,
170
+ INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
171
+ GIC_FDT_IRQ_TYPE_PPI,
172
+ INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
173
+ GIC_FDT_IRQ_TYPE_PPI,
174
+ INTID_TO_PPI(ARCH_TIMER_NS_EL2_IRQ), irqflags);
175
+ }
176
}
177
178
static void fdt_add_cpu_nodes(const VirtMachineState *vms)
179
@@ -XXX,XX +XXX,XX @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
180
[GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
181
[GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
182
[GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ,
183
+ [GTIMER_HYPVIRT] = ARCH_TIMER_NS_EL2_VIRT_IRQ,
184
};
185
186
for (unsigned irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
187
@@ -XXX,XX +XXX,XX @@ static void machvirt_init(MachineState *machine)
188
qdev_realize(DEVICE(cpuobj), NULL, &error_fatal);
189
object_unref(cpuobj);
47
}
190
}
48
+ if (type != 2) {
191
+
49
+ level = 2;
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
50
+ }
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
51
if (domain_prot == 0 || domain_prot == 2) {
194
+ !vmc->no_ns_el2_virt_timer_irq;
52
- if (type == 2)
195
+
53
- code = 9; /* Section domain fault. */
196
fdt_add_timer_nodes(vms);
54
- else
197
fdt_add_cpu_nodes(vms);
55
- code = 11; /* Page domain fault. */
198
56
+ fi->type = ARMFault_Domain;
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
57
goto do_fault;
200
58
}
201
static void virt_machine_8_2_options(MachineClass *mc)
59
if (type == 2) {
202
{
60
/* 1Mb section. */
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
61
phys_addr = (desc & 0xfff00000) | (address & 0x000fffff);
204
+
62
ap = (desc >> 10) & 3;
205
virt_machine_9_0_options(mc);
63
- code = 13;
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
64
*page_size = 1024 * 1024;
207
+ /*
65
} else {
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
66
/* Lookup l2 entry. */
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
67
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
210
+ * guest BIOS binaries.)
68
mmu_idx, fi);
211
+ */
69
switch (desc & 3) {
212
+ vmc->no_ns_el2_virt_timer_irq = true;
70
case 0: /* Page translation fault. */
213
}
71
- code = 7;
214
DEFINE_VIRT_MACHINE(8, 2)
72
+ fi->type = ARMFault_Translation;
73
goto do_fault;
74
case 1: /* 64k page. */
75
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
76
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
77
/* UNPREDICTABLE in ARMv5; we choose to take a
78
* page translation fault.
79
*/
80
- code = 7;
81
+ fi->type = ARMFault_Translation;
82
goto do_fault;
83
}
84
} else {
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
86
/* Never happens, but compiler isn't smart enough to tell. */
87
abort();
88
}
89
- code = 15;
90
}
91
*prot = ap_to_rw_prot(env, mmu_idx, ap, domain_prot);
92
*prot |= *prot ? PAGE_EXEC : 0;
93
if (!(*prot & (1 << access_type))) {
94
/* Access permission fault. */
95
+ fi->type = ARMFault_Permission;
96
goto do_fault;
97
}
98
*phys_ptr = phys_addr;
99
return false;
100
do_fault:
101
- *fsr = code | (domain << 4);
102
+ fi->domain = domain;
103
+ fi->level = level;
104
return true;
105
}
106
107
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
108
return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr,
109
attrs, prot, page_size, fsr, fi);
110
} else {
111
- return get_phys_addr_v5(env, address, access_type, mmu_idx, phys_ptr,
112
- prot, page_size, fsr, fi);
113
+ bool ret = get_phys_addr_v5(env, address, access_type, mmu_idx,
114
+ phys_ptr, prot, page_size, fi);
115
+
116
+ *fsr = arm_fi_to_sfsc(fi);
117
+ return ret;
118
}
119
}
120
215
121
--
216
--
122
2.7.4
217
2.34.1
123
124
diff view generated by jsdifflib
1
Now that ARMMMUFaultInfo is guaranteed to have enough information
1
Update the virt golden reference files to say that the FACP is ACPI
2
to construct a fault status code, we can pass it in to the
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
deliver_fault() function and let it generate the correct type
3
virtual EL2 timer.
4
of FSR for the destination, rather than relying on the value
4
5
provided by get_phys_addr().
5
Diffs from iasl:
6
6
7
I don't think there are any cases the old code was getting
7
@@ -XXX,XX +XXX,XX @@
8
wrong, but this is more obviously correct.
8
/*
9
* Intel ACPI Component Architecture
10
* AML/ASL+ Disassembler version 20200925 (64-bit version)
11
* Copyright (c) 2000 - 2020 Intel Corporation
12
*
13
- * Disassembly of tests/data/acpi/virt/FACP, Mon Jan 22 13:48:40 2024
14
+ * Disassembly of /tmp/aml-W8RZH2, Mon Jan 22 13:48:40 2024
15
*
16
* ACPI Data Table [FACP]
17
*
18
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
19
*/
20
21
[000h 0000 4] Signature : "FACP" [Fixed ACPI Description Table (FADT)]
22
[004h 0004 4] Table Length : 00000114
23
[008h 0008 1] Revision : 06
24
-[009h 0009 1] Checksum : 15
25
+[009h 0009 1] Checksum : 12
26
[00Ah 0010 6] Oem ID : "BOCHS "
27
[010h 0016 8] Oem Table ID : "BXPC "
28
[018h 0024 4] Oem Revision : 00000001
29
[01Ch 0028 4] Asl Compiler ID : "BXPC"
30
[020h 0032 4] Asl Compiler Revision : 00000001
31
32
[024h 0036 4] FACS Address : 00000000
33
[028h 0040 4] DSDT Address : 00000000
34
[02Ch 0044 1] Model : 00
35
[02Dh 0045 1] PM Profile : 00 [Unspecified]
36
[02Eh 0046 2] SCI Interrupt : 0000
37
[030h 0048 4] SMI Command Port : 00000000
38
[034h 0052 1] ACPI Enable Value : 00
39
[035h 0053 1] ACPI Disable Value : 00
40
[036h 0054 1] S4BIOS Command : 00
41
[037h 0055 1] P-State Control : 00
42
@@ -XXX,XX +XXX,XX @@
43
Use APIC Physical Destination Mode (V4) : 0
44
Hardware Reduced (V5) : 1
45
Low Power S0 Idle (V5) : 0
46
47
[074h 0116 12] Reset Register : [Generic Address Structure]
48
[074h 0116 1] Space ID : 00 [SystemMemory]
49
[075h 0117 1] Bit Width : 00
50
[076h 0118 1] Bit Offset : 00
51
[077h 0119 1] Encoded Access Width : 00 [Undefined/Legacy]
52
[078h 0120 8] Address : 0000000000000000
53
54
[080h 0128 1] Value to cause reset : 00
55
[081h 0129 2] ARM Flags (decoded below) : 0003
56
PSCI Compliant : 1
57
Must use HVC for PSCI : 1
58
59
-[083h 0131 1] FADT Minor Revision : 00
60
+[083h 0131 1] FADT Minor Revision : 03
61
[084h 0132 8] FACS Address : 0000000000000000
62
[08Ch 0140 8] DSDT Address : 0000000000000000
63
[094h 0148 12] PM1A Event Block : [Generic Address Structure]
64
[094h 0148 1] Space ID : 00 [SystemMemory]
65
[095h 0149 1] Bit Width : 00
66
[096h 0150 1] Bit Offset : 00
67
[097h 0151 1] Encoded Access Width : 00 [Undefined/Legacy]
68
[098h 0152 8] Address : 0000000000000000
69
70
[0A0h 0160 12] PM1B Event Block : [Generic Address Structure]
71
[0A0h 0160 1] Space ID : 00 [SystemMemory]
72
[0A1h 0161 1] Bit Width : 00
73
[0A2h 0162 1] Bit Offset : 00
74
[0A3h 0163 1] Encoded Access Width : 00 [Undefined/Legacy]
75
[0A4h 0164 8] Address : 0000000000000000
76
77
@@ -XXX,XX +XXX,XX @@
78
[0F5h 0245 1] Bit Width : 00
79
[0F6h 0246 1] Bit Offset : 00
80
[0F7h 0247 1] Encoded Access Width : 00 [Undefined/Legacy]
81
[0F8h 0248 8] Address : 0000000000000000
82
83
[100h 0256 12] Sleep Status Register : [Generic Address Structure]
84
[100h 0256 1] Space ID : 00 [SystemMemory]
85
[101h 0257 1] Bit Width : 00
86
[102h 0258 1] Bit Offset : 00
87
[103h 0259 1] Encoded Access Width : 00 [Undefined/Legacy]
88
[104h 0260 8] Address : 0000000000000000
89
90
[10Ch 0268 8] Hypervisor ID : 00000000554D4551
91
92
Raw Table Data: Length 276 (0x114)
93
94
- 0000: 46 41 43 50 14 01 00 00 06 15 42 4F 43 48 53 20 // FACP......BOCHS
95
+ 0000: 46 41 43 50 14 01 00 00 06 12 42 4F 43 48 53 20 // FACP......BOCHS
96
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
97
0020: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
98
0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
99
0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
100
0050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
101
0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
102
0070: 00 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
103
- 0080: 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
104
+ 0080: 00 03 00 03 00 00 00 00 00 00 00 00 00 00 00 00 // ................
105
0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
106
00A0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
107
00B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
108
00C0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
109
00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
110
00E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
111
00F0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // ................
112
0100: 00 00 00 00 00 00 00 00 00 00 00 00 51 45 4D 55 // ............QEMU
113
0110: 00 00 00 00 // ....
114
115
@@ -XXX,XX +XXX,XX @@
116
/*
117
* Intel ACPI Component Architecture
118
* AML/ASL+ Disassembler version 20200925 (64-bit version)
119
* Copyright (c) 2000 - 2020 Intel Corporation
120
*
121
- * Disassembly of tests/data/acpi/virt/GTDT, Mon Jan 22 13:48:40 2024
122
+ * Disassembly of /tmp/aml-XDSZH2, Mon Jan 22 13:48:40 2024
123
*
124
* ACPI Data Table [GTDT]
125
*
126
* Format: [HexOffset DecimalOffset ByteLength] FieldName : FieldValue
127
*/
128
129
[000h 0000 4] Signature : "GTDT" [Generic Timer Description Table]
130
-[004h 0004 4] Table Length : 00000060
131
-[008h 0008 1] Revision : 02
132
-[009h 0009 1] Checksum : 9C
133
+[004h 0004 4] Table Length : 00000068
134
+[008h 0008 1] Revision : 03
135
+[009h 0009 1] Checksum : 93
136
[00Ah 0010 6] Oem ID : "BOCHS "
137
[010h 0016 8] Oem Table ID : "BXPC "
138
[018h 0024 4] Oem Revision : 00000001
139
[01Ch 0028 4] Asl Compiler ID : "BXPC"
140
[020h 0032 4] Asl Compiler Revision : 00000001
141
142
[024h 0036 8] Counter Block Address : FFFFFFFFFFFFFFFF
143
[02Ch 0044 4] Reserved : 00000000
144
145
[030h 0048 4] Secure EL1 Interrupt : 0000001D
146
[034h 0052 4] EL1 Flags (decoded below) : 00000000
147
Trigger Mode : 0
148
Polarity : 0
149
Always On : 0
150
151
[038h 0056 4] Non-Secure EL1 Interrupt : 0000001E
152
@@ -XXX,XX +XXX,XX @@
153
154
[040h 0064 4] Virtual Timer Interrupt : 0000001B
155
[044h 0068 4] VT Flags (decoded below) : 00000000
156
Trigger Mode : 0
157
Polarity : 0
158
Always On : 0
159
160
[048h 0072 4] Non-Secure EL2 Interrupt : 0000001A
161
[04Ch 0076 4] NEL2 Flags (decoded below) : 00000000
162
Trigger Mode : 0
163
Polarity : 0
164
Always On : 0
165
[050h 0080 8] Counter Read Block Address : FFFFFFFFFFFFFFFF
166
167
[058h 0088 4] Platform Timer Count : 00000000
168
[05Ch 0092 4] Platform Timer Offset : 00000000
169
+[060h 0096 4] Virtual EL2 Timer GSIV : 00000000
170
+[064h 0100 4] Virtual EL2 Timer Flags : 00000000
171
172
-Raw Table Data: Length 96 (0x60)
173
+Raw Table Data: Length 104 (0x68)
174
175
- 0000: 47 54 44 54 60 00 00 00 02 9C 42 4F 43 48 53 20 // GTDT`.....BOCHS
176
+ 0000: 47 54 44 54 68 00 00 00 03 93 42 4F 43 48 53 20 // GTDTh.....BOCHS
177
0010: 42 58 50 43 20 20 20 20 01 00 00 00 42 58 50 43 // BXPC ....BXPC
178
0020: 01 00 00 00 FF FF FF FF FF FF FF FF 00 00 00 00 // ................
179
0030: 1D 00 00 00 00 00 00 00 1E 00 00 00 04 00 00 00 // ................
180
0040: 1B 00 00 00 00 00 00 00 1A 00 00 00 00 00 00 00 // ................
181
0050: FF FF FF FF FF FF FF FF 00 00 00 00 00 00 00 00 // ................
182
+ 0060: 00 00 00 00 00 00 00 00 // ........
9
183
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
13
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
14
Message-id: 1512503192-2239-10-git-send-email-peter.maydell@linaro.org
15
---
187
---
16
target/arm/op_helper.c | 79 ++++++++++++++------------------------------------
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
17
1 file changed, 22 insertions(+), 57 deletions(-)
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
18
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
19
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
191
3 files changed, 2 deletions(-)
192
193
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
20
index XXXXXXX..XXXXXXX 100644
194
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/op_helper.c
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
22
+++ b/target/arm/op_helper.c
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
23
@@ -XXX,XX +XXX,XX @@ static inline uint32_t merge_syn_data_abort(uint32_t template_syn,
197
@@ -1,3 +1 @@
24
}
198
/* List of comma-separated changed AML files to ignore */
25
199
-"tests/data/acpi/virt/FACP",
26
static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
200
-"tests/data/acpi/virt/GTDT",
27
- uint32_t fsr, uint32_t fsc, ARMMMUFaultInfo *fi)
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
28
+ int mmu_idx, ARMMMUFaultInfo *fi)
202
index XXXXXXX..XXXXXXX 100644
29
{
203
GIT binary patch
30
CPUARMState *env = &cpu->env;
204
delta 25
31
int target_el;
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
32
bool same_el;
206
33
- uint32_t syn, exc;
207
delta 28
34
+ uint32_t syn, exc, fsr, fsc;
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
35
+ ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
209
36
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
37
target_el = exception_target_el(env);
211
index XXXXXXX..XXXXXXX 100644
38
if (fi->stage2) {
212
GIT binary patch
39
@@ -XXX,XX +XXX,XX @@ static void deliver_fault(ARMCPU *cpu, vaddr addr, MMUAccessType access_type,
213
delta 25
40
}
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
41
same_el = (arm_current_el(env) == target_el);
215
42
216
delta 16
43
- if (fsc == 0x3f) {
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
44
- /* Caller doesn't have a long-format fault status code. This
218
45
- * should only happen if this fault will never actually be reported
46
- * to an EL that uses a syndrome register. Check that here.
47
- * 0x3f is a (currently) reserved FSC code, in case the constructed
48
- * syndrome does leak into the guest somehow.
49
+ if (target_el == 2 || arm_el_is_aa64(env, target_el) ||
50
+ arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
51
+ /* LPAE format fault status register : bottom 6 bits are
52
+ * status code in the same form as needed for syndrome
53
+ */
54
+ fsr = arm_fi_to_lfsc(fi);
55
+ fsc = extract32(fsr, 0, 6);
56
+ } else {
57
+ fsr = arm_fi_to_sfsc(fi);
58
+ /* Short format FSR : this fault will never actually be reported
59
+ * to an EL that uses a syndrome register. Use a (currently)
60
+ * reserved FSR code in case the constructed syndrome does leak
61
+ * into the guest somehow.
62
*/
63
- assert(target_el != 2 && !arm_el_is_aa64(env, target_el));
64
+ fsc = 0x3f;
65
}
66
67
if (access_type == MMU_INST_FETCH) {
68
@@ -XXX,XX +XXX,XX @@ void tlb_fill(CPUState *cs, target_ulong addr, MMUAccessType access_type,
69
ret = arm_tlb_fill(cs, addr, access_type, mmu_idx, &fsr, &fi);
70
if (unlikely(ret)) {
71
ARMCPU *cpu = ARM_CPU(cs);
72
- uint32_t fsc;
73
74
if (retaddr) {
75
/* now we have a real cpu fault */
76
cpu_restore_state(cs, retaddr);
77
}
78
79
- if (fsr & (1 << 9)) {
80
- /* LPAE format fault status register : bottom 6 bits are
81
- * status code in the same form as needed for syndrome
82
- */
83
- fsc = extract32(fsr, 0, 6);
84
- } else {
85
- /* Short format FSR : this fault will never actually be reported
86
- * to an EL that uses a syndrome register. Use a (currently)
87
- * reserved FSR code in case the constructed syndrome does leak
88
- * into the guest somehow. deliver_fault will assert that
89
- * we don't target an EL using the syndrome.
90
- */
91
- fsc = 0x3f;
92
- }
93
-
94
- deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
95
+ deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
96
}
97
}
98
99
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_unaligned_access(CPUState *cs, vaddr vaddr,
100
int mmu_idx, uintptr_t retaddr)
101
{
102
ARMCPU *cpu = ARM_CPU(cs);
103
- CPUARMState *env = &cpu->env;
104
- uint32_t fsr, fsc;
105
ARMMMUFaultInfo fi = {};
106
- ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
107
108
if (retaddr) {
109
/* now we have a real cpu fault */
110
cpu_restore_state(cs, retaddr);
111
}
112
113
- /* the DFSR for an alignment fault depends on whether we're using
114
- * the LPAE long descriptor format, or the short descriptor format
115
- */
116
- if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
117
- fsr = (1 << 9) | 0x21;
118
- } else {
119
- fsr = 0x1;
120
- }
121
- fsc = 0x21;
122
-
123
- deliver_fault(cpu, vaddr, access_type, fsr, fsc, &fi);
124
+ fi.type = ARMFault_Alignment;
125
+ deliver_fault(cpu, vaddr, access_type, mmu_idx, &fi);
126
}
127
128
/* arm_cpu_do_transaction_failed: handle a memory system error response
129
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
130
MemTxResult response, uintptr_t retaddr)
131
{
132
ARMCPU *cpu = ARM_CPU(cs);
133
- CPUARMState *env = &cpu->env;
134
- uint32_t fsr, fsc;
135
ARMMMUFaultInfo fi = {};
136
- ARMMMUIdx arm_mmu_idx = core_to_arm_mmu_idx(env, mmu_idx);
137
138
if (retaddr) {
139
/* now we have a real cpu fault */
140
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
141
* Slave error (1); in QEMU we follow that.
142
*/
143
fi.ea = (response != MEMTX_DECODE_ERROR);
144
-
145
- /* The fault status register format depends on whether we're using
146
- * the LPAE long descriptor format, or the short descriptor format.
147
- */
148
- if (arm_s1_regime_using_lpae_format(env, arm_mmu_idx)) {
149
- /* long descriptor form, STATUS 0b010000: synchronous ext abort */
150
- fsr = (fi.ea << 12) | (1 << 9) | 0x10;
151
- } else {
152
- /* short descriptor form, FSR 0b01000 : synchronous ext abort */
153
- fsr = (fi.ea << 12) | 0x8;
154
- }
155
- fsc = 0x10;
156
-
157
- deliver_fault(cpu, addr, access_type, fsr, fsc, &fi);
158
+ fi.type = ARMFault_SyncExternal;
159
+ deliver_fault(cpu, addr, access_type, mmu_idx, &fi);
160
}
161
162
#endif /* !defined(CONFIG_USER_ONLY) */
163
--
219
--
164
2.7.4
220
2.34.1
165
166
diff view generated by jsdifflib
1
From: Prasad J Pandit <pjp@fedoraproject.org>
1
The patchset adding the GMAC ethernet to this SoC crossed in the
2
mail with the patchset cleaning up the NIC handling. When we
3
create the GMAC modules we must call qemu_configure_nic_device()
4
so that the user has the opportunity to use the -nic commandline
5
option to create a network backend and connect it to the GMACs.
2
6
3
The ctz32() routine could return a value greater than
7
Add the missing call.
4
TC6393XB_GPIOS=16, because the device has 24 GPIO level
5
bits but we only implement 16 outgoing lines. This could
6
lead to an OOB array access. Mask 'level' to avoid it.
7
8
8
Reported-by: Moguofang <moguofang@huawei.com>
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
9
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
10
Message-id: 20171212041539.25700-1-ppandit@redhat.com
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
12
Message-id: 20240206171231.396392-2-peter.maydell@linaro.org
13
---
13
---
14
hw/display/tc6393xb.c | 1 +
14
hw/arm/npcm7xx.c | 1 +
15
1 file changed, 1 insertion(+)
15
1 file changed, 1 insertion(+)
16
16
17
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/display/tc6393xb.c
19
--- a/hw/arm/npcm7xx.c
20
+++ b/hw/display/tc6393xb.c
20
+++ b/hw/arm/npcm7xx.c
21
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_handler_update(TC6393xbState *s)
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
22
int bit;
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
23
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
24
level = s->gpio_level & s->gpio_dir;
24
25
+ level &= MAKE_64BIT_MASK(0, TC6393XB_GPIOS);
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
26
26
/*
27
for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) {
27
* The device exists regardless of whether it's connected to a QEMU
28
bit = ctz32(diff);
28
* netdev backend. So always instantiate it even if there is no
29
--
29
--
30
2.7.4
30
2.34.1
31
32
diff view generated by jsdifflib
1
In ARMv7M the CPU ignores explicit writes to CONTROL.SPSEL
1
Currently QEMU will warn if there is a NIC on the board that
2
in Handler mode. In v8M the behaviour is slightly different:
2
is not connected to a backend. By default the '-nic user' will
3
writes to the bit are permitted but will have no effect.
3
get used for all NICs, but if you manually connect a specific
4
NIC to a specific backend, then the other NICs on the board
5
have no backend and will be warned about:
4
6
5
We've already done the hard work to handle the value in
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
6
CONTROL.SPSEL being out of sync with what stack pointer is
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
7
actually in use, so all we need to do to fix this last loose
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
8
end is to update the condition we use to guard whether we
10
9
call write_v7m_control_spsel() on the register write.
11
So suppress those warnings by manually connecting every NIC
12
on the board to some backend.
10
13
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
13
Message-id: 1512153879-5291-3-git-send-email-peter.maydell@linaro.org
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
14
---
18
---
15
target/arm/helper.c | 5 ++++-
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
16
1 file changed, 4 insertions(+), 1 deletion(-)
20
1 file changed, 4 insertions(+), 1 deletion(-)
17
21
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
24
--- a/tests/qtest/npcm7xx_emc-test.c
21
+++ b/target/arm/helper.c
25
+++ b/tests/qtest/npcm7xx_emc-test.c
22
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
23
* thread mode; other bits can be updated by any privileged code.
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
24
* write_v7m_control_spsel() deals with updating the SPSEL bit in
28
* in the 'model' field to specify the device to match.
25
* env->v7m.control, so we only need update the others.
29
*/
26
+ * For v7M, we must just ignore explicit writes to SPSEL in handler
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
27
+ * mode; for v8M the write is permitted but will have no effect.
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
28
*/
32
+ "-nic user,model=npcm7xx-emc "
29
- if (!arm_v7m_is_handler_mode(env)) {
33
+ "-nic user,model=npcm-gmac "
30
+ if (arm_feature(env, ARM_FEATURE_V8) ||
34
+ "-nic user,model=npcm-gmac",
31
+ !arm_v7m_is_handler_mode(env)) {
35
test_sockets[1], module_num);
32
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
36
33
}
37
g_test_queue_destroy(packet_test_clear, test_sockets);
34
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
35
--
38
--
36
2.7.4
39
2.34.1
37
38
diff view generated by jsdifflib
1
Make get_phys_addr_v6() return a fault type in the ARMMMUFaultInfo
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
structure, which we convert to the FSC at the callsite.
2
CPU, and in fact if you try to do it we will assert:
3
3
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
5
(assertion=0x5555565a8c70 "!arm_feature(env, ARM_FEATURE_M)", file=0x5555565a6e5c "../../target/arm/helper.c", line=12600, function=0x5555565a9560 <__PRETTY_FUNCTION__.0> "arm_security_space_below_el3") at ./assert/assert.c:101
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
9
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
11
from the migration pre/post hooks in machine.c); this should always
12
return false because these CPUs don't set ARM_FEATURE_PMU.
13
14
Avoid the assertion by not calling arm_mdcr_el2_eff() before we
15
have done the early return for "PMU not present".
16
17
This fixes an assertion failure if you try to do a loadvm or
18
savevm for an M-profile board.
19
20
Cc: qemu-stable@nongnu.org
21
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2155
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-6-git-send-email-peter.maydell@linaro.org
9
---
26
---
10
target/arm/helper.c | 41 ++++++++++++++++++-----------------------
27
target/arm/helper.c | 12 ++++++++++--
11
1 file changed, 18 insertions(+), 23 deletions(-)
28
1 file changed, 10 insertions(+), 2 deletions(-)
12
29
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
32
--- a/target/arm/helper.c
16
+++ b/target/arm/helper.c
33
+++ b/target/arm/helper.c
17
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
18
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
35
bool enabled, prohibited = false, filtered;
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
36
bool secure = arm_is_secure(env);
20
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
37
int el = arm_current_el(env);
21
- target_ulong *page_size_ptr, uint32_t *fsr,
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
22
+ target_ulong *page_size_ptr,
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
23
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs);
40
+ uint64_t mdcr_el2;
24
41
+ uint8_t hpmn;
25
/* Security attributes for an address, as returned by v8m_security_lookup. */
42
26
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
43
+ /*
27
hwaddr s2pa;
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
28
int s2prot;
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
29
int ret;
46
+ * must be before we read that value.
30
- uint32_t fsr;
47
+ */
31
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
32
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
49
return false;
33
- &txattrs, &s2prot, &s2size, &fsr, fi, NULL);
34
+ &txattrs, &s2prot, &s2size, fi, NULL);
35
if (ret) {
36
fi->s2addr = addr;
37
fi->stage2 = true;
38
@@ -XXX,XX +XXX,XX @@ do_fault:
39
return true;
40
}
41
42
-/* Fault type for long-descriptor MMU fault reporting; this corresponds
43
- * to bits [5..2] in the STATUS field in long-format DFSR/IFSR.
44
- */
45
-typedef enum {
46
- translation_fault = 1,
47
- access_fault = 2,
48
- permission_fault = 3,
49
-} MMUFaultType;
50
-
51
/*
52
* check_s2_mmu_setup
53
* @cpu: ARMCPU
54
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
55
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
56
MMUAccessType access_type, ARMMMUIdx mmu_idx,
57
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
58
- target_ulong *page_size_ptr, uint32_t *fsr,
59
+ target_ulong *page_size_ptr,
60
ARMMMUFaultInfo *fi, ARMCacheAttrs *cacheattrs)
61
{
62
ARMCPU *cpu = arm_env_get_cpu(env);
63
CPUState *cs = CPU(cpu);
64
/* Read an LPAE long-descriptor translation table. */
65
- MMUFaultType fault_type = translation_fault;
66
+ ARMFaultType fault_type = ARMFault_Translation;
67
uint32_t level;
68
uint32_t epd = 0;
69
int32_t t0sz, t1sz;
70
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
71
ttbr_select = 1;
72
} else {
73
/* in the gap between the two regions, this is a Translation fault */
74
- fault_type = translation_fault;
75
+ fault_type = ARMFault_Translation;
76
goto do_fault;
77
}
50
}
78
51
79
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
80
ok = check_s2_mmu_setup(cpu, aarch64, startlevel,
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
81
inputsize, stride);
82
if (!ok) {
83
- fault_type = translation_fault;
84
+ fault_type = ARMFault_Translation;
85
goto do_fault;
86
}
87
level = startlevel;
88
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
89
/* Here descaddr is the final physical address, and attributes
90
* are all in attrs.
91
*/
92
- fault_type = access_fault;
93
+ fault_type = ARMFault_AccessFlag;
94
if ((attrs & (1 << 8)) == 0) {
95
/* Access flag */
96
goto do_fault;
97
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
98
*prot = get_S1prot(env, mmu_idx, aarch64, ap, ns, xn, pxn);
99
}
100
101
- fault_type = permission_fault;
102
+ fault_type = ARMFault_Permission;
103
if (!(*prot & (1 << access_type))) {
104
goto do_fault;
105
}
106
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
107
return false;
108
109
do_fault:
110
- /* Long-descriptor format IFSR/DFSR value */
111
- *fsr = (1 << 9) | (fault_type << 2) | level;
112
+ fi->type = fault_type;
113
+ fi->level = level;
114
/* Tag the error as S2 for failed S1 PTW at S2 or ordinary S2. */
115
fi->stage2 = fi->s1ptw || (mmu_idx == ARMMMUIdx_S2NS);
116
return true;
117
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
118
/* S1 is done. Now do S2 translation. */
119
ret = get_phys_addr_lpae(env, ipa, access_type, ARMMMUIdx_S2NS,
120
phys_ptr, attrs, &s2_prot,
121
- page_size, fsr, fi,
122
+ page_size, fi,
123
cacheattrs != NULL ? &cacheattrs2 : NULL);
124
+ *fsr = arm_fi_to_lfsc(fi);
125
fi->s2addr = ipa;
126
/* Combine the S1 and S2 perms. */
127
*prot &= s2_prot;
128
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
129
}
130
131
if (regime_using_lpae_format(env, mmu_idx)) {
132
- return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
133
- attrs, prot, page_size, fsr, fi, cacheattrs);
134
+ bool ret = get_phys_addr_lpae(env, address, access_type, mmu_idx,
135
+ phys_ptr, attrs, prot, page_size,
136
+ fi, cacheattrs);
137
+
54
+
138
+ *fsr = arm_fi_to_lfsc(fi);
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
139
+ return ret;
56
(counter < hpmn || counter == 31)) {
140
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
57
e = env->cp15.c9_pmcr & PMCRE;
141
bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
142
phys_ptr, attrs, prot, page_size, fi);
143
--
58
--
144
2.7.4
59
2.34.1
145
60
146
61
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
Add support for the Zynq Ultrascale MPSoc Generic QSPI.
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
4
5
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
7
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
8
Message-id: 20171126231634.9531-13-frasse.iglesias@gmail.com
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
[PMM: commit message tweaks]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
13
---
11
include/hw/ssi/xilinx_spips.h | 32 ++-
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
12
hw/ssi/xilinx_spips.c | 579 ++++++++++++++++++++++++++++++++++++----
15
tests/qtest/meson.build | 3 +-
13
default-configs/arm-softmmu.mak | 2 +-
16
2 files changed, 4 insertions(+), 83 deletions(-)
14
3 files changed, 564 insertions(+), 49 deletions(-)
15
17
16
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
17
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/ssi/xilinx_spips.h
20
--- a/tests/qtest/npcm_gmac-test.c
19
+++ b/include/hw/ssi/xilinx_spips.h
21
+++ b/tests/qtest/npcm_gmac-test.c
20
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
21
#define XILINX_SPIPS_H
23
const GMACModule *module;
22
24
} TestData;
23
#include "hw/ssi/ssi.h"
25
24
-#include "qemu/fifo8.h"
26
-/* Values extracted from hw/arm/npcm8xx.c */
25
+#include "qemu/fifo32.h"
27
+/* Values extracted from hw/arm/npcm7xx.c */
26
+#include "hw/stream.h"
28
static const GMACModule gmac_module_list[] = {
27
29
{
28
typedef struct XilinxSPIPS XilinxSPIPS;
30
.irq = 14,
29
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
30
#define XLNX_SPIPS_R_MAX (0x100 / 4)
32
.irq = 15,
31
+#define XLNX_ZYNQMP_SPIPS_R_MAX (0x200 / 4)
33
.base_addr = 0xf0804000
32
34
},
33
/* Bite off 4k chunks at a time */
35
- {
34
#define LQSPI_CACHE_SIZE 1024
36
- .irq = 16,
35
@@ -XXX,XX +XXX,XX @@ typedef struct {
37
- .base_addr = 0xf0806000
36
bool mmio_execution_enabled;
38
- },
37
} XilinxQSPIPS;
39
- {
38
40
- .irq = 17,
39
+typedef struct {
41
- .base_addr = 0xf0808000
40
+ XilinxQSPIPS parent_obj;
42
- }
41
+
43
};
42
+ StreamSlave *dma;
44
43
+ uint8_t dma_buf[4];
45
/* Returns the index of the GMAC module. */
44
+ int gqspi_irqline;
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
45
+
47
return qtest_readl(qts, mod->base_addr + regno);
46
+ uint32_t regs[XLNX_ZYNQMP_SPIPS_R_MAX];
47
+
48
+ /* GQSPI has seperate tx/rx fifos */
49
+ Fifo8 rx_fifo_g;
50
+ Fifo8 tx_fifo_g;
51
+ Fifo32 fifo_g;
52
+ /*
53
+ * At the end of each generic command, misaligned extra bytes are discard
54
+ * or padded to tx and rx respectively to round it out (and avoid need for
55
+ * individual byte access. Since we use byte fifos, keep track of the
56
+ * alignment WRT to word access.
57
+ */
58
+ uint8_t rx_fifo_g_align;
59
+ uint8_t tx_fifo_g_align;
60
+ bool man_start_com_g;
61
+} XlnxZynqMPQSPIPS;
62
+
63
typedef struct XilinxSPIPSClass {
64
SysBusDeviceClass parent_class;
65
66
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPSClass {
67
68
#define TYPE_XILINX_SPIPS "xlnx.ps7-spi"
69
#define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi"
70
+#define TYPE_XLNX_ZYNQMP_QSPIPS "xlnx.usmp-gqspi"
71
72
#define XILINX_SPIPS(obj) \
73
OBJECT_CHECK(XilinxSPIPS, (obj), TYPE_XILINX_SPIPS)
74
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPSClass {
75
#define XILINX_QSPIPS(obj) \
76
OBJECT_CHECK(XilinxQSPIPS, (obj), TYPE_XILINX_QSPIPS)
77
78
+#define XLNX_ZYNQMP_QSPIPS(obj) \
79
+ OBJECT_CHECK(XlnxZynqMPQSPIPS, (obj), TYPE_XLNX_ZYNQMP_QSPIPS)
80
+
81
#endif /* XILINX_SPIPS_H */
82
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/ssi/xilinx_spips.c
85
+++ b/hw/ssi/xilinx_spips.c
86
@@ -XXX,XX +XXX,XX @@
87
#include "hw/ssi/xilinx_spips.h"
88
#include "qapi/error.h"
89
#include "hw/register.h"
90
+#include "sysemu/dma.h"
91
#include "migration/blocker.h"
92
93
#ifndef XILINX_SPIPS_ERR_DEBUG
94
@@ -XXX,XX +XXX,XX @@
95
#define R_INTR_DIS (0x0C / 4)
96
#define R_INTR_MASK (0x10 / 4)
97
#define IXR_TX_FIFO_UNDERFLOW (1 << 6)
98
+/* Poll timeout not implemented */
99
+#define IXR_RX_FIFO_EMPTY (1 << 11)
100
+#define IXR_GENERIC_FIFO_FULL (1 << 10)
101
+#define IXR_GENERIC_FIFO_NOT_FULL (1 << 9)
102
+#define IXR_TX_FIFO_EMPTY (1 << 8)
103
+#define IXR_GENERIC_FIFO_EMPTY (1 << 7)
104
#define IXR_RX_FIFO_FULL (1 << 5)
105
#define IXR_RX_FIFO_NOT_EMPTY (1 << 4)
106
#define IXR_TX_FIFO_FULL (1 << 3)
107
#define IXR_TX_FIFO_NOT_FULL (1 << 2)
108
#define IXR_TX_FIFO_MODE_FAIL (1 << 1)
109
#define IXR_RX_FIFO_OVERFLOW (1 << 0)
110
-#define IXR_ALL ((IXR_TX_FIFO_UNDERFLOW<<1)-1)
111
+#define IXR_ALL ((1 << 13) - 1)
112
+#define GQSPI_IXR_MASK 0xFBE
113
+#define IXR_SELF_CLEAR \
114
+(IXR_GENERIC_FIFO_EMPTY \
115
+| IXR_GENERIC_FIFO_FULL \
116
+| IXR_GENERIC_FIFO_NOT_FULL \
117
+| IXR_TX_FIFO_EMPTY \
118
+| IXR_TX_FIFO_FULL \
119
+| IXR_TX_FIFO_NOT_FULL \
120
+| IXR_RX_FIFO_EMPTY \
121
+| IXR_RX_FIFO_FULL \
122
+| IXR_RX_FIFO_NOT_EMPTY)
123
124
#define R_EN (0x14 / 4)
125
#define R_DELAY (0x18 / 4)
126
@@ -XXX,XX +XXX,XX @@
127
128
#define R_MOD_ID (0xFC / 4)
129
130
+#define R_GQSPI_SELECT (0x144 / 4)
131
+ FIELD(GQSPI_SELECT, GENERIC_QSPI_EN, 0, 1)
132
+#define R_GQSPI_ISR (0x104 / 4)
133
+#define R_GQSPI_IER (0x108 / 4)
134
+#define R_GQSPI_IDR (0x10c / 4)
135
+#define R_GQSPI_IMR (0x110 / 4)
136
+#define R_GQSPI_TX_THRESH (0x128 / 4)
137
+#define R_GQSPI_RX_THRESH (0x12c / 4)
138
+#define R_GQSPI_CNFG (0x100 / 4)
139
+ FIELD(GQSPI_CNFG, MODE_EN, 30, 2)
140
+ FIELD(GQSPI_CNFG, GEN_FIFO_START_MODE, 29, 1)
141
+ FIELD(GQSPI_CNFG, GEN_FIFO_START, 28, 1)
142
+ FIELD(GQSPI_CNFG, ENDIAN, 26, 1)
143
+ /* Poll timeout not implemented */
144
+ FIELD(GQSPI_CNFG, EN_POLL_TIMEOUT, 20, 1)
145
+ /* QEMU doesnt care about any of these last three */
146
+ FIELD(GQSPI_CNFG, BR, 3, 3)
147
+ FIELD(GQSPI_CNFG, CPH, 2, 1)
148
+ FIELD(GQSPI_CNFG, CPL, 1, 1)
149
+#define R_GQSPI_GEN_FIFO (0x140 / 4)
150
+#define R_GQSPI_TXD (0x11c / 4)
151
+#define R_GQSPI_RXD (0x120 / 4)
152
+#define R_GQSPI_FIFO_CTRL (0x14c / 4)
153
+ FIELD(GQSPI_FIFO_CTRL, RX_FIFO_RESET, 2, 1)
154
+ FIELD(GQSPI_FIFO_CTRL, TX_FIFO_RESET, 1, 1)
155
+ FIELD(GQSPI_FIFO_CTRL, GENERIC_FIFO_RESET, 0, 1)
156
+#define R_GQSPI_GFIFO_THRESH (0x150 / 4)
157
+#define R_GQSPI_DATA_STS (0x15c / 4)
158
+/* We use the snapshot register to hold the core state for the currently
159
+ * or most recently executed command. So the generic fifo format is defined
160
+ * for the snapshot register
161
+ */
162
+#define R_GQSPI_GF_SNAPSHOT (0x160 / 4)
163
+ FIELD(GQSPI_GF_SNAPSHOT, POLL, 19, 1)
164
+ FIELD(GQSPI_GF_SNAPSHOT, STRIPE, 18, 1)
165
+ FIELD(GQSPI_GF_SNAPSHOT, RECIEVE, 17, 1)
166
+ FIELD(GQSPI_GF_SNAPSHOT, TRANSMIT, 16, 1)
167
+ FIELD(GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT, 14, 2)
168
+ FIELD(GQSPI_GF_SNAPSHOT, CHIP_SELECT, 12, 2)
169
+ FIELD(GQSPI_GF_SNAPSHOT, SPI_MODE, 10, 2)
170
+ FIELD(GQSPI_GF_SNAPSHOT, EXPONENT, 9, 1)
171
+ FIELD(GQSPI_GF_SNAPSHOT, DATA_XFER, 8, 1)
172
+ FIELD(GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA, 0, 8)
173
+#define R_GQSPI_MOD_ID (0x168 / 4)
174
+#define R_GQSPI_MOD_ID_VALUE 0x010A0000
175
/* size of TXRX FIFOs */
176
-#define RXFF_A 32
177
-#define TXFF_A 32
178
+#define RXFF_A (128)
179
+#define TXFF_A (128)
180
181
#define RXFF_A_Q (64 * 4)
182
#define TXFF_A_Q (64 * 4)
183
@@ -XXX,XX +XXX,XX @@ static inline int num_effective_busses(XilinxSPIPS *s)
184
s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM) ? s->num_busses : 1;
185
}
48
}
186
49
187
-static inline bool xilinx_spips_cs_is_set(XilinxSPIPS *s, int i, int field)
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
51
- NPCMRegister regno)
188
-{
52
-{
189
- return ~field & (1 << i) && (s->regs[R_CONFIG] & MANUAL_CS
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
190
- || !fifo8_is_empty(&s->tx_fifo));
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
55
- uint32_t read_offset = regno & 0x1ff;
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
191
-}
57
-}
192
-
58
-
193
-static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
59
/* Check that GMAC registers are reset to default value */
194
+static void xilinx_spips_update_cs(XilinxSPIPS *s, int field)
60
static void test_init(gconstpointer test_data)
195
{
61
{
196
- int i, j;
62
const TestData *td = test_data;
197
- bool found = false;
63
const GMACModule *mod = td->module;
198
- int field = s->regs[R_CONFIG] >> CS_SHIFT;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
199
+ int i;
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
200
66
201
for (i = 0; i < s->num_cs; i++) {
67
#define CHECK_REG32(regno, value) \
202
- for (j = 0; j < num_effective_busses(s); j++) {
68
do { \
203
- int upage = !!(s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE);
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
204
- int cs_to_set = (j * s->num_cs + i + upage) %
70
} while (0)
205
- (s->num_cs * s->num_busses);
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
206
-
76
-
207
- if (xilinx_spips_cs_is_set(s, i, field) && !found) {
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
208
- DB_PRINT_L(0, "selecting slave %d\n", i);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
209
- qemu_set_irq(s->cs_lines[cs_to_set], 0);
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
210
- if (s->cs_lines_state[cs_to_set]) {
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
211
- s->cs_lines_state[cs_to_set] = false;
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
212
- s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD);
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
213
- }
83
214
- } else {
84
- /* TODO Add registers PCS */
215
- DB_PRINT_L(0, "deselecting slave %d\n", i);
85
- if (mod->base_addr == 0xf0802000) {
216
- qemu_set_irq(s->cs_lines[cs_to_set], 1);
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
217
- s->cs_lines_state[cs_to_set] = true;
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
218
- }
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
219
- }
89
-
220
- if (xilinx_spips_cs_is_set(s, i, field)) {
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
221
- found = true;
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
222
+ bool old_state = s->cs_lines_state[i];
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
223
+ bool new_state = field & (1 << i);
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
224
+
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
225
+ if (old_state != new_state) {
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
226
+ s->cs_lines_state[i] = new_state;
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
227
+ s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD);
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
228
+ DB_PRINT_L(1, "%sselecting slave %d\n", new_state ? "" : "de", i);
98
-
229
}
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
230
+ qemu_set_irq(s->cs_lines[i], !new_state);
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
231
}
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
232
- if (!found) {
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
233
+ if (!(field & ((1 << s->num_cs) - 1))) {
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
234
s->snoop_state = SNOOP_CHECKING;
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
235
s->cmd_dummies = 0;
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
236
s->link_state = 1;
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
237
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
238
}
108
-
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
115
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
116
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
117
- CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
118
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
119
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
120
- CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
121
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
122
- CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
123
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
124
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
125
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
126
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
127
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
128
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
129
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
130
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
131
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
132
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
133
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
134
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
135
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
136
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
137
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
138
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
139
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
140
- }
141
-
142
qtest_quit(qts);
239
}
143
}
240
144
241
+static void xlnx_zynqmp_qspips_update_cs_lines(XlnxZynqMPQSPIPS *s)
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
242
+{
243
+ if (s->regs[R_GQSPI_GF_SNAPSHOT]) {
244
+ int field = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, CHIP_SELECT);
245
+ xilinx_spips_update_cs(XILINX_SPIPS(s), field);
246
+ }
247
+}
248
+
249
+static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
250
+{
251
+ int field = ~((s->regs[R_CONFIG] & CS) >> CS_SHIFT);
252
+
253
+ /* In dual parallel, mirror low CS to both */
254
+ if (num_effective_busses(s) == 2) {
255
+ /* Single bit chip-select for qspi */
256
+ field &= 0x1;
257
+ field |= field << 1;
258
+ /* Dual stack U-Page */
259
+ } else if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_TWO_MEM &&
260
+ s->regs[R_LQSPI_STS] & LQSPI_CFG_U_PAGE) {
261
+ /* Single bit chip-select for qspi */
262
+ field &= 0x1;
263
+ /* change from CS0 to CS1 */
264
+ field <<= 1;
265
+ }
266
+ /* Auto CS */
267
+ if (!(s->regs[R_CONFIG] & MANUAL_CS) &&
268
+ fifo8_is_empty(&s->tx_fifo)) {
269
+ field = 0;
270
+ }
271
+ xilinx_spips_update_cs(s, field);
272
+}
273
+
274
static void xilinx_spips_update_ixr(XilinxSPIPS *s)
275
{
276
- if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE) {
277
- return;
278
+ if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
279
+ s->regs[R_INTR_STATUS] &= ~IXR_SELF_CLEAR;
280
+ s->regs[R_INTR_STATUS] |=
281
+ (fifo8_is_full(&s->rx_fifo) ? IXR_RX_FIFO_FULL : 0) |
282
+ (s->rx_fifo.num >= s->regs[R_RX_THRES] ?
283
+ IXR_RX_FIFO_NOT_EMPTY : 0) |
284
+ (fifo8_is_full(&s->tx_fifo) ? IXR_TX_FIFO_FULL : 0) |
285
+ (fifo8_is_empty(&s->tx_fifo) ? IXR_TX_FIFO_EMPTY : 0) |
286
+ (s->tx_fifo.num < s->regs[R_TX_THRES] ? IXR_TX_FIFO_NOT_FULL : 0);
287
}
288
- /* These are set/cleared as they occur */
289
- s->regs[R_INTR_STATUS] &= (IXR_TX_FIFO_UNDERFLOW | IXR_RX_FIFO_OVERFLOW |
290
- IXR_TX_FIFO_MODE_FAIL);
291
- /* these are pure functions of fifo state, set them here */
292
- s->regs[R_INTR_STATUS] |=
293
- (fifo8_is_full(&s->rx_fifo) ? IXR_RX_FIFO_FULL : 0) |
294
- (s->rx_fifo.num >= s->regs[R_RX_THRES] ? IXR_RX_FIFO_NOT_EMPTY : 0) |
295
- (fifo8_is_full(&s->tx_fifo) ? IXR_TX_FIFO_FULL : 0) |
296
- (s->tx_fifo.num < s->regs[R_TX_THRES] ? IXR_TX_FIFO_NOT_FULL : 0);
297
- /* drive external interrupt pin */
298
int new_irqline = !!(s->regs[R_INTR_MASK] & s->regs[R_INTR_STATUS] &
299
IXR_ALL);
300
if (new_irqline != s->irqline) {
301
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_ixr(XilinxSPIPS *s)
302
}
303
}
304
305
+static void xlnx_zynqmp_qspips_update_ixr(XlnxZynqMPQSPIPS *s)
306
+{
307
+ uint32_t gqspi_int;
308
+ int new_irqline;
309
+
310
+ s->regs[R_GQSPI_ISR] &= ~IXR_SELF_CLEAR;
311
+ s->regs[R_GQSPI_ISR] |=
312
+ (fifo32_is_empty(&s->fifo_g) ? IXR_GENERIC_FIFO_EMPTY : 0) |
313
+ (fifo32_is_full(&s->fifo_g) ? IXR_GENERIC_FIFO_FULL : 0) |
314
+ (s->fifo_g.fifo.num < s->regs[R_GQSPI_GFIFO_THRESH] ?
315
+ IXR_GENERIC_FIFO_NOT_FULL : 0) |
316
+ (fifo8_is_empty(&s->rx_fifo_g) ? IXR_RX_FIFO_EMPTY : 0) |
317
+ (fifo8_is_full(&s->rx_fifo_g) ? IXR_RX_FIFO_FULL : 0) |
318
+ (s->rx_fifo_g.num >= s->regs[R_GQSPI_RX_THRESH] ?
319
+ IXR_RX_FIFO_NOT_EMPTY : 0) |
320
+ (fifo8_is_empty(&s->tx_fifo_g) ? IXR_TX_FIFO_EMPTY : 0) |
321
+ (fifo8_is_full(&s->tx_fifo_g) ? IXR_TX_FIFO_FULL : 0) |
322
+ (s->tx_fifo_g.num < s->regs[R_GQSPI_TX_THRESH] ?
323
+ IXR_TX_FIFO_NOT_FULL : 0);
324
+
325
+ /* GQSPI Interrupt Trigger Status */
326
+ gqspi_int = (~s->regs[R_GQSPI_IMR]) & s->regs[R_GQSPI_ISR] & GQSPI_IXR_MASK;
327
+ new_irqline = !!(gqspi_int & IXR_ALL);
328
+
329
+ /* drive external interrupt pin */
330
+ if (new_irqline != s->gqspi_irqline) {
331
+ s->gqspi_irqline = new_irqline;
332
+ qemu_set_irq(XILINX_SPIPS(s)->irq, s->gqspi_irqline);
333
+ }
334
+}
335
+
336
static void xilinx_spips_reset(DeviceState *d)
337
{
338
XilinxSPIPS *s = XILINX_SPIPS(d);
339
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
340
xilinx_spips_update_cs_lines(s);
341
}
342
343
+static void xlnx_zynqmp_qspips_reset(DeviceState *d)
344
+{
345
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(d);
346
+ int i;
347
+
348
+ xilinx_spips_reset(d);
349
+
350
+ for (i = 0; i < XLNX_ZYNQMP_SPIPS_R_MAX; i++) {
351
+ s->regs[i] = 0;
352
+ }
353
+ fifo8_reset(&s->rx_fifo_g);
354
+ fifo8_reset(&s->rx_fifo_g);
355
+ fifo32_reset(&s->fifo_g);
356
+ s->regs[R_GQSPI_TX_THRESH] = 1;
357
+ s->regs[R_GQSPI_RX_THRESH] = 1;
358
+ s->regs[R_GQSPI_GFIFO_THRESH] = 1;
359
+ s->regs[R_GQSPI_IMR] = GQSPI_IXR_MASK;
360
+ s->man_start_com_g = false;
361
+ s->gqspi_irqline = 0;
362
+ xlnx_zynqmp_qspips_update_ixr(s);
363
+}
364
+
365
/* N way (num) in place bit striper. Lay out row wise bits (MSB to LSB)
366
* column wise (from element 0 to N-1). num is the length of x, and dir
367
* reverses the direction of the transform. Best illustrated by example:
368
@@ -XXX,XX +XXX,XX @@ static inline void stripe8(uint8_t *x, int num, bool dir)
369
memcpy(x, r, sizeof(uint8_t) * num);
370
}
371
372
+static void xlnx_zynqmp_qspips_flush_fifo_g(XlnxZynqMPQSPIPS *s)
373
+{
374
+ while (s->regs[R_GQSPI_DATA_STS] || !fifo32_is_empty(&s->fifo_g)) {
375
+ uint8_t tx_rx[2] = { 0 };
376
+ int num_stripes = 1;
377
+ uint8_t busses;
378
+ int i;
379
+
380
+ if (!s->regs[R_GQSPI_DATA_STS]) {
381
+ uint8_t imm;
382
+
383
+ s->regs[R_GQSPI_GF_SNAPSHOT] = fifo32_pop(&s->fifo_g);
384
+ DB_PRINT_L(0, "GQSPI command: %x\n", s->regs[R_GQSPI_GF_SNAPSHOT]);
385
+ if (!s->regs[R_GQSPI_GF_SNAPSHOT]) {
386
+ DB_PRINT_L(0, "Dummy GQSPI Delay Command Entry, Do nothing");
387
+ continue;
388
+ }
389
+ xlnx_zynqmp_qspips_update_cs_lines(s);
390
+
391
+ imm = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA);
392
+ if (!ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_XFER)) {
393
+ /* immedate transfer */
394
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT) ||
395
+ ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE)) {
396
+ s->regs[R_GQSPI_DATA_STS] = 1;
397
+ /* CS setup/hold - do nothing */
398
+ } else {
399
+ s->regs[R_GQSPI_DATA_STS] = 0;
400
+ }
401
+ } else if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, EXPONENT)) {
402
+ if (imm > 31) {
403
+ qemu_log_mask(LOG_UNIMP, "QSPI exponential transfer too"
404
+ " long - 2 ^ %" PRId8 " requested\n", imm);
405
+ }
406
+ s->regs[R_GQSPI_DATA_STS] = 1ul << imm;
407
+ } else {
408
+ s->regs[R_GQSPI_DATA_STS] = imm;
409
+ }
410
+ }
411
+ /* Zero length transfer check */
412
+ if (!s->regs[R_GQSPI_DATA_STS]) {
413
+ continue;
414
+ }
415
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE) &&
416
+ fifo8_is_full(&s->rx_fifo_g)) {
417
+ /* No space in RX fifo for transfer - try again later */
418
+ return;
419
+ }
420
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, STRIPE) &&
421
+ (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT) ||
422
+ ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE))) {
423
+ num_stripes = 2;
424
+ }
425
+ if (!ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_XFER)) {
426
+ tx_rx[0] = ARRAY_FIELD_EX32(s->regs,
427
+ GQSPI_GF_SNAPSHOT, IMMEDIATE_DATA);
428
+ } else if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, TRANSMIT)) {
429
+ for (i = 0; i < num_stripes; ++i) {
430
+ if (!fifo8_is_empty(&s->tx_fifo_g)) {
431
+ tx_rx[i] = fifo8_pop(&s->tx_fifo_g);
432
+ s->tx_fifo_g_align++;
433
+ } else {
434
+ return;
435
+ }
436
+ }
437
+ }
438
+ if (num_stripes == 1) {
439
+ /* mirror */
440
+ tx_rx[1] = tx_rx[0];
441
+ }
442
+ busses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT);
443
+ for (i = 0; i < 2; ++i) {
444
+ DB_PRINT_L(1, "bus %d tx = %02x\n", i, tx_rx[i]);
445
+ tx_rx[i] = ssi_transfer(XILINX_SPIPS(s)->spi[i], tx_rx[i]);
446
+ DB_PRINT_L(1, "bus %d rx = %02x\n", i, tx_rx[i]);
447
+ }
448
+ if (s->regs[R_GQSPI_DATA_STS] > 1 &&
449
+ busses == 0x3 && num_stripes == 2) {
450
+ s->regs[R_GQSPI_DATA_STS] -= 2;
451
+ } else if (s->regs[R_GQSPI_DATA_STS] > 0) {
452
+ s->regs[R_GQSPI_DATA_STS]--;
453
+ }
454
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, RECIEVE)) {
455
+ for (i = 0; i < 2; ++i) {
456
+ if (busses & (1 << i)) {
457
+ DB_PRINT_L(1, "bus %d push_byte = %02x\n", i, tx_rx[i]);
458
+ fifo8_push(&s->rx_fifo_g, tx_rx[i]);
459
+ s->rx_fifo_g_align++;
460
+ }
461
+ }
462
+ }
463
+ if (!s->regs[R_GQSPI_DATA_STS]) {
464
+ for (; s->tx_fifo_g_align % 4; s->tx_fifo_g_align++) {
465
+ fifo8_pop(&s->tx_fifo_g);
466
+ }
467
+ for (; s->rx_fifo_g_align % 4; s->rx_fifo_g_align++) {
468
+ fifo8_push(&s->rx_fifo_g, 0);
469
+ }
470
+ }
471
+ }
472
+}
473
+
474
static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
475
{
476
if (!qs) {
477
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_check_flush(XilinxSPIPS *s)
478
xilinx_spips_update_ixr(s);
479
}
480
481
+static void xlnx_zynqmp_qspips_check_flush(XlnxZynqMPQSPIPS *s)
482
+{
483
+ bool gqspi_has_work = s->regs[R_GQSPI_DATA_STS] ||
484
+ !fifo32_is_empty(&s->fifo_g);
485
+
486
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_SELECT, GENERIC_QSPI_EN)) {
487
+ if (s->man_start_com_g || (gqspi_has_work &&
488
+ !ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, GEN_FIFO_START_MODE))) {
489
+ xlnx_zynqmp_qspips_flush_fifo_g(s);
490
+ }
491
+ } else {
492
+ xilinx_spips_check_flush(XILINX_SPIPS(s));
493
+ }
494
+ if (!gqspi_has_work) {
495
+ s->man_start_com_g = false;
496
+ }
497
+ xlnx_zynqmp_qspips_update_ixr(s);
498
+}
499
+
500
static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
501
{
502
int i;
503
@@ -XXX,XX +XXX,XX @@ static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
504
return max - i;
505
}
506
507
+static const void *pop_buf(Fifo8 *fifo, uint32_t max, uint32_t *num)
508
+{
509
+ void *ret;
510
+
511
+ if (max == 0 || max > fifo->num) {
512
+ abort();
513
+ }
514
+ *num = MIN(fifo->capacity - fifo->head, max);
515
+ ret = &fifo->data[fifo->head];
516
+ fifo->head += *num;
517
+ fifo->head %= fifo->capacity;
518
+ fifo->num -= *num;
519
+ return ret;
520
+}
521
+
522
+static void xlnx_zynqmp_qspips_notify(void *opaque)
523
+{
524
+ XlnxZynqMPQSPIPS *rq = XLNX_ZYNQMP_QSPIPS(opaque);
525
+ XilinxSPIPS *s = XILINX_SPIPS(rq);
526
+ Fifo8 *recv_fifo;
527
+
528
+ if (ARRAY_FIELD_EX32(rq->regs, GQSPI_SELECT, GENERIC_QSPI_EN)) {
529
+ if (!(ARRAY_FIELD_EX32(rq->regs, GQSPI_CNFG, MODE_EN) == 2)) {
530
+ return;
531
+ }
532
+ recv_fifo = &rq->rx_fifo_g;
533
+ } else {
534
+ if (!(s->regs[R_CMND] & R_CMND_DMA_EN)) {
535
+ return;
536
+ }
537
+ recv_fifo = &s->rx_fifo;
538
+ }
539
+ while (recv_fifo->num >= 4
540
+ && stream_can_push(rq->dma, xlnx_zynqmp_qspips_notify, rq))
541
+ {
542
+ size_t ret;
543
+ uint32_t num;
544
+ const void *rxd = pop_buf(recv_fifo, 4, &num);
545
+
546
+ memcpy(rq->dma_buf, rxd, num);
547
+
548
+ ret = stream_push(rq->dma, rq->dma_buf, 4);
549
+ assert(ret == 4);
550
+ xlnx_zynqmp_qspips_check_flush(rq);
551
+ }
552
+}
553
+
554
static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
555
unsigned size)
556
{
557
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
558
ret <<= 8 * shortfall;
559
}
560
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
561
+ xilinx_spips_check_flush(s);
562
xilinx_spips_update_ixr(s);
563
return ret;
564
}
565
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
566
567
}
568
569
+static uint64_t xlnx_zynqmp_qspips_read(void *opaque,
570
+ hwaddr addr, unsigned size)
571
+{
572
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(opaque);
573
+ uint32_t reg = addr / 4;
574
+ uint32_t ret;
575
+ uint8_t rx_buf[4];
576
+ int shortfall;
577
+
578
+ if (reg <= R_MOD_ID) {
579
+ return xilinx_spips_read(opaque, addr, size);
580
+ } else {
581
+ switch (reg) {
582
+ case R_GQSPI_RXD:
583
+ if (fifo8_is_empty(&s->rx_fifo_g)) {
584
+ qemu_log_mask(LOG_GUEST_ERROR,
585
+ "Read from empty GQSPI RX FIFO\n");
586
+ return 0;
587
+ }
588
+ memset(rx_buf, 0, sizeof(rx_buf));
589
+ shortfall = rx_data_bytes(&s->rx_fifo_g, rx_buf,
590
+ XILINX_SPIPS(s)->num_txrx_bytes);
591
+ ret = ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN) ?
592
+ cpu_to_be32(*(uint32_t *)rx_buf) :
593
+ cpu_to_le32(*(uint32_t *)rx_buf);
594
+ if (!ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN)) {
595
+ ret <<= 8 * shortfall;
596
+ }
597
+ xlnx_zynqmp_qspips_check_flush(s);
598
+ xlnx_zynqmp_qspips_update_ixr(s);
599
+ return ret;
600
+ default:
601
+ return s->regs[reg];
602
+ }
603
+ }
604
+}
605
+
606
static void xilinx_spips_write(void *opaque, hwaddr addr,
607
uint64_t value, unsigned size)
608
{
609
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_write(void *opaque, hwaddr addr,
610
}
611
}
612
613
+static void xlnx_zynqmp_qspips_write(void *opaque, hwaddr addr,
614
+ uint64_t value, unsigned size)
615
+{
616
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(opaque);
617
+ uint32_t reg = addr / 4;
618
+
619
+ if (reg <= R_MOD_ID) {
620
+ xilinx_qspips_write(opaque, addr, value, size);
621
+ } else {
622
+ switch (reg) {
623
+ case R_GQSPI_CNFG:
624
+ if (FIELD_EX32(value, GQSPI_CNFG, GEN_FIFO_START) &&
625
+ ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, GEN_FIFO_START_MODE)) {
626
+ s->man_start_com_g = true;
627
+ }
628
+ s->regs[reg] = value & ~(R_GQSPI_CNFG_GEN_FIFO_START_MASK);
629
+ break;
630
+ case R_GQSPI_GEN_FIFO:
631
+ if (!fifo32_is_full(&s->fifo_g)) {
632
+ fifo32_push(&s->fifo_g, value);
633
+ }
634
+ break;
635
+ case R_GQSPI_TXD:
636
+ tx_data_bytes(&s->tx_fifo_g, (uint32_t)value, 4,
637
+ ARRAY_FIELD_EX32(s->regs, GQSPI_CNFG, ENDIAN));
638
+ break;
639
+ case R_GQSPI_FIFO_CTRL:
640
+ if (FIELD_EX32(value, GQSPI_FIFO_CTRL, GENERIC_FIFO_RESET)) {
641
+ fifo32_reset(&s->fifo_g);
642
+ }
643
+ if (FIELD_EX32(value, GQSPI_FIFO_CTRL, TX_FIFO_RESET)) {
644
+ fifo8_reset(&s->tx_fifo_g);
645
+ }
646
+ if (FIELD_EX32(value, GQSPI_FIFO_CTRL, RX_FIFO_RESET)) {
647
+ fifo8_reset(&s->rx_fifo_g);
648
+ }
649
+ break;
650
+ case R_GQSPI_IDR:
651
+ s->regs[R_GQSPI_IMR] |= value;
652
+ break;
653
+ case R_GQSPI_IER:
654
+ s->regs[R_GQSPI_IMR] &= ~value;
655
+ break;
656
+ case R_GQSPI_ISR:
657
+ s->regs[R_GQSPI_ISR] &= ~value;
658
+ break;
659
+ case R_GQSPI_IMR:
660
+ case R_GQSPI_RXD:
661
+ case R_GQSPI_GF_SNAPSHOT:
662
+ case R_GQSPI_MOD_ID:
663
+ break;
664
+ default:
665
+ s->regs[reg] = value;
666
+ break;
667
+ }
668
+ xlnx_zynqmp_qspips_update_cs_lines(s);
669
+ xlnx_zynqmp_qspips_check_flush(s);
670
+ xlnx_zynqmp_qspips_update_cs_lines(s);
671
+ xlnx_zynqmp_qspips_update_ixr(s);
672
+ }
673
+ xlnx_zynqmp_qspips_notify(s);
674
+}
675
+
676
static const MemoryRegionOps qspips_ops = {
677
.read = xilinx_spips_read,
678
.write = xilinx_qspips_write,
679
.endianness = DEVICE_LITTLE_ENDIAN,
680
};
681
682
+static const MemoryRegionOps xlnx_zynqmp_qspips_ops = {
683
+ .read = xlnx_zynqmp_qspips_read,
684
+ .write = xlnx_zynqmp_qspips_write,
685
+ .endianness = DEVICE_LITTLE_ENDIAN,
686
+};
687
+
688
#define LQSPI_CACHE_SIZE 1024
689
690
static void lqspi_load_cache(void *opaque, hwaddr addr)
691
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
692
}
693
694
memory_region_init_io(&s->iomem, OBJECT(s), xsc->reg_ops, s,
695
- "spi", XLNX_SPIPS_R_MAX * 4);
696
+ "spi", XLNX_ZYNQMP_SPIPS_R_MAX * 4);
697
sysbus_init_mmio(sbd, &s->iomem);
698
699
s->irqline = -1;
700
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_realize(DeviceState *dev, Error **errp)
701
}
702
}
703
704
+static void xlnx_zynqmp_qspips_realize(DeviceState *dev, Error **errp)
705
+{
706
+ XlnxZynqMPQSPIPS *s = XLNX_ZYNQMP_QSPIPS(dev);
707
+ XilinxSPIPSClass *xsc = XILINX_SPIPS_GET_CLASS(s);
708
+
709
+ xilinx_qspips_realize(dev, errp);
710
+ fifo8_create(&s->rx_fifo_g, xsc->rx_fifo_size);
711
+ fifo8_create(&s->tx_fifo_g, xsc->tx_fifo_size);
712
+ fifo32_create(&s->fifo_g, 32);
713
+}
714
+
715
+static void xlnx_zynqmp_qspips_init(Object *obj)
716
+{
717
+ XlnxZynqMPQSPIPS *rq = XLNX_ZYNQMP_QSPIPS(obj);
718
+
719
+ object_property_add_link(obj, "stream-connected-dma", TYPE_STREAM_SLAVE,
720
+ (Object **)&rq->dma,
721
+ object_property_allow_set_link,
722
+ OBJ_PROP_LINK_UNREF_ON_RELEASE,
723
+ NULL);
724
+}
725
+
726
static int xilinx_spips_post_load(void *opaque, int version_id)
727
{
728
xilinx_spips_update_ixr((XilinxSPIPS *)opaque);
729
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_xilinx_spips = {
730
}
731
};
732
733
+static int xlnx_zynqmp_qspips_post_load(void *opaque, int version_id)
734
+{
735
+ XlnxZynqMPQSPIPS *s = (XlnxZynqMPQSPIPS *)opaque;
736
+ XilinxSPIPS *qs = XILINX_SPIPS(s);
737
+
738
+ if (ARRAY_FIELD_EX32(s->regs, GQSPI_SELECT, GENERIC_QSPI_EN) &&
739
+ fifo8_is_empty(&qs->rx_fifo) && fifo8_is_empty(&qs->tx_fifo)) {
740
+ xlnx_zynqmp_qspips_update_ixr(s);
741
+ xlnx_zynqmp_qspips_update_cs_lines(s);
742
+ }
743
+ return 0;
744
+}
745
+
746
+static const VMStateDescription vmstate_xilinx_qspips = {
747
+ .name = "xilinx_qspips",
748
+ .version_id = 1,
749
+ .minimum_version_id = 1,
750
+ .fields = (VMStateField[]) {
751
+ VMSTATE_STRUCT(parent_obj, XilinxQSPIPS, 0,
752
+ vmstate_xilinx_spips, XilinxSPIPS),
753
+ VMSTATE_END_OF_LIST()
754
+ }
755
+};
756
+
757
+static const VMStateDescription vmstate_xlnx_zynqmp_qspips = {
758
+ .name = "xlnx_zynqmp_qspips",
759
+ .version_id = 1,
760
+ .minimum_version_id = 1,
761
+ .post_load = xlnx_zynqmp_qspips_post_load,
762
+ .fields = (VMStateField[]) {
763
+ VMSTATE_STRUCT(parent_obj, XlnxZynqMPQSPIPS, 0,
764
+ vmstate_xilinx_qspips, XilinxQSPIPS),
765
+ VMSTATE_FIFO8(tx_fifo_g, XlnxZynqMPQSPIPS),
766
+ VMSTATE_FIFO8(rx_fifo_g, XlnxZynqMPQSPIPS),
767
+ VMSTATE_FIFO32(fifo_g, XlnxZynqMPQSPIPS),
768
+ VMSTATE_UINT32_ARRAY(regs, XlnxZynqMPQSPIPS, XLNX_ZYNQMP_SPIPS_R_MAX),
769
+ VMSTATE_END_OF_LIST()
770
+ }
771
+};
772
+
773
static Property xilinx_qspips_properties[] = {
774
/* We had to turn this off for 2.10 as it is not compatible with migration.
775
* It can be enabled but will prevent the device to be migrated.
776
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_class_init(ObjectClass *klass, void *data)
777
xsc->tx_fifo_size = TXFF_A;
778
}
779
780
+static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, void * data)
781
+{
782
+ DeviceClass *dc = DEVICE_CLASS(klass);
783
+ XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass);
784
+
785
+ dc->realize = xlnx_zynqmp_qspips_realize;
786
+ dc->reset = xlnx_zynqmp_qspips_reset;
787
+ dc->vmsd = &vmstate_xlnx_zynqmp_qspips;
788
+ xsc->reg_ops = &xlnx_zynqmp_qspips_ops;
789
+ xsc->rx_fifo_size = RXFF_A_Q;
790
+ xsc->tx_fifo_size = TXFF_A_Q;
791
+}
792
+
793
static const TypeInfo xilinx_spips_info = {
794
.name = TYPE_XILINX_SPIPS,
795
.parent = TYPE_SYS_BUS_DEVICE,
796
@@ -XXX,XX +XXX,XX @@ static const TypeInfo xilinx_qspips_info = {
797
.class_init = xilinx_qspips_class_init,
798
};
799
800
+static const TypeInfo xlnx_zynqmp_qspips_info = {
801
+ .name = TYPE_XLNX_ZYNQMP_QSPIPS,
802
+ .parent = TYPE_XILINX_QSPIPS,
803
+ .instance_size = sizeof(XlnxZynqMPQSPIPS),
804
+ .instance_init = xlnx_zynqmp_qspips_init,
805
+ .class_init = xlnx_zynqmp_qspips_class_init,
806
+};
807
+
808
static void xilinx_spips_register_types(void)
809
{
810
type_register_static(&xilinx_spips_info);
811
type_register_static(&xilinx_qspips_info);
812
+ type_register_static(&xlnx_zynqmp_qspips_info);
813
}
814
815
type_init(xilinx_spips_register_types)
816
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
817
index XXXXXXX..XXXXXXX 100644
146
index XXXXXXX..XXXXXXX 100644
818
--- a/default-configs/arm-softmmu.mak
147
--- a/tests/qtest/meson.build
819
+++ b/default-configs/arm-softmmu.mak
148
+++ b/tests/qtest/meson.build
820
@@ -XXX,XX +XXX,XX @@ CONFIG_SMBIOS=y
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
821
CONFIG_ASPEED_SOC=y
150
'npcm7xx_sdhci-test',
822
CONFIG_GPIO_KEY=y
151
'npcm7xx_smbus-test',
823
CONFIG_MSF2=y
152
'npcm7xx_timer-test',
824
-
153
- 'npcm7xx_watchdog_timer-test'] + \
825
CONFIG_FW_CFG_DMA=y
154
+ 'npcm7xx_watchdog_timer-test',
826
+CONFIG_XILINX_AXI=y
155
+ 'npcm_gmac-test'] + \
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
157
qtests_aspeed = \
158
['aspeed_hace-test',
827
--
159
--
828
2.7.4
160
2.34.1
829
830
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
From the very beginning, post_load() was called from common
3
An access fault is raised when the Access Flag is not set in the
4
reset. This is not standard and obliged to discriminate the
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
reset case from the restore case using the iidr value.
5
descriptor. This was already implemented for stage 2. Implement it for
6
stage 1 as well.
6
7
7
Let's get rid of that call.
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Tested-by: Mostafa Saleh <smostafa@google.com>
11
Message-id: 1511883692-11511-2-git-send-email-eric.auger@redhat.com
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
[PMM: tweaked comment text]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
15
---
14
hw/intc/arm_gicv3_its_common.c | 2 --
16
hw/arm/smmuv3-internal.h | 1 +
15
hw/intc/arm_gicv3_its_kvm.c | 4 ----
17
include/hw/arm/smmu-common.h | 1 +
16
2 files changed, 6 deletions(-)
18
hw/arm/smmu-common.c | 11 +++++++++++
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
17
21
18
diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
19
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/intc/arm_gicv3_its_common.c
24
--- a/hw/arm/smmuv3-internal.h
21
+++ b/hw/intc/arm_gicv3_its_common.c
25
+++ b/hw/arm/smmuv3-internal.h
22
@@ -XXX,XX +XXX,XX @@ static void gicv3_its_common_reset(DeviceState *dev)
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
23
s->creadr = 0;
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
24
s->iidr = 0;
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
25
memset(&s->baser, 0, sizeof(s->baser));
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
26
-
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
27
- gicv3_its_post_load(s, 0);
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
28
}
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
29
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
30
static void gicv3_its_common_class_init(ObjectClass *klass, void *data)
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
31
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
32
index XXXXXXX..XXXXXXX 100644
35
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/intc/arm_gicv3_its_kvm.c
36
--- a/include/hw/arm/smmu-common.h
34
+++ b/hw/intc/arm_gicv3_its_kvm.c
37
+++ b/include/hw/arm/smmu-common.h
35
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_post_load(GICv3ITSState *s)
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
36
{
39
bool disabled; /* smmu is disabled */
37
int i;
40
bool bypassed; /* translation is bypassed */
38
41
bool aborted; /* translation is aborted */
39
- if (!s->iidr) {
42
+ bool affd; /* AF fault disable */
40
- return;
43
uint32_t iotlb_hits; /* counts IOTLB hits */
41
- }
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
42
-
45
/* Used by stage-1 only. */
43
kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
44
GITS_IIDR, &s->iidr, true, &error_abort);
47
index XXXXXXX..XXXXXXX 100644
48
--- a/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
51
pte_addr, pte, iova, gpa,
52
block_size >> 20);
53
}
54
+
55
+ /*
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
58
+ * An Access flag fault takes priority over a Permission fault.
59
+ */
60
+ if (!PTE_AF(pte) && !cfg->affd) {
61
+ info->type = SMMU_PTW_ERR_ACCESS;
62
+ goto error;
63
+ }
64
+
65
ap = PTE_AP(pte);
66
if (is_permission_fault(ap, perm)) {
67
info->type = SMMU_PTW_ERR_PERMISSION;
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/smmuv3.c
71
+++ b/hw/arm/smmuv3.c
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
74
cfg->tbi = CD_TBI(cd);
75
cfg->asid = CD_ASID(cd);
76
+ cfg->affd = CD_AFFD(cd);
77
78
trace_smmuv3_decode_cd(cfg->oas);
45
79
46
--
80
--
47
2.7.4
81
2.34.1
48
49
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Make tx/rx_data_bytes more generic so they can be reused (when adding
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
support for the Zynqmp Generic QSPI).
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20171126231634.9531-9-frasse.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
7
---
12
hw/ssi/xilinx_spips.c | 64 +++++++++++++++++++++++++++++----------------------
8
hw/arm/stellaris.c | 6 ++++--
13
1 file changed, 37 insertions(+), 27 deletions(-)
9
1 file changed, 4 insertions(+), 2 deletions(-)
14
10
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
13
--- a/hw/arm/stellaris.c
18
+++ b/hw/ssi/xilinx_spips.c
14
+++ b/hw/arm/stellaris.c
19
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
20
/* config register */
21
#define R_CONFIG (0x00 / 4)
22
#define IFMODE (1U << 31)
23
-#define ENDIAN (1 << 26)
24
+#define R_CONFIG_ENDIAN (1 << 26)
25
#define MODEFAIL_GEN_EN (1 << 17)
26
#define MAN_START_COM (1 << 16)
27
#define MAN_START_EN (1 << 15)
28
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
29
}
16
}
30
}
17
}
31
18
32
-static inline void rx_data_bytes(XilinxSPIPS *s, uint8_t *value, int max)
19
-static void stellaris_adc_reset(StellarisADCState *s)
33
+static inline void tx_data_bytes(Fifo8 *fifo, uint32_t value, int num, bool be)
20
+static void stellaris_adc_reset_hold(Object *obj)
34
{
21
{
35
int i;
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
36
+ for (i = 0; i < num && !fifo8_is_full(fifo); ++i) {
23
int n;
37
+ if (be) {
24
38
+ fifo8_push(fifo, (uint8_t)(value >> 24));
25
for (n = 0; n < 4; n++) {
39
+ value <<= 8;
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
40
+ } else {
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
41
+ fifo8_push(fifo, (uint8_t)value);
28
"adc", 0x1000);
42
+ value >>= 8;
29
sysbus_init_mmio(sbd, &s->iomem);
43
+ }
30
- stellaris_adc_reset(s);
44
+ }
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
45
+}
46
47
- for (i = 0; i < max && !fifo8_is_empty(&s->rx_fifo); ++i) {
48
- value[i] = fifo8_pop(&s->rx_fifo);
49
+static inline int rx_data_bytes(Fifo8 *fifo, uint8_t *value, int max)
50
+{
51
+ int i;
52
+
53
+ for (i = 0; i < max && !fifo8_is_empty(fifo); ++i) {
54
+ value[i] = fifo8_pop(fifo);
55
}
56
+ return max - i;
57
}
32
}
58
33
59
static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
60
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
61
uint32_t mask = ~0;
36
{
62
uint32_t ret;
37
DeviceClass *dc = DEVICE_CLASS(klass);
63
uint8_t rx_buf[4];
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
64
+ int shortfall;
39
65
40
+ rc->phases.hold = stellaris_adc_reset_hold;
66
addr >>= 2;
41
dc->vmsd = &vmstate_stellaris_adc;
67
switch (addr) {
68
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
69
break;
70
case R_RX_DATA:
71
memset(rx_buf, 0, sizeof(rx_buf));
72
- rx_data_bytes(s, rx_buf, s->num_txrx_bytes);
73
- ret = s->regs[R_CONFIG] & ENDIAN ? cpu_to_be32(*(uint32_t *)rx_buf)
74
- : cpu_to_le32(*(uint32_t *)rx_buf);
75
+ shortfall = rx_data_bytes(&s->rx_fifo, rx_buf, s->num_txrx_bytes);
76
+ ret = s->regs[R_CONFIG] & R_CONFIG_ENDIAN ?
77
+ cpu_to_be32(*(uint32_t *)rx_buf) :
78
+ cpu_to_le32(*(uint32_t *)rx_buf);
79
+ if (!(s->regs[R_CONFIG] & R_CONFIG_ENDIAN)) {
80
+ ret <<= 8 * shortfall;
81
+ }
82
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
83
xilinx_spips_update_ixr(s);
84
return ret;
85
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
86
87
}
42
}
88
43
89
-static inline void tx_data_bytes(XilinxSPIPS *s, uint32_t value, int num)
90
-{
91
- int i;
92
- for (i = 0; i < num && !fifo8_is_full(&s->tx_fifo); ++i) {
93
- if (s->regs[R_CONFIG] & ENDIAN) {
94
- fifo8_push(&s->tx_fifo, (uint8_t)(value >> 24));
95
- value <<= 8;
96
- } else {
97
- fifo8_push(&s->tx_fifo, (uint8_t)value);
98
- value >>= 8;
99
- }
100
- }
101
-}
102
-
103
static void xilinx_spips_write(void *opaque, hwaddr addr,
104
uint64_t value, unsigned size)
105
{
106
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_write(void *opaque, hwaddr addr,
107
mask = 0;
108
break;
109
case R_TX_DATA:
110
- tx_data_bytes(s, (uint32_t)value, s->num_txrx_bytes);
111
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, s->num_txrx_bytes,
112
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
113
goto no_reg_update;
114
case R_TXD1:
115
- tx_data_bytes(s, (uint32_t)value, 1);
116
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, 1,
117
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
118
goto no_reg_update;
119
case R_TXD2:
120
- tx_data_bytes(s, (uint32_t)value, 2);
121
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, 2,
122
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
123
goto no_reg_update;
124
case R_TXD3:
125
- tx_data_bytes(s, (uint32_t)value, 3);
126
+ tx_data_bytes(&s->tx_fifo, (uint32_t)value, 3,
127
+ s->regs[R_CONFIG] & R_CONFIG_ENDIAN);
128
goto no_reg_update;
129
}
130
s->regs[addr] = (s->regs[addr] & ~mask) | (value & mask);
131
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
132
133
while (cache_entry < LQSPI_CACHE_SIZE) {
134
for (i = 0; i < 64; ++i) {
135
- tx_data_bytes(s, 0, 1);
136
+ tx_data_bytes(&s->tx_fifo, 0, 1, false);
137
}
138
xilinx_spips_flush_txfifo(s);
139
for (i = 0; i < 64; ++i) {
140
- rx_data_bytes(s, &q->lqspi_buf[cache_entry++], 1);
141
+ rx_data_bytes(&s->rx_fifo, &q->lqspi_buf[cache_entry++], 1);
142
}
143
}
144
145
--
44
--
146
2.7.4
45
2.34.1
147
46
148
47
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add support for the RX discard and RX drain functionality. Also transmit
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
one byte per dummy cycle (to the flash memories) with commands that require
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
these.
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20171126231634.9531-8-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
8
---
13
include/hw/ssi/xilinx_spips.h | 6 ++
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
14
hw/ssi/xilinx_spips.c | 167 +++++++++++++++++++++++++++++++++++++-----
10
1 file changed, 22 insertions(+), 4 deletions(-)
15
2 files changed, 155 insertions(+), 18 deletions(-)
16
11
17
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/ssi/xilinx_spips.h
14
--- a/hw/arm/stellaris.c
20
+++ b/include/hw/ssi/xilinx_spips.h
15
+++ b/hw/arm/stellaris.c
21
@@ -XXX,XX +XXX,XX @@ struct XilinxSPIPS {
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
22
uint8_t num_busses;
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
23
24
uint8_t snoop_state;
25
+ int cmd_dummies;
26
+ uint8_t link_state;
27
+ uint8_t link_state_next;
28
+ uint8_t link_state_next_when;
29
qemu_irq *cs_lines;
30
+ bool *cs_lines_state;
31
SSIBus **spi;
32
33
Fifo8 rx_fifo;
34
Fifo8 tx_fifo;
35
36
uint8_t num_txrx_bytes;
37
+ uint32_t rx_discard;
38
39
uint32_t regs[XLNX_SPIPS_R_MAX];
40
};
41
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/ssi/xilinx_spips.c
44
+++ b/hw/ssi/xilinx_spips.c
45
@@ -XXX,XX +XXX,XX @@
46
#include "qemu/bitops.h"
47
#include "hw/ssi/xilinx_spips.h"
48
#include "qapi/error.h"
49
+#include "hw/register.h"
50
#include "migration/blocker.h"
51
52
#ifndef XILINX_SPIPS_ERR_DEBUG
53
@@ -XXX,XX +XXX,XX @@
54
#define LQSPI_CFG_DUMMY_SHIFT 8
55
#define LQSPI_CFG_INST_CODE 0xFF
56
57
+#define R_CMND (0xc0 / 4)
58
+ #define R_CMND_RXFIFO_DRAIN (1 << 19)
59
+ FIELD(CMND, PARTIAL_BYTE_LEN, 16, 3)
60
+#define R_CMND_EXT_ADD (1 << 15)
61
+ FIELD(CMND, RX_DISCARD, 8, 7)
62
+ FIELD(CMND, DUMMY_CYCLES, 2, 6)
63
+#define R_CMND_DMA_EN (1 << 1)
64
+#define R_CMND_PUSH_WAIT (1 << 0)
65
#define R_LQSPI_STS (0xA4 / 4)
66
#define LQSPI_STS_WR_RECVD (1 << 1)
67
68
@@ -XXX,XX +XXX,XX @@
69
#define LQSPI_ADDRESS_BITS 24
70
71
#define SNOOP_CHECKING 0xFF
72
-#define SNOOP_NONE 0xFE
73
+#define SNOOP_ADDR 0xF0
74
+#define SNOOP_NONE 0xEE
75
#define SNOOP_STRIPING 0
76
77
static inline int num_effective_busses(XilinxSPIPS *s)
78
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
79
if (xilinx_spips_cs_is_set(s, i, field) && !found) {
80
DB_PRINT_L(0, "selecting slave %d\n", i);
81
qemu_set_irq(s->cs_lines[cs_to_set], 0);
82
+ if (s->cs_lines_state[cs_to_set]) {
83
+ s->cs_lines_state[cs_to_set] = false;
84
+ s->rx_discard = ARRAY_FIELD_EX32(s->regs, CMND, RX_DISCARD);
85
+ }
86
} else {
87
DB_PRINT_L(0, "deselecting slave %d\n", i);
88
qemu_set_irq(s->cs_lines[cs_to_set], 1);
89
+ s->cs_lines_state[cs_to_set] = true;
90
}
91
}
92
if (xilinx_spips_cs_is_set(s, i, field)) {
93
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_update_cs_lines(XilinxSPIPS *s)
94
}
95
if (!found) {
96
s->snoop_state = SNOOP_CHECKING;
97
+ s->cmd_dummies = 0;
98
+ s->link_state = 1;
99
+ s->link_state_next = 1;
100
+ s->link_state_next_when = 0;
101
DB_PRINT_L(1, "moving to snoop check state\n");
102
}
103
}
18
}
104
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
19
105
/* FIXME: move magic number definition somewhere sensible */
20
-/* I2C controller. */
106
s->regs[R_MOD_ID] = 0x01090106;
21
+/*
107
s->regs[R_LQSPI_CFG] = R_LQSPI_CFG_RESET;
22
+ * I2C controller.
108
+ s->link_state = 1;
23
+ * ??? For now we only implement the master interface.
109
+ s->link_state_next = 1;
24
+ */
110
+ s->link_state_next_when = 0;
25
111
s->snoop_state = SNOOP_CHECKING;
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
112
+ s->cmd_dummies = 0;
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
113
xilinx_spips_update_ixr(s);
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
114
xilinx_spips_update_cs_lines(s);
29
stellaris_i2c_update(s);
115
}
30
}
116
@@ -XXX,XX +XXX,XX @@ static inline void stripe8(uint8_t *x, int num, bool dir)
31
117
memcpy(x, r, sizeof(uint8_t) * num);
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
118
}
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
119
34
{
120
+static int xilinx_spips_num_dummies(XilinxQSPIPS *qs, uint8_t command)
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
121
+{
122
+ if (!qs) {
123
+ /* The SPI device is not a QSPI device */
124
+ return -1;
125
+ }
126
+
36
+
127
+ switch (command) { /* check for dummies */
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
128
+ case READ: /* no dummy bytes/cycles */
38
i2c_end_transfer(s->bus);
129
+ case PP:
130
+ case DPP:
131
+ case QPP:
132
+ case READ_4:
133
+ case PP_4:
134
+ case QPP_4:
135
+ return 0;
136
+ case FAST_READ:
137
+ case DOR:
138
+ case QOR:
139
+ case DOR_4:
140
+ case QOR_4:
141
+ return 1;
142
+ case DIOR:
143
+ case FAST_READ_4:
144
+ case DIOR_4:
145
+ return 2;
146
+ case QIOR:
147
+ case QIOR_4:
148
+ return 5;
149
+ default:
150
+ return -1;
151
+ }
152
+}
39
+}
153
+
40
+
154
+static inline uint8_t get_addr_length(XilinxSPIPS *s, uint8_t cmd)
41
+static void stellaris_i2c_reset_hold(Object *obj)
155
+{
42
+{
156
+ switch (cmd) {
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
157
+ case PP_4:
44
158
+ case QPP_4:
45
s->msa = 0;
159
+ case READ_4:
46
s->mcs = 0;
160
+ case QIOR_4:
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
161
+ case FAST_READ_4:
48
s->mimr = 0;
162
+ case DOR_4:
49
s->mris = 0;
163
+ case QOR_4:
50
s->mcr = 0;
164
+ case DIOR_4:
165
+ return 4;
166
+ default:
167
+ return (s->regs[R_CMND] & R_CMND_EXT_ADD) ? 4 : 3;
168
+ }
169
+}
51
+}
170
+
52
+
171
static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
53
+static void stellaris_i2c_reset_exit(Object *obj)
54
+{
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
56
+
57
stellaris_i2c_update(s);
58
}
59
60
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_init(Object *obj)
61
memory_region_init_io(&s->iomem, obj, &stellaris_i2c_ops, s,
62
"i2c", 0x1000);
63
sysbus_init_mmio(sbd, &s->iomem);
64
- /* ??? For now we only implement the master interface. */
65
- stellaris_i2c_reset(s);
66
}
67
68
/* Analogue to Digital Converter. This is only partially implemented,
69
@@ -XXX,XX +XXX,XX @@ type_init(stellaris_machine_init)
70
static void stellaris_i2c_class_init(ObjectClass *klass, void *data)
172
{
71
{
173
int debug_level = 0;
72
DeviceClass *dc = DEVICE_CLASS(klass);
174
+ XilinxQSPIPS *q = (XilinxQSPIPS *) object_dynamic_cast(OBJECT(s),
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
175
+ TYPE_XILINX_QSPIPS);
74
176
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
177
for (;;) {
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
178
int i;
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
179
uint8_t tx = 0;
78
dc->vmsd = &vmstate_stellaris_i2c;
180
uint8_t tx_rx[num_effective_busses(s)];
181
+ uint8_t dummy_cycles = 0;
182
+ uint8_t addr_length;
183
184
if (fifo8_is_empty(&s->tx_fifo)) {
185
if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
186
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
187
tx_rx[i] = fifo8_pop(&s->tx_fifo);
188
}
189
stripe8(tx_rx, num_effective_busses(s), false);
190
- } else {
191
+ } else if (s->snoop_state >= SNOOP_ADDR) {
192
tx = fifo8_pop(&s->tx_fifo);
193
for (i = 0; i < num_effective_busses(s); ++i) {
194
tx_rx[i] = tx;
195
}
196
+ } else {
197
+ /* Extract a dummy byte and generate dummy cycles according to the
198
+ * link state */
199
+ tx = fifo8_pop(&s->tx_fifo);
200
+ dummy_cycles = 8 / s->link_state;
201
}
202
203
for (i = 0; i < num_effective_busses(s); ++i) {
204
int bus = num_effective_busses(s) - 1 - i;
205
- DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]);
206
- tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]);
207
- DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
208
+ if (dummy_cycles) {
209
+ int d;
210
+ for (d = 0; d < dummy_cycles; ++d) {
211
+ tx_rx[0] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[0]);
212
+ }
213
+ } else {
214
+ DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]);
215
+ tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]);
216
+ DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
217
+ }
218
}
219
220
- if (fifo8_is_full(&s->rx_fifo)) {
221
+ if (s->regs[R_CMND] & R_CMND_RXFIFO_DRAIN) {
222
+ DB_PRINT_L(debug_level, "dircarding drained rx byte\n");
223
+ /* Do nothing */
224
+ } else if (s->rx_discard) {
225
+ DB_PRINT_L(debug_level, "dircarding discarded rx byte\n");
226
+ s->rx_discard -= 8 / s->link_state;
227
+ } else if (fifo8_is_full(&s->rx_fifo)) {
228
s->regs[R_INTR_STATUS] |= IXR_RX_FIFO_OVERFLOW;
229
DB_PRINT_L(0, "rx FIFO overflow");
230
} else if (s->snoop_state == SNOOP_STRIPING) {
231
stripe8(tx_rx, num_effective_busses(s), true);
232
for (i = 0; i < num_effective_busses(s); ++i) {
233
fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[i]);
234
+ DB_PRINT_L(debug_level, "pushing striped rx byte\n");
235
}
236
} else {
237
+ DB_PRINT_L(debug_level, "pushing unstriped rx byte\n");
238
fifo8_push(&s->rx_fifo, (uint8_t)tx_rx[0]);
239
}
240
241
+ if (s->link_state_next_when) {
242
+ s->link_state_next_when--;
243
+ if (!s->link_state_next_when) {
244
+ s->link_state = s->link_state_next;
245
+ }
246
+ }
247
+
248
DB_PRINT_L(debug_level, "initial snoop state: %x\n",
249
(unsigned)s->snoop_state);
250
switch (s->snoop_state) {
251
case (SNOOP_CHECKING):
252
- switch (tx) { /* new instruction code */
253
- case READ: /* 3 address bytes, no dummy bytes/cycles */
254
- case PP:
255
+ /* Store the count of dummy bytes in the txfifo */
256
+ s->cmd_dummies = xilinx_spips_num_dummies(q, tx);
257
+ addr_length = get_addr_length(s, tx);
258
+ if (s->cmd_dummies < 0) {
259
+ s->snoop_state = SNOOP_NONE;
260
+ } else {
261
+ s->snoop_state = SNOOP_ADDR + addr_length - 1;
262
+ }
263
+ switch (tx) {
264
case DPP:
265
- case QPP:
266
- s->snoop_state = 3;
267
- break;
268
- case FAST_READ: /* 3 address bytes, 1 dummy byte */
269
case DOR:
270
+ case DOR_4:
271
+ s->link_state_next = 2;
272
+ s->link_state_next_when = addr_length + s->cmd_dummies;
273
+ break;
274
+ case QPP:
275
+ case QPP_4:
276
case QOR:
277
- case DIOR: /* FIXME: these vary between vendor - set to spansion */
278
- s->snoop_state = 4;
279
+ case QOR_4:
280
+ s->link_state_next = 4;
281
+ s->link_state_next_when = addr_length + s->cmd_dummies;
282
+ break;
283
+ case DIOR:
284
+ case DIOR_4:
285
+ s->link_state = 2;
286
break;
287
- case QIOR: /* 3 address bytes, 2 dummy bytes */
288
- s->snoop_state = 6;
289
+ case QIOR:
290
+ case QIOR_4:
291
+ s->link_state = 4;
292
break;
293
- default:
294
+ }
295
+ break;
296
+ case (SNOOP_ADDR):
297
+ /* Address has been transmitted, transmit dummy cycles now if
298
+ * needed */
299
+ if (s->cmd_dummies < 0) {
300
s->snoop_state = SNOOP_NONE;
301
+ } else {
302
+ s->snoop_state = s->cmd_dummies;
303
}
304
break;
305
case (SNOOP_STRIPING):
306
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_write(void *opaque, hwaddr addr,
307
uint64_t value, unsigned size)
308
{
309
XilinxQSPIPS *q = XILINX_QSPIPS(opaque);
310
+ XilinxSPIPS *s = XILINX_SPIPS(opaque);
311
312
xilinx_spips_write(opaque, addr, value, size);
313
addr >>= 2;
314
@@ -XXX,XX +XXX,XX @@ static void xilinx_qspips_write(void *opaque, hwaddr addr,
315
if (addr == R_LQSPI_CFG) {
316
xilinx_qspips_invalidate_mmio_ptr(q);
317
}
318
+ if (s->regs[R_CMND] & R_CMND_RXFIFO_DRAIN) {
319
+ fifo8_reset(&s->rx_fifo);
320
+ }
321
}
79
}
322
80
323
static const MemoryRegionOps qspips_ops = {
324
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_realize(DeviceState *dev, Error **errp)
325
}
326
327
s->cs_lines = g_new0(qemu_irq, s->num_cs * s->num_busses);
328
+ s->cs_lines_state = g_new0(bool, s->num_cs * s->num_busses);
329
for (i = 0, cs = s->cs_lines; i < s->num_busses; ++i, cs += s->num_cs) {
330
ssi_auto_connect_slaves(DEVICE(s), cs, s->spi[i]);
331
}
332
--
81
--
333
2.7.4
82
2.34.1
334
83
335
84
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Voiding the ITS caches is not supposed to happen via
3
QDev objects created with qdev_new() need to manually add
4
individual register writes. So we introduced a dedicated
4
their parent relationship with object_property_add_child().
5
ITS KVM device ioctl to perform a cold reset of the ITS:
6
KVM_DEV_ARM_VGIC_GRP_CTRL/KVM_DEV_ARM_ITS_CTRL_RESET. Let's
7
use this latter if the kernel supports it.
8
5
9
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
This commit plug the devices which aren't part of the SoC;
7
they will be plugged into a SoC container in the next one.
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 1511883692-11511-5-git-send-email-eric.auger@redhat.com
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
hw/intc/arm_gicv3_its_kvm.c | 9 ++++++++-
14
hw/arm/stellaris.c | 4 ++++
15
1 file changed, 8 insertions(+), 1 deletion(-)
15
1 file changed, 4 insertions(+)
16
16
17
diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
18
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/intc/arm_gicv3_its_kvm.c
19
--- a/hw/arm/stellaris.c
20
+++ b/hw/intc/arm_gicv3_its_kvm.c
20
+++ b/hw/arm/stellaris.c
21
@@ -XXX,XX +XXX,XX @@ static void kvm_arm_its_reset(DeviceState *dev)
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
22
22
&error_fatal);
23
c->parent_reset(dev);
23
24
24
ssddev = qdev_new("ssd0323");
25
- error_report("ITS KVM: full reset is not supported by QEMU");
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
26
+ if (kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
26
qdev_prop_set_uint8(ssddev, "cs", 1);
27
+ KVM_DEV_ARM_ITS_CTRL_RESET)) {
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
28
+ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL,
28
29
+ KVM_DEV_ARM_ITS_CTRL_RESET, NULL, true, &error_abort);
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
30
+ return;
30
+ object_property_add_child(OBJECT(ms), "splitter",
31
+ }
31
+ OBJECT(gpio_d_splitter));
32
+
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
33
+ error_report("ITS KVM: full reset is not supported by the host kernel");
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
34
34
qdev_connect_gpio_out(
35
if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS,
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
36
GITS_CTLR)) {
36
DeviceState *gpad;
37
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
42
}
37
--
43
--
38
2.7.4
44
2.34.1
39
45
40
46
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Update headers against v4.15-rc1.
3
QDev objects created with qdev_new() need to manually add
4
their parent relationship with object_property_add_child().
4
5
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Since we don't model the SoC, just use a QOM container.
6
Message-id: 1511883692-11511-4-git-send-email-eric.auger@redhat.com
7
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
12
---
9
include/standard-headers/asm-s390/virtio-ccw.h | 1 +
13
hw/arm/stellaris.c | 11 ++++++++++-
10
include/standard-headers/asm-x86/hyperv.h | 394 +--------------------
14
1 file changed, 10 insertions(+), 1 deletion(-)
11
include/standard-headers/linux/input-event-codes.h | 2 +
12
include/standard-headers/linux/input.h | 1 +
13
include/standard-headers/linux/pci_regs.h | 45 ++-
14
linux-headers/asm-arm/kvm.h | 8 +
15
linux-headers/asm-arm/kvm_para.h | 1 +
16
linux-headers/asm-arm/unistd.h | 2 +
17
linux-headers/asm-arm64/kvm.h | 8 +
18
linux-headers/asm-arm64/unistd.h | 1 +
19
linux-headers/asm-powerpc/epapr_hcalls.h | 1 +
20
linux-headers/asm-powerpc/kvm.h | 1 +
21
linux-headers/asm-powerpc/kvm_para.h | 1 +
22
linux-headers/asm-powerpc/unistd.h | 1 +
23
linux-headers/asm-s390/kvm.h | 1 +
24
linux-headers/asm-s390/kvm_para.h | 1 +
25
linux-headers/asm-s390/unistd.h | 4 +-
26
linux-headers/asm-x86/kvm.h | 1 +
27
linux-headers/asm-x86/kvm_para.h | 2 +-
28
linux-headers/asm-x86/unistd.h | 1 +
29
linux-headers/linux/kvm.h | 2 +
30
linux-headers/linux/kvm_para.h | 1 +
31
linux-headers/linux/psci.h | 1 +
32
linux-headers/linux/userfaultfd.h | 1 +
33
linux-headers/linux/vfio.h | 1 +
34
linux-headers/linux/vfio_ccw.h | 1 +
35
linux-headers/linux/vhost.h | 1 +
36
27 files changed, 74 insertions(+), 411 deletions(-)
37
15
38
diff --git a/include/standard-headers/asm-s390/virtio-ccw.h b/include/standard-headers/asm-s390/virtio-ccw.h
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
39
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
40
--- a/include/standard-headers/asm-s390/virtio-ccw.h
18
--- a/hw/arm/stellaris.c
41
+++ b/include/standard-headers/asm-s390/virtio-ccw.h
19
+++ b/hw/arm/stellaris.c
42
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
43
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
21
* 400fe000 system control
44
/*
22
*/
45
* Definitions for virtio-ccw devices.
23
46
*
24
+ Object *soc_container;
47
diff --git a/include/standard-headers/asm-x86/hyperv.h b/include/standard-headers/asm-x86/hyperv.h
25
DeviceState *gpio_dev[7], *nvic;
48
index XXXXXXX..XXXXXXX 100644
26
qemu_irq gpio_in[7][8];
49
--- a/include/standard-headers/asm-x86/hyperv.h
27
qemu_irq gpio_out[7][8];
50
+++ b/include/standard-headers/asm-x86/hyperv.h
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
51
@@ -1,393 +1 @@
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
52
-#ifndef _ASM_X86_HYPERV_H
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
53
-#define _ASM_X86_HYPERV_H
31
32
+ soc_container = object_new("container");
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
34
+
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
37
&error_fatal);
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
39
* need its sysclk output.
40
*/
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
43
44
/*
45
* Most devices come preprogrammed with a MAC address in the user data.
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
48
49
nvic = qdev_new(TYPE_ARMV7M);
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
55
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
57
sbd = SYS_BUS_DEVICE(dev);
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
59
qdev_connect_clock_in(dev, "clk",
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
61
sysbus_realize_and_unref(sbd, &error_fatal);
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
63
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
54
-
66
-
55
-#include "standard-headers/linux/types.h"
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
56
-
68
qdev_connect_clock_in(dev, "WDOGCLK",
57
-/*
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
58
- * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
70
59
- * is set by CPUID(HvCpuIdFunctionVersionAndFeatures).
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
60
- */
72
SysBusDevice *sbd;
61
-#define HYPERV_CPUID_VENDOR_AND_MAX_FUNCTIONS    0x40000000
73
62
-#define HYPERV_CPUID_INTERFACE            0x40000001
74
dev = qdev_new("pl011_luminary");
63
-#define HYPERV_CPUID_VERSION            0x40000002
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
64
-#define HYPERV_CPUID_FEATURES            0x40000003
76
sbd = SYS_BUS_DEVICE(dev);
65
-#define HYPERV_CPUID_ENLIGHTMENT_INFO        0x40000004
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
66
-#define HYPERV_CPUID_IMPLEMENT_LIMITS        0x40000005
78
sysbus_realize_and_unref(sbd, &error_fatal);
67
-
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
68
-#define HYPERV_HYPERVISOR_PRESENT_BIT        0x80000000
80
DeviceState *enet;
69
-#define HYPERV_CPUID_MIN            0x40000005
81
70
-#define HYPERV_CPUID_MAX            0x4000ffff
82
enet = qdev_new("stellaris_enet");
71
-
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
72
-/*
84
if (nd) {
73
- * Feature identification. EAX indicates which features are available
85
qdev_set_nic_properties(enet, nd);
74
- * to the partition based upon the current partition privileges.
86
} else {
75
- */
76
-
77
-/* VP Runtime (HV_X64_MSR_VP_RUNTIME) available */
78
-#define HV_X64_MSR_VP_RUNTIME_AVAILABLE        (1 << 0)
79
-/* Partition Reference Counter (HV_X64_MSR_TIME_REF_COUNT) available*/
80
-#define HV_X64_MSR_TIME_REF_COUNT_AVAILABLE    (1 << 1)
81
-/* Partition reference TSC MSR is available */
82
-#define HV_X64_MSR_REFERENCE_TSC_AVAILABLE (1 << 9)
83
-
84
-/* A partition's reference time stamp counter (TSC) page */
85
-#define HV_X64_MSR_REFERENCE_TSC        0x40000021
86
-
87
-/*
88
- * There is a single feature flag that signifies if the partition has access
89
- * to MSRs with local APIC and TSC frequencies.
90
- */
91
-#define HV_X64_ACCESS_FREQUENCY_MSRS        (1 << 11)
92
-
93
-/*
94
- * Basic SynIC MSRs (HV_X64_MSR_SCONTROL through HV_X64_MSR_EOM
95
- * and HV_X64_MSR_SINT0 through HV_X64_MSR_SINT15) available
96
- */
97
-#define HV_X64_MSR_SYNIC_AVAILABLE        (1 << 2)
98
-/*
99
- * Synthetic Timer MSRs (HV_X64_MSR_STIMER0_CONFIG through
100
- * HV_X64_MSR_STIMER3_COUNT) available
101
- */
102
-#define HV_X64_MSR_SYNTIMER_AVAILABLE        (1 << 3)
103
-/*
104
- * APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
105
- * are available
106
- */
107
-#define HV_X64_MSR_APIC_ACCESS_AVAILABLE    (1 << 4)
108
-/* Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL) available*/
109
-#define HV_X64_MSR_HYPERCALL_AVAILABLE        (1 << 5)
110
-/* Access virtual processor index MSR (HV_X64_MSR_VP_INDEX) available*/
111
-#define HV_X64_MSR_VP_INDEX_AVAILABLE        (1 << 6)
112
-/* Virtual system reset MSR (HV_X64_MSR_RESET) is available*/
113
-#define HV_X64_MSR_RESET_AVAILABLE        (1 << 7)
114
- /*
115
- * Access statistics pages MSRs (HV_X64_MSR_STATS_PARTITION_RETAIL_PAGE,
116
- * HV_X64_MSR_STATS_PARTITION_INTERNAL_PAGE, HV_X64_MSR_STATS_VP_RETAIL_PAGE,
117
- * HV_X64_MSR_STATS_VP_INTERNAL_PAGE) available
118
- */
119
-#define HV_X64_MSR_STAT_PAGES_AVAILABLE        (1 << 8)
120
-
121
-/* Frequency MSRs available */
122
-#define HV_FEATURE_FREQUENCY_MSRS_AVAILABLE    (1 << 8)
123
-
124
-/* Crash MSR available */
125
-#define HV_FEATURE_GUEST_CRASH_MSR_AVAILABLE (1 << 10)
126
-
127
-/*
128
- * Feature identification: EBX indicates which flags were specified at
129
- * partition creation. The format is the same as the partition creation
130
- * flag structure defined in section Partition Creation Flags.
131
- */
132
-#define HV_X64_CREATE_PARTITIONS        (1 << 0)
133
-#define HV_X64_ACCESS_PARTITION_ID        (1 << 1)
134
-#define HV_X64_ACCESS_MEMORY_POOL        (1 << 2)
135
-#define HV_X64_ADJUST_MESSAGE_BUFFERS        (1 << 3)
136
-#define HV_X64_POST_MESSAGES            (1 << 4)
137
-#define HV_X64_SIGNAL_EVENTS            (1 << 5)
138
-#define HV_X64_CREATE_PORT            (1 << 6)
139
-#define HV_X64_CONNECT_PORT            (1 << 7)
140
-#define HV_X64_ACCESS_STATS            (1 << 8)
141
-#define HV_X64_DEBUGGING            (1 << 11)
142
-#define HV_X64_CPU_POWER_MANAGEMENT        (1 << 12)
143
-#define HV_X64_CONFIGURE_PROFILER        (1 << 13)
144
-
145
-/*
146
- * Feature identification. EDX indicates which miscellaneous features
147
- * are available to the partition.
148
- */
149
-/* The MWAIT instruction is available (per section MONITOR / MWAIT) */
150
-#define HV_X64_MWAIT_AVAILABLE                (1 << 0)
151
-/* Guest debugging support is available */
152
-#define HV_X64_GUEST_DEBUGGING_AVAILABLE        (1 << 1)
153
-/* Performance Monitor support is available*/
154
-#define HV_X64_PERF_MONITOR_AVAILABLE            (1 << 2)
155
-/* Support for physical CPU dynamic partitioning events is available*/
156
-#define HV_X64_CPU_DYNAMIC_PARTITIONING_AVAILABLE    (1 << 3)
157
-/*
158
- * Support for passing hypercall input parameter block via XMM
159
- * registers is available
160
- */
161
-#define HV_X64_HYPERCALL_PARAMS_XMM_AVAILABLE        (1 << 4)
162
-/* Support for a virtual guest idle state is available */
163
-#define HV_X64_GUEST_IDLE_STATE_AVAILABLE        (1 << 5)
164
-/* Guest crash data handler available */
165
-#define HV_X64_GUEST_CRASH_MSR_AVAILABLE        (1 << 10)
166
-
167
-/*
168
- * Implementation recommendations. Indicates which behaviors the hypervisor
169
- * recommends the OS implement for optimal performance.
170
- */
171
- /*
172
- * Recommend using hypercall for address space switches rather
173
- * than MOV to CR3 instruction
174
- */
175
-#define HV_X64_AS_SWITCH_RECOMMENDED        (1 << 0)
176
-/* Recommend using hypercall for local TLB flushes rather
177
- * than INVLPG or MOV to CR3 instructions */
178
-#define HV_X64_LOCAL_TLB_FLUSH_RECOMMENDED    (1 << 1)
179
-/*
180
- * Recommend using hypercall for remote TLB flushes rather
181
- * than inter-processor interrupts
182
- */
183
-#define HV_X64_REMOTE_TLB_FLUSH_RECOMMENDED    (1 << 2)
184
-/*
185
- * Recommend using MSRs for accessing APIC registers
186
- * EOI, ICR and TPR rather than their memory-mapped counterparts
187
- */
188
-#define HV_X64_APIC_ACCESS_RECOMMENDED        (1 << 3)
189
-/* Recommend using the hypervisor-provided MSR to initiate a system RESET */
190
-#define HV_X64_SYSTEM_RESET_RECOMMENDED        (1 << 4)
191
-/*
192
- * Recommend using relaxed timing for this partition. If used,
193
- * the VM should disable any watchdog timeouts that rely on the
194
- * timely delivery of external interrupts
195
- */
196
-#define HV_X64_RELAXED_TIMING_RECOMMENDED    (1 << 5)
197
-
198
-/*
199
- * Virtual APIC support
200
- */
201
-#define HV_X64_DEPRECATING_AEOI_RECOMMENDED    (1 << 9)
202
-
203
-/* Recommend using the newer ExProcessorMasks interface */
204
-#define HV_X64_EX_PROCESSOR_MASKS_RECOMMENDED    (1 << 11)
205
-
206
-/*
207
- * Crash notification flag.
208
- */
209
-#define HV_CRASH_CTL_CRASH_NOTIFY (1ULL << 63)
210
-
211
-/* MSR used to identify the guest OS. */
212
-#define HV_X64_MSR_GUEST_OS_ID            0x40000000
213
-
214
-/* MSR used to setup pages used to communicate with the hypervisor. */
215
-#define HV_X64_MSR_HYPERCALL            0x40000001
216
-
217
-/* MSR used to provide vcpu index */
218
-#define HV_X64_MSR_VP_INDEX            0x40000002
219
-
220
-/* MSR used to reset the guest OS. */
221
-#define HV_X64_MSR_RESET            0x40000003
222
-
223
-/* MSR used to provide vcpu runtime in 100ns units */
224
-#define HV_X64_MSR_VP_RUNTIME            0x40000010
225
-
226
-/* MSR used to read the per-partition time reference counter */
227
-#define HV_X64_MSR_TIME_REF_COUNT        0x40000020
228
-
229
-/* MSR used to retrieve the TSC frequency */
230
-#define HV_X64_MSR_TSC_FREQUENCY        0x40000022
231
-
232
-/* MSR used to retrieve the local APIC timer frequency */
233
-#define HV_X64_MSR_APIC_FREQUENCY        0x40000023
234
-
235
-/* Define the virtual APIC registers */
236
-#define HV_X64_MSR_EOI                0x40000070
237
-#define HV_X64_MSR_ICR                0x40000071
238
-#define HV_X64_MSR_TPR                0x40000072
239
-#define HV_X64_MSR_APIC_ASSIST_PAGE        0x40000073
240
-
241
-/* Define synthetic interrupt controller model specific registers. */
242
-#define HV_X64_MSR_SCONTROL            0x40000080
243
-#define HV_X64_MSR_SVERSION            0x40000081
244
-#define HV_X64_MSR_SIEFP            0x40000082
245
-#define HV_X64_MSR_SIMP                0x40000083
246
-#define HV_X64_MSR_EOM                0x40000084
247
-#define HV_X64_MSR_SINT0            0x40000090
248
-#define HV_X64_MSR_SINT1            0x40000091
249
-#define HV_X64_MSR_SINT2            0x40000092
250
-#define HV_X64_MSR_SINT3            0x40000093
251
-#define HV_X64_MSR_SINT4            0x40000094
252
-#define HV_X64_MSR_SINT5            0x40000095
253
-#define HV_X64_MSR_SINT6            0x40000096
254
-#define HV_X64_MSR_SINT7            0x40000097
255
-#define HV_X64_MSR_SINT8            0x40000098
256
-#define HV_X64_MSR_SINT9            0x40000099
257
-#define HV_X64_MSR_SINT10            0x4000009A
258
-#define HV_X64_MSR_SINT11            0x4000009B
259
-#define HV_X64_MSR_SINT12            0x4000009C
260
-#define HV_X64_MSR_SINT13            0x4000009D
261
-#define HV_X64_MSR_SINT14            0x4000009E
262
-#define HV_X64_MSR_SINT15            0x4000009F
263
-
264
-/*
265
- * Synthetic Timer MSRs. Four timers per vcpu.
266
- */
267
-#define HV_X64_MSR_STIMER0_CONFIG        0x400000B0
268
-#define HV_X64_MSR_STIMER0_COUNT        0x400000B1
269
-#define HV_X64_MSR_STIMER1_CONFIG        0x400000B2
270
-#define HV_X64_MSR_STIMER1_COUNT        0x400000B3
271
-#define HV_X64_MSR_STIMER2_CONFIG        0x400000B4
272
-#define HV_X64_MSR_STIMER2_COUNT        0x400000B5
273
-#define HV_X64_MSR_STIMER3_CONFIG        0x400000B6
274
-#define HV_X64_MSR_STIMER3_COUNT        0x400000B7
275
-
276
-/* Hyper-V guest crash notification MSR's */
277
-#define HV_X64_MSR_CRASH_P0            0x40000100
278
-#define HV_X64_MSR_CRASH_P1            0x40000101
279
-#define HV_X64_MSR_CRASH_P2            0x40000102
280
-#define HV_X64_MSR_CRASH_P3            0x40000103
281
-#define HV_X64_MSR_CRASH_P4            0x40000104
282
-#define HV_X64_MSR_CRASH_CTL            0x40000105
283
-#define HV_X64_MSR_CRASH_CTL_NOTIFY        (1ULL << 63)
284
-#define HV_X64_MSR_CRASH_PARAMS        \
285
-        (1 + (HV_X64_MSR_CRASH_P4 - HV_X64_MSR_CRASH_P0))
286
-
287
-#define HV_X64_MSR_HYPERCALL_ENABLE        0x00000001
288
-#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT    12
289
-#define HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_MASK    \
290
-        (~((1ull << HV_X64_MSR_HYPERCALL_PAGE_ADDRESS_SHIFT) - 1))
291
-
292
-/* Declare the various hypercall operations. */
293
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE    0x0002
294
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST    0x0003
295
-#define HVCALL_NOTIFY_LONG_SPIN_WAIT        0x0008
296
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_SPACE_EX 0x0013
297
-#define HVCALL_FLUSH_VIRTUAL_ADDRESS_LIST_EX 0x0014
298
-#define HVCALL_POST_MESSAGE            0x005c
299
-#define HVCALL_SIGNAL_EVENT            0x005d
300
-
301
-#define HV_X64_MSR_APIC_ASSIST_PAGE_ENABLE        0x00000001
302
-#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT    12
303
-#define HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_MASK    \
304
-        (~((1ull << HV_X64_MSR_APIC_ASSIST_PAGE_ADDRESS_SHIFT) - 1))
305
-
306
-#define HV_X64_MSR_TSC_REFERENCE_ENABLE        0x00000001
307
-#define HV_X64_MSR_TSC_REFERENCE_ADDRESS_SHIFT    12
308
-
309
-#define HV_PROCESSOR_POWER_STATE_C0        0
310
-#define HV_PROCESSOR_POWER_STATE_C1        1
311
-#define HV_PROCESSOR_POWER_STATE_C2        2
312
-#define HV_PROCESSOR_POWER_STATE_C3        3
313
-
314
-#define HV_FLUSH_ALL_PROCESSORS            BIT(0)
315
-#define HV_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES    BIT(1)
316
-#define HV_FLUSH_NON_GLOBAL_MAPPINGS_ONLY    BIT(2)
317
-#define HV_FLUSH_USE_EXTENDED_RANGE_FORMAT    BIT(3)
318
-
319
-enum HV_GENERIC_SET_FORMAT {
320
-    HV_GENERIC_SET_SPARCE_4K,
321
-    HV_GENERIC_SET_ALL,
322
-};
323
-
324
-/* hypercall status code */
325
-#define HV_STATUS_SUCCESS            0
326
-#define HV_STATUS_INVALID_HYPERCALL_CODE    2
327
-#define HV_STATUS_INVALID_HYPERCALL_INPUT    3
328
-#define HV_STATUS_INVALID_ALIGNMENT        4
329
-#define HV_STATUS_INSUFFICIENT_MEMORY        11
330
-#define HV_STATUS_INVALID_CONNECTION_ID        18
331
-#define HV_STATUS_INSUFFICIENT_BUFFERS        19
332
-
333
-typedef struct _HV_REFERENCE_TSC_PAGE {
334
-    uint32_t tsc_sequence;
335
-    uint32_t res1;
336
-    uint64_t tsc_scale;
337
-    int64_t tsc_offset;
338
-} HV_REFERENCE_TSC_PAGE, *PHV_REFERENCE_TSC_PAGE;
339
-
340
-/* Define the number of synthetic interrupt sources. */
341
-#define HV_SYNIC_SINT_COUNT        (16)
342
-/* Define the expected SynIC version. */
343
-#define HV_SYNIC_VERSION_1        (0x1)
344
-
345
-#define HV_SYNIC_CONTROL_ENABLE        (1ULL << 0)
346
-#define HV_SYNIC_SIMP_ENABLE        (1ULL << 0)
347
-#define HV_SYNIC_SIEFP_ENABLE        (1ULL << 0)
348
-#define HV_SYNIC_SINT_MASKED        (1ULL << 16)
349
-#define HV_SYNIC_SINT_AUTO_EOI        (1ULL << 17)
350
-#define HV_SYNIC_SINT_VECTOR_MASK    (0xFF)
351
-
352
-#define HV_SYNIC_STIMER_COUNT        (4)
353
-
354
-/* Define synthetic interrupt controller message constants. */
355
-#define HV_MESSAGE_SIZE            (256)
356
-#define HV_MESSAGE_PAYLOAD_BYTE_COUNT    (240)
357
-#define HV_MESSAGE_PAYLOAD_QWORD_COUNT    (30)
358
-
359
-/* Define hypervisor message types. */
360
-enum hv_message_type {
361
-    HVMSG_NONE            = 0x00000000,
362
-
363
-    /* Memory access messages. */
364
-    HVMSG_UNMAPPED_GPA        = 0x80000000,
365
-    HVMSG_GPA_INTERCEPT        = 0x80000001,
366
-
367
-    /* Timer notification messages. */
368
-    HVMSG_TIMER_EXPIRED            = 0x80000010,
369
-
370
-    /* Error messages. */
371
-    HVMSG_INVALID_VP_REGISTER_VALUE    = 0x80000020,
372
-    HVMSG_UNRECOVERABLE_EXCEPTION    = 0x80000021,
373
-    HVMSG_UNSUPPORTED_FEATURE        = 0x80000022,
374
-
375
-    /* Trace buffer complete messages. */
376
-    HVMSG_EVENTLOG_BUFFERCOMPLETE    = 0x80000040,
377
-
378
-    /* Platform-specific processor intercept messages. */
379
-    HVMSG_X64_IOPORT_INTERCEPT        = 0x80010000,
380
-    HVMSG_X64_MSR_INTERCEPT        = 0x80010001,
381
-    HVMSG_X64_CPUID_INTERCEPT        = 0x80010002,
382
-    HVMSG_X64_EXCEPTION_INTERCEPT    = 0x80010003,
383
-    HVMSG_X64_APIC_EOI            = 0x80010004,
384
-    HVMSG_X64_LEGACY_FP_ERROR        = 0x80010005
385
-};
386
-
387
-/* Define synthetic interrupt controller message flags. */
388
-union hv_message_flags {
389
-    uint8_t asu8;
390
-    struct {
391
-        uint8_t msg_pending:1;
392
-        uint8_t reserved:7;
393
-    };
394
-};
395
-
396
-/* Define port identifier type. */
397
-union hv_port_id {
398
-    uint32_t asu32;
399
-    struct {
400
-        uint32_t id:24;
401
-        uint32_t reserved:8;
402
-    } u;
403
-};
404
-
405
-/* Define synthetic interrupt controller message header. */
406
-struct hv_message_header {
407
-    uint32_t message_type;
408
-    uint8_t payload_size;
409
-    union hv_message_flags message_flags;
410
-    uint8_t reserved[2];
411
-    union {
412
-        uint64_t sender;
413
-        union hv_port_id port;
414
-    };
415
-};
416
-
417
-/* Define synthetic interrupt controller message format. */
418
-struct hv_message {
419
-    struct hv_message_header header;
420
-    union {
421
-        uint64_t payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT];
422
-    } u;
423
-};
424
-
425
-/* Define the synthetic interrupt message page layout. */
426
-struct hv_message_page {
427
-    struct hv_message sint_message[HV_SYNIC_SINT_COUNT];
428
-};
429
-
430
-/* Define timer message payload structure. */
431
-struct hv_timer_message_payload {
432
-    uint32_t timer_index;
433
-    uint32_t reserved;
434
-    uint64_t expiration_time;    /* When the timer expired */
435
-    uint64_t delivery_time;    /* When the message was delivered */
436
-};
437
-
438
-#define HV_STIMER_ENABLE        (1ULL << 0)
439
-#define HV_STIMER_PERIODIC        (1ULL << 1)
440
-#define HV_STIMER_LAZY            (1ULL << 2)
441
-#define HV_STIMER_AUTOENABLE        (1ULL << 3)
442
-#define HV_STIMER_SINT(config)        (uint8_t)(((config) >> 16) & 0x0F)
443
-
444
-#endif
445
+ /* this is a temporary placeholder until kvm_para.h stops including it */
446
diff --git a/include/standard-headers/linux/input-event-codes.h b/include/standard-headers/linux/input-event-codes.h
447
index XXXXXXX..XXXXXXX 100644
448
--- a/include/standard-headers/linux/input-event-codes.h
449
+++ b/include/standard-headers/linux/input-event-codes.h
450
@@ -XXX,XX +XXX,XX @@
451
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
452
/*
453
* Input event codes
454
*
455
@@ -XXX,XX +XXX,XX @@
456
#define BTN_TOOL_MOUSE        0x146
457
#define BTN_TOOL_LENS        0x147
458
#define BTN_TOOL_QUINTTAP    0x148    /* Five fingers on trackpad */
459
+#define BTN_STYLUS3        0x149
460
#define BTN_TOUCH        0x14a
461
#define BTN_STYLUS        0x14b
462
#define BTN_STYLUS2        0x14c
463
diff --git a/include/standard-headers/linux/input.h b/include/standard-headers/linux/input.h
464
index XXXXXXX..XXXXXXX 100644
465
--- a/include/standard-headers/linux/input.h
466
+++ b/include/standard-headers/linux/input.h
467
@@ -XXX,XX +XXX,XX @@
468
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
469
/*
470
* Copyright (c) 1999-2002 Vojtech Pavlik
471
*
472
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
473
index XXXXXXX..XXXXXXX 100644
474
--- a/include/standard-headers/linux/pci_regs.h
475
+++ b/include/standard-headers/linux/pci_regs.h
476
@@ -XXX,XX +XXX,XX @@
477
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
478
/*
479
*    pci_regs.h
480
*
481
@@ -XXX,XX +XXX,XX @@
482
#define PCI_ERR_ROOT_FIRST_FATAL    0x00000010 /* First UNC is Fatal */
483
#define PCI_ERR_ROOT_NONFATAL_RCV    0x00000020 /* Non-Fatal Received */
484
#define PCI_ERR_ROOT_FATAL_RCV        0x00000040 /* Fatal Received */
485
+#define PCI_ERR_ROOT_AER_IRQ        0xf8000000 /* Advanced Error Interrupt Message Number */
486
#define PCI_ERR_ROOT_ERR_SRC    52    /* Error Source Identification */
487
488
/* Virtual Channel */
489
@@ -XXX,XX +XXX,XX @@
490
#define PCI_SATA_SIZEOF_LONG    16
491
492
/* Resizable BARs */
493
+#define PCI_REBAR_CAP        4    /* capability register */
494
+#define PCI_REBAR_CAP_SIZES        0x00FFFFF0 /* supported BAR sizes */
495
#define PCI_REBAR_CTRL        8    /* control register */
496
-#define PCI_REBAR_CTRL_NBAR_MASK    (7 << 5)    /* mask for # bars */
497
-#define PCI_REBAR_CTRL_NBAR_SHIFT    5    /* shift for # bars */
498
+#define PCI_REBAR_CTRL_BAR_IDX        0x00000007 /* BAR index */
499
+#define PCI_REBAR_CTRL_NBAR_MASK    0x000000E0 /* # of resizable BARs */
500
+#define PCI_REBAR_CTRL_NBAR_SHIFT    5      /* shift for # of BARs */
501
+#define PCI_REBAR_CTRL_BAR_SIZE    0x00001F00 /* BAR size */
502
503
/* Dynamic Power Allocation */
504
#define PCI_DPA_CAP        4    /* capability register */
505
@@ -XXX,XX +XXX,XX @@
506
507
/* Downstream Port Containment */
508
#define PCI_EXP_DPC_CAP            4    /* DPC Capability */
509
+#define PCI_EXP_DPC_IRQ            0x1f    /* DPC Interrupt Message Number */
510
#define PCI_EXP_DPC_CAP_RP_EXT        0x20    /* Root Port Extensions for DPC */
511
#define PCI_EXP_DPC_CAP_POISONED_TLP    0x40    /* Poisoned TLP Egress Blocking Supported */
512
#define PCI_EXP_DPC_CAP_SW_TRIGGER    0x80    /* Software Triggering Supported */
513
@@ -XXX,XX +XXX,XX @@
514
#define PCI_PTM_CTRL_ENABLE        0x00000001 /* PTM enable */
515
#define PCI_PTM_CTRL_ROOT        0x00000002 /* Root select */
516
517
-/* L1 PM Substates */
518
-#define PCI_L1SS_CAP         4    /* capability register */
519
-#define PCI_L1SS_CAP_PCIPM_L1_2     1    /* PCI PM L1.2 Support */
520
-#define PCI_L1SS_CAP_PCIPM_L1_1     2    /* PCI PM L1.1 Support */
521
-#define PCI_L1SS_CAP_ASPM_L1_2         4    /* ASPM L1.2 Support */
522
-#define PCI_L1SS_CAP_ASPM_L1_1         8    /* ASPM L1.1 Support */
523
-#define PCI_L1SS_CAP_L1_PM_SS        16    /* L1 PM Substates Support */
524
-#define PCI_L1SS_CTL1         8    /* Control Register 1 */
525
-#define PCI_L1SS_CTL1_PCIPM_L1_2    1    /* PCI PM L1.2 Enable */
526
-#define PCI_L1SS_CTL1_PCIPM_L1_1    2    /* PCI PM L1.1 Support */
527
-#define PCI_L1SS_CTL1_ASPM_L1_2    4    /* ASPM L1.2 Support */
528
-#define PCI_L1SS_CTL1_ASPM_L1_1    8    /* ASPM L1.1 Support */
529
-#define PCI_L1SS_CTL1_L1SS_MASK    0x0000000F
530
-#define PCI_L1SS_CTL2         0xC    /* Control Register 2 */
531
+/* ASPM L1 PM Substates */
532
+#define PCI_L1SS_CAP        0x04    /* Capabilities Register */
533
+#define PCI_L1SS_CAP_PCIPM_L1_2    0x00000001 /* PCI-PM L1.2 Supported */
534
+#define PCI_L1SS_CAP_PCIPM_L1_1    0x00000002 /* PCI-PM L1.1 Supported */
535
+#define PCI_L1SS_CAP_ASPM_L1_2        0x00000004 /* ASPM L1.2 Supported */
536
+#define PCI_L1SS_CAP_ASPM_L1_1        0x00000008 /* ASPM L1.1 Supported */
537
+#define PCI_L1SS_CAP_L1_PM_SS        0x00000010 /* L1 PM Substates Supported */
538
+#define PCI_L1SS_CAP_CM_RESTORE_TIME    0x0000ff00 /* Port Common_Mode_Restore_Time */
539
+#define PCI_L1SS_CAP_P_PWR_ON_SCALE    0x00030000 /* Port T_POWER_ON scale */
540
+#define PCI_L1SS_CAP_P_PWR_ON_VALUE    0x00f80000 /* Port T_POWER_ON value */
541
+#define PCI_L1SS_CTL1        0x08    /* Control 1 Register */
542
+#define PCI_L1SS_CTL1_PCIPM_L1_2    0x00000001 /* PCI-PM L1.2 Enable */
543
+#define PCI_L1SS_CTL1_PCIPM_L1_1    0x00000002 /* PCI-PM L1.1 Enable */
544
+#define PCI_L1SS_CTL1_ASPM_L1_2    0x00000004 /* ASPM L1.2 Enable */
545
+#define PCI_L1SS_CTL1_ASPM_L1_1    0x00000008 /* ASPM L1.1 Enable */
546
+#define PCI_L1SS_CTL1_L1SS_MASK    0x0000000f
547
+#define PCI_L1SS_CTL1_CM_RESTORE_TIME    0x0000ff00 /* Common_Mode_Restore_Time */
548
+#define PCI_L1SS_CTL1_LTR_L12_TH_VALUE    0x03ff0000 /* LTR_L1.2_THRESHOLD_Value */
549
+#define PCI_L1SS_CTL1_LTR_L12_TH_SCALE    0xe0000000 /* LTR_L1.2_THRESHOLD_Scale */
550
+#define PCI_L1SS_CTL2        0x0c    /* Control 2 Register */
551
552
#endif /* LINUX_PCI_REGS_H */
553
diff --git a/linux-headers/asm-arm/kvm.h b/linux-headers/asm-arm/kvm.h
554
index XXXXXXX..XXXXXXX 100644
555
--- a/linux-headers/asm-arm/kvm.h
556
+++ b/linux-headers/asm-arm/kvm.h
557
@@ -XXX,XX +XXX,XX @@
558
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
559
/*
560
* Copyright (C) 2012 - Virtual Open Systems and Columbia University
561
* Author: Christoffer Dall <c.dall@virtualopensystems.com>
562
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
563
    (__ARM_CP15_REG(op1, 0, crm, 0) | KVM_REG_SIZE_U64)
564
#define ARM_CP15_REG64(...) __ARM_CP15_REG64(__VA_ARGS__)
565
566
+/* PL1 Physical Timer Registers */
567
+#define KVM_REG_ARM_PTIMER_CTL        ARM_CP15_REG32(0, 14, 2, 1)
568
+#define KVM_REG_ARM_PTIMER_CNT        ARM_CP15_REG64(0, 14)
569
+#define KVM_REG_ARM_PTIMER_CVAL        ARM_CP15_REG64(2, 14)
570
+
571
+/* Virtual Timer Registers */
572
#define KVM_REG_ARM_TIMER_CTL        ARM_CP15_REG32(0, 14, 3, 1)
573
#define KVM_REG_ARM_TIMER_CNT        ARM_CP15_REG64(1, 14)
574
#define KVM_REG_ARM_TIMER_CVAL        ARM_CP15_REG64(3, 14)
575
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
576
#define KVM_DEV_ARM_ITS_SAVE_TABLES        1
577
#define KVM_DEV_ARM_ITS_RESTORE_TABLES    2
578
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES    3
579
+#define KVM_DEV_ARM_ITS_CTRL_RESET        4
580
581
/* KVM_IRQ_LINE irq field index values */
582
#define KVM_ARM_IRQ_TYPE_SHIFT        24
583
diff --git a/linux-headers/asm-arm/kvm_para.h b/linux-headers/asm-arm/kvm_para.h
584
index XXXXXXX..XXXXXXX 100644
585
--- a/linux-headers/asm-arm/kvm_para.h
586
+++ b/linux-headers/asm-arm/kvm_para.h
587
@@ -1 +1,2 @@
588
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
589
#include <asm-generic/kvm_para.h>
590
diff --git a/linux-headers/asm-arm/unistd.h b/linux-headers/asm-arm/unistd.h
591
index XXXXXXX..XXXXXXX 100644
592
--- a/linux-headers/asm-arm/unistd.h
593
+++ b/linux-headers/asm-arm/unistd.h
594
@@ -XXX,XX +XXX,XX @@
595
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
596
/*
597
* arch/arm/include/asm/unistd.h
598
*
599
@@ -XXX,XX +XXX,XX @@
600
#define __ARM_NR_usr26            (__ARM_NR_BASE+3)
601
#define __ARM_NR_usr32            (__ARM_NR_BASE+4)
602
#define __ARM_NR_set_tls        (__ARM_NR_BASE+5)
603
+#define __ARM_NR_get_tls        (__ARM_NR_BASE+6)
604
605
#endif /* __ASM_ARM_UNISTD_H */
606
diff --git a/linux-headers/asm-arm64/kvm.h b/linux-headers/asm-arm64/kvm.h
607
index XXXXXXX..XXXXXXX 100644
608
--- a/linux-headers/asm-arm64/kvm.h
609
+++ b/linux-headers/asm-arm64/kvm.h
610
@@ -XXX,XX +XXX,XX @@
611
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
612
/*
613
* Copyright (C) 2012,2013 - ARM Ltd
614
* Author: Marc Zyngier <marc.zyngier@arm.com>
615
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
616
617
#define ARM64_SYS_REG(...) (__ARM64_SYS_REG(__VA_ARGS__) | KVM_REG_SIZE_U64)
618
619
+/* Physical Timer EL0 Registers */
620
+#define KVM_REG_ARM_PTIMER_CTL        ARM64_SYS_REG(3, 3, 14, 2, 1)
621
+#define KVM_REG_ARM_PTIMER_CVAL        ARM64_SYS_REG(3, 3, 14, 2, 2)
622
+#define KVM_REG_ARM_PTIMER_CNT        ARM64_SYS_REG(3, 3, 14, 0, 1)
623
+
624
+/* EL0 Virtual Timer Registers */
625
#define KVM_REG_ARM_TIMER_CTL        ARM64_SYS_REG(3, 3, 14, 3, 1)
626
#define KVM_REG_ARM_TIMER_CNT        ARM64_SYS_REG(3, 3, 14, 3, 2)
627
#define KVM_REG_ARM_TIMER_CVAL        ARM64_SYS_REG(3, 3, 14, 0, 2)
628
@@ -XXX,XX +XXX,XX @@ struct kvm_arch_memory_slot {
629
#define KVM_DEV_ARM_ITS_SAVE_TABLES 1
630
#define KVM_DEV_ARM_ITS_RESTORE_TABLES 2
631
#define KVM_DEV_ARM_VGIC_SAVE_PENDING_TABLES    3
632
+#define KVM_DEV_ARM_ITS_CTRL_RESET        4
633
634
/* Device Control API on vcpu fd */
635
#define KVM_ARM_VCPU_PMU_V3_CTRL    0
636
diff --git a/linux-headers/asm-arm64/unistd.h b/linux-headers/asm-arm64/unistd.h
637
index XXXXXXX..XXXXXXX 100644
638
--- a/linux-headers/asm-arm64/unistd.h
639
+++ b/linux-headers/asm-arm64/unistd.h
640
@@ -XXX,XX +XXX,XX @@
641
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
642
/*
643
* Copyright (C) 2012 ARM Ltd.
644
*
645
diff --git a/linux-headers/asm-powerpc/epapr_hcalls.h b/linux-headers/asm-powerpc/epapr_hcalls.h
646
index XXXXXXX..XXXXXXX 100644
647
--- a/linux-headers/asm-powerpc/epapr_hcalls.h
648
+++ b/linux-headers/asm-powerpc/epapr_hcalls.h
649
@@ -XXX,XX +XXX,XX @@
650
+/* SPDX-License-Identifier: ((GPL-2.0+ WITH Linux-syscall-note) OR BSD-3-Clause) */
651
/*
652
* ePAPR hcall interface
653
*
654
diff --git a/linux-headers/asm-powerpc/kvm.h b/linux-headers/asm-powerpc/kvm.h
655
index XXXXXXX..XXXXXXX 100644
656
--- a/linux-headers/asm-powerpc/kvm.h
657
+++ b/linux-headers/asm-powerpc/kvm.h
658
@@ -XXX,XX +XXX,XX @@
659
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
660
/*
661
* This program is free software; you can redistribute it and/or modify
662
* it under the terms of the GNU General Public License, version 2, as
663
diff --git a/linux-headers/asm-powerpc/kvm_para.h b/linux-headers/asm-powerpc/kvm_para.h
664
index XXXXXXX..XXXXXXX 100644
665
--- a/linux-headers/asm-powerpc/kvm_para.h
666
+++ b/linux-headers/asm-powerpc/kvm_para.h
667
@@ -XXX,XX +XXX,XX @@
668
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
669
/*
670
* This program is free software; you can redistribute it and/or modify
671
* it under the terms of the GNU General Public License, version 2, as
672
diff --git a/linux-headers/asm-powerpc/unistd.h b/linux-headers/asm-powerpc/unistd.h
673
index XXXXXXX..XXXXXXX 100644
674
--- a/linux-headers/asm-powerpc/unistd.h
675
+++ b/linux-headers/asm-powerpc/unistd.h
676
@@ -XXX,XX +XXX,XX @@
677
+/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
678
/*
679
* This file contains the system call numbers.
680
*
681
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
682
index XXXXXXX..XXXXXXX 100644
683
--- a/linux-headers/asm-s390/kvm.h
684
+++ b/linux-headers/asm-s390/kvm.h
685
@@ -XXX,XX +XXX,XX @@
686
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
687
#ifndef __LINUX_KVM_S390_H
688
#define __LINUX_KVM_S390_H
689
/*
690
diff --git a/linux-headers/asm-s390/kvm_para.h b/linux-headers/asm-s390/kvm_para.h
691
index XXXXXXX..XXXXXXX 100644
692
--- a/linux-headers/asm-s390/kvm_para.h
693
+++ b/linux-headers/asm-s390/kvm_para.h
694
@@ -XXX,XX +XXX,XX @@
695
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
696
/*
697
* User API definitions for paravirtual devices on s390
698
*
699
diff --git a/linux-headers/asm-s390/unistd.h b/linux-headers/asm-s390/unistd.h
700
index XXXXXXX..XXXXXXX 100644
701
--- a/linux-headers/asm-s390/unistd.h
702
+++ b/linux-headers/asm-s390/unistd.h
703
@@ -XXX,XX +XXX,XX @@
704
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
705
/*
706
* S390 version
707
*
708
@@ -XXX,XX +XXX,XX @@
709
#define __NR_pwritev2        377
710
#define __NR_s390_guarded_storage    378
711
#define __NR_statx        379
712
-#define NR_syscalls 380
713
+#define __NR_s390_sthyi        380
714
+#define NR_syscalls 381
715
716
/*
717
* There are some system calls that are not present on 64 bit, some
718
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
719
index XXXXXXX..XXXXXXX 100644
720
--- a/linux-headers/asm-x86/kvm.h
721
+++ b/linux-headers/asm-x86/kvm.h
722
@@ -XXX,XX +XXX,XX @@
723
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
724
#ifndef _ASM_X86_KVM_H
725
#define _ASM_X86_KVM_H
726
727
diff --git a/linux-headers/asm-x86/kvm_para.h b/linux-headers/asm-x86/kvm_para.h
728
index XXXXXXX..XXXXXXX 100644
729
--- a/linux-headers/asm-x86/kvm_para.h
730
+++ b/linux-headers/asm-x86/kvm_para.h
731
@@ -XXX,XX +XXX,XX @@
732
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
733
#ifndef _ASM_X86_KVM_PARA_H
734
#define _ASM_X86_KVM_PARA_H
735
736
@@ -XXX,XX +XXX,XX @@ struct kvm_vcpu_pv_apf_data {
737
#define KVM_PV_EOI_ENABLED KVM_PV_EOI_MASK
738
#define KVM_PV_EOI_DISABLED 0x0
739
740
-
741
#endif /* _ASM_X86_KVM_PARA_H */
742
diff --git a/linux-headers/asm-x86/unistd.h b/linux-headers/asm-x86/unistd.h
743
index XXXXXXX..XXXXXXX 100644
744
--- a/linux-headers/asm-x86/unistd.h
745
+++ b/linux-headers/asm-x86/unistd.h
746
@@ -XXX,XX +XXX,XX @@
747
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
748
#ifndef _ASM_X86_UNISTD_H
749
#define _ASM_X86_UNISTD_H
750
751
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
752
index XXXXXXX..XXXXXXX 100644
753
--- a/linux-headers/linux/kvm.h
754
+++ b/linux-headers/linux/kvm.h
755
@@ -XXX,XX +XXX,XX @@
756
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
757
#ifndef __LINUX_KVM_H
758
#define __LINUX_KVM_H
759
760
@@ -XXX,XX +XXX,XX @@ struct kvm_ppc_resize_hpt {
761
#define KVM_CAP_PPC_SMT_POSSIBLE 147
762
#define KVM_CAP_HYPERV_SYNIC2 148
763
#define KVM_CAP_HYPERV_VP_INDEX 149
764
+#define KVM_CAP_S390_AIS_MIGRATION 150
765
766
#ifdef KVM_CAP_IRQ_ROUTING
767
768
diff --git a/linux-headers/linux/kvm_para.h b/linux-headers/linux/kvm_para.h
769
index XXXXXXX..XXXXXXX 100644
770
--- a/linux-headers/linux/kvm_para.h
771
+++ b/linux-headers/linux/kvm_para.h
772
@@ -XXX,XX +XXX,XX @@
773
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
774
#ifndef __LINUX_KVM_PARA_H
775
#define __LINUX_KVM_PARA_H
776
777
diff --git a/linux-headers/linux/psci.h b/linux-headers/linux/psci.h
778
index XXXXXXX..XXXXXXX 100644
779
--- a/linux-headers/linux/psci.h
780
+++ b/linux-headers/linux/psci.h
781
@@ -XXX,XX +XXX,XX @@
782
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
783
/*
784
* ARM Power State and Coordination Interface (PSCI) header
785
*
786
diff --git a/linux-headers/linux/userfaultfd.h b/linux-headers/linux/userfaultfd.h
787
index XXXXXXX..XXXXXXX 100644
788
--- a/linux-headers/linux/userfaultfd.h
789
+++ b/linux-headers/linux/userfaultfd.h
790
@@ -XXX,XX +XXX,XX @@
791
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
792
/*
793
* include/linux/userfaultfd.h
794
*
795
diff --git a/linux-headers/linux/vfio.h b/linux-headers/linux/vfio.h
796
index XXXXXXX..XXXXXXX 100644
797
--- a/linux-headers/linux/vfio.h
798
+++ b/linux-headers/linux/vfio.h
799
@@ -XXX,XX +XXX,XX @@
800
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
801
/*
802
* VFIO API definition
803
*
804
diff --git a/linux-headers/linux/vfio_ccw.h b/linux-headers/linux/vfio_ccw.h
805
index XXXXXXX..XXXXXXX 100644
806
--- a/linux-headers/linux/vfio_ccw.h
807
+++ b/linux-headers/linux/vfio_ccw.h
808
@@ -XXX,XX +XXX,XX @@
809
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
810
/*
811
* Interfaces for vfio-ccw
812
*
813
diff --git a/linux-headers/linux/vhost.h b/linux-headers/linux/vhost.h
814
index XXXXXXX..XXXXXXX 100644
815
--- a/linux-headers/linux/vhost.h
816
+++ b/linux-headers/linux/vhost.h
817
@@ -XXX,XX +XXX,XX @@
818
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
819
#ifndef _LINUX_VHOST_H
820
#define _LINUX_VHOST_H
821
/* Userspace interface for in-kernel virtio accelerators. */
822
--
87
--
823
2.7.4
88
2.34.1
824
89
825
90
diff view generated by jsdifflib
1
Make get_phys_addr_pmsav5() return a fault type in the ARMMMUFaultInfo
1
We support two different encodings for the AArch32 IMPDEF
2
structure, which we convert to the FSC at the callsite.
2
CBAR register -- older cores like the Cortex A9, A7, A15
3
have this at 4, c15, c0, 0; newer cores like the
4
Cortex A35, A53, A57 and A72 have it at 1 c15 c0 0.
3
5
4
Note that PMSAv5 does not define any guest-visible fault status
6
When we implemented this we picked which encoding to
5
register, so the different "fsr" values we were previously
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
6
returning are entirely arbitrary. So we can just switch to using
8
However this isn't right for three cases:
7
the most appropriae fi->type values without worrying that we
9
* the qemu-system-arm 'max' CPU, which is supposed to be
8
need to special-case FaultInfo->FSC conversion for PMSAv5.
10
a variant on a Cortex-A57; it ought to use the same
11
encoding the A57 does and which the AArch64 'max'
12
exposes to AArch32 guest code
13
* the Cortex-R52, which is AArch32-only but has the CBAR
14
at the newer encoding (and where we incorrectly are
15
not yet setting ARM_FEATURE_CBAR_RO anyway)
16
* any possible future support for other v8 AArch32
17
only CPUs, or for supporting "boot the CPU into
18
AArch32 mode" on our existing cores like the A57 etc
19
20
Make the decision of the encoding be based on whether
21
the CPU implements the ARM_FEATURE_V8 flag instead.
22
23
This changes the behaviour only for the qemu-system-arm
24
'-cpu max'. We don't expect anybody to be relying on the
25
old behaviour because:
26
* it's not what the real hardware Cortex-A57 does
27
(and that's what our ID register claims we are)
28
* we don't implement the memory-mapped GICv3 support
29
which is the only thing that exists at the peripheral
30
base address pointed to by the register
9
31
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
13
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
14
Message-id: 1512503192-2239-7-git-send-email-peter.maydell@linaro.org
15
---
35
---
16
target/arm/helper.c | 20 +++++++++++++-------
36
target/arm/helper.c | 2 +-
17
1 file changed, 13 insertions(+), 7 deletions(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
18
38
19
diff --git a/target/arm/helper.c b/target/arm/helper.c
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
20
index XXXXXXX..XXXXXXX 100644
40
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/helper.c
41
--- a/target/arm/helper.c
22
+++ b/target/arm/helper.c
42
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
24
44
* AArch64 cores we might need to add a specific feature flag
25
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
45
* to indicate cores with "flavour 2" CBAR.
26
MMUAccessType access_type, ARMMMUIdx mmu_idx,
46
*/
27
- hwaddr *phys_ptr, int *prot, uint32_t *fsr)
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
28
+ hwaddr *phys_ptr, int *prot,
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
29
+ ARMMMUFaultInfo *fi)
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
30
{
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
31
int n;
51
| extract64(cpu->reset_cbar, 32, 12);
32
uint32_t mask;
33
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
34
}
35
}
36
if (n < 0) {
37
- *fsr = 2;
38
+ fi->type = ARMFault_Background;
39
return true;
40
}
41
42
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
43
mask = (mask >> (n * 4)) & 0xf;
44
switch (mask) {
45
case 0:
46
- *fsr = 1;
47
+ fi->type = ARMFault_Permission;
48
+ fi->level = 1;
49
return true;
50
case 1:
51
if (is_user) {
52
- *fsr = 1;
53
+ fi->type = ARMFault_Permission;
54
+ fi->level = 1;
55
return true;
56
}
57
*prot = PAGE_READ | PAGE_WRITE;
58
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
59
break;
60
case 5:
61
if (is_user) {
62
- *fsr = 1;
63
+ fi->type = ARMFault_Permission;
64
+ fi->level = 1;
65
return true;
66
}
67
*prot = PAGE_READ;
68
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
69
break;
70
default:
71
/* Bad permission. */
72
- *fsr = 1;
73
+ fi->type = ARMFault_Permission;
74
+ fi->level = 1;
75
return true;
76
}
77
*prot |= PAGE_EXEC;
78
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
79
} else {
80
/* Pre-v7 MPU */
81
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
82
- phys_ptr, prot, fsr);
83
+ phys_ptr, prot, fi);
84
+ *fsr = arm_fi_to_sfsc(fi);
85
}
86
qemu_log_mask(CPU_LOG_MMU, "PMSA MPU lookup for %s at 0x%08" PRIx32
87
" mmu_idx %u -> %s (prot %c%c%c)\n",
88
--
52
--
89
2.7.4
53
2.34.1
90
91
diff view generated by jsdifflib
1
When we added the ARMMMUIdx_MSUser MMU index we forgot to
1
The Cortex-R52 implements the Configuration Base Address Register
2
add it to the case statement in regime_is_user(), so we
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
weren't treating it as unprivileged when doing MPU lookups.
3
type, so that our implementation provides the register and the
4
Correct the omission.
4
associated qdev property.
5
5
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 1512153879-5291-4-git-send-email-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
9
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
10
---
9
---
11
target/arm/helper.c | 1 +
10
target/arm/tcg/cpu32.c | 1 +
12
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
13
12
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
15
--- a/target/arm/tcg/cpu32.c
17
+++ b/target/arm/helper.c
16
+++ b/target/arm/tcg/cpu32.c
18
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
19
case ARMMMUIdx_S1SE0:
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
20
case ARMMMUIdx_S1NSE0:
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
21
case ARMMMUIdx_MUser:
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
22
+ case ARMMMUIdx_MSUser:
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
23
return true;
22
cpu->midr = 0x411fd133; /* r1p3 */
24
default:
23
cpu->revidr = 0x00000000;
25
return false;
24
cpu->reset_fpsid = 0x41034023;
26
--
25
--
27
2.7.4
26
2.34.1
28
29
diff view generated by jsdifflib
1
For the TT instruction we're going to need to do an MPU lookup that
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
also tells us which MPU region the access hit. This requires us
2
also by enabling the AUXCR feature which defines the ACTLR
3
to do the MPU lookup without first doing the SAU security access
3
and HACTLR registers. As is our usual practice, we make these
4
check, so pull the MPU lookup parts of get_phys_addr_pmsav8()
4
simple reads-as-zero stubs for now.
5
out into their own function.
6
7
The TT instruction also needs to know the MPU region number which
8
the lookup hit, so provide this information to the caller of the
9
MPU lookup code, even though get_phys_addr_pmsav8() doesn't
10
need to know it.
11
5
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 1512153879-5291-7-git-send-email-peter.maydell@linaro.org
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
15
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
16
---
9
---
17
target/arm/helper.c | 130 +++++++++++++++++++++++++++++++---------------------
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
18
1 file changed, 79 insertions(+), 51 deletions(-)
11
1 file changed, 108 insertions(+)
19
12
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
21
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
15
--- a/target/arm/tcg/cpu32.c
23
+++ b/target/arm/helper.c
16
+++ b/target/arm/tcg/cpu32.c
24
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
25
}
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
26
}
19
}
27
20
28
-static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
29
- MMUAccessType access_type, ARMMMUIdx mmu_idx,
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
30
- hwaddr *phys_ptr, MemTxAttrs *txattrs,
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
31
- int *prot, uint32_t *fsr)
24
+ { .name = "IMP_ATCMREGIONR",
32
+static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
33
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
34
+ hwaddr *phys_ptr, MemTxAttrs *txattrs,
27
+ { .name = "IMP_BTCMREGIONR",
35
+ int *prot, uint32_t *fsr, uint32_t *mregion)
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
30
+ { .name = "IMP_CTCMREGIONR",
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
33
+ { .name = "IMP_CSCTLR",
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
36
+ { .name = "IMP_BPCTLR",
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
39
+ { .name = "IMP_MEMPROTCLR",
40
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
41
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
42
+ { .name = "IMP_SLAVEPCTLR",
43
+ .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
44
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
45
+ { .name = "IMP_PERIPHREGIONR",
46
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
47
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
48
+ { .name = "IMP_FLASHIFREGIONR",
49
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
50
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
51
+ { .name = "IMP_BUILDOPTR",
52
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
53
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
54
+ { .name = "IMP_PINOPTR",
55
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
56
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
57
+ { .name = "IMP_QOSR",
58
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
59
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
60
+ { .name = "IMP_BUSTIMEOUTR",
61
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
62
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
63
+ { .name = "IMP_INTMONR",
64
+ .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
65
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
66
+ { .name = "IMP_ICERR0",
67
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
68
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
69
+ { .name = "IMP_ICERR1",
70
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
71
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
72
+ { .name = "IMP_DCERR0",
73
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
74
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
75
+ { .name = "IMP_DCERR1",
76
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
77
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
78
+ { .name = "IMP_TCMERR0",
79
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
80
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
81
+ { .name = "IMP_TCMERR1",
82
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
83
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
84
+ { .name = "IMP_TCMSYNDR0",
85
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
86
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
87
+ { .name = "IMP_TCMSYNDR1",
88
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
89
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
90
+ { .name = "IMP_FLASHERR0",
91
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
92
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
93
+ { .name = "IMP_FLASHERR1",
94
+ .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
95
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
96
+ { .name = "IMP_CDBGDR0",
97
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
98
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
99
+ { .name = "IMP_CBDGBR1",
100
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
101
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
102
+ { .name = "IMP_TESTR0",
103
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
104
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
105
+ { .name = "IMP_TESTR1",
106
+ .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
107
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
108
+ { .name = "IMP_CDBGDCI",
109
+ .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
110
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
111
+ { .name = "IMP_CDBGDCT",
112
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
113
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
114
+ { .name = "IMP_CDBGICT",
115
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
116
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
117
+ { .name = "IMP_CDBGDCD",
118
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
119
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
120
+ { .name = "IMP_CDBGICD",
121
+ .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
122
+ .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
123
+};
124
+
125
+
126
static void cortex_r52_initfn(Object *obj)
36
{
127
{
37
+ /* Perform a PMSAv8 MPU lookup (without also doing the SAU check
128
ARMCPU *cpu = ARM_CPU(obj);
38
+ * that a full phys-to-virt translation does).
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
39
+ * mregion is (if not NULL) set to the region number which matched,
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
40
+ * or -1 if no region number is returned (MPU off, address did not
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
41
+ * hit a region, address hit in multiple regions).
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
42
+ */
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
43
ARMCPU *cpu = arm_env_get_cpu(env);
134
cpu->midr = 0x411fd133; /* r1p3 */
44
bool is_user = regime_is_user(env, mmu_idx);
135
cpu->revidr = 0x00000000;
45
uint32_t secure = regime_is_secure(env, mmu_idx);
136
cpu->reset_fpsid = 0x41034023;
46
int n;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
47
int matchregion = -1;
138
48
bool hit = false;
139
cpu->pmsav7_dregion = 16;
49
- V8M_SAttributes sattrs = {};
140
cpu->pmsav8r_hdregion = 16;
50
141
+
51
*phys_ptr = address;
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
52
*prot = 0;
53
-
54
- if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
55
- v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
56
- if (access_type == MMU_INST_FETCH) {
57
- /* Instruction fetches always use the MMU bank and the
58
- * transaction attribute determined by the fetch address,
59
- * regardless of CPU state. This is painful for QEMU
60
- * to handle, because it would mean we need to encode
61
- * into the mmu_idx not just the (user, negpri) information
62
- * for the current security state but also that for the
63
- * other security state, which would balloon the number
64
- * of mmu_idx values needed alarmingly.
65
- * Fortunately we can avoid this because it's not actually
66
- * possible to arbitrarily execute code from memory with
67
- * the wrong security attribute: it will always generate
68
- * an exception of some kind or another, apart from the
69
- * special case of an NS CPU executing an SG instruction
70
- * in S&NSC memory. So we always just fail the translation
71
- * here and sort things out in the exception handler
72
- * (including possibly emulating an SG instruction).
73
- */
74
- if (sattrs.ns != !secure) {
75
- *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
76
- return true;
77
- }
78
- } else {
79
- /* For data accesses we always use the MMU bank indicated
80
- * by the current CPU state, but the security attributes
81
- * might downgrade a secure access to nonsecure.
82
- */
83
- if (sattrs.ns) {
84
- txattrs->secure = false;
85
- } else if (!secure) {
86
- /* NS access to S memory must fault.
87
- * Architecturally we should first check whether the
88
- * MPU information for this address indicates that we
89
- * are doing an unaligned access to Device memory, which
90
- * should generate a UsageFault instead. QEMU does not
91
- * currently check for that kind of unaligned access though.
92
- * If we added it we would need to do so as a special case
93
- * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
94
- */
95
- *fsr = M_FAKE_FSR_SFAULT;
96
- return true;
97
- }
98
- }
99
+ if (mregion) {
100
+ *mregion = -1;
101
}
102
103
/* Unlike the ARM ARM pseudocode, we don't need to check whether this
104
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
105
/* We don't need to look the attribute up in the MAIR0/MAIR1
106
* registers because that only tells us about cacheability.
107
*/
108
+ if (mregion) {
109
+ *mregion = matchregion;
110
+ }
111
}
112
113
*fsr = 0x00d; /* Permission fault */
114
return !(*prot & (1 << access_type));
115
}
143
}
116
144
117
+
145
static void cortex_r5f_initfn(Object *obj)
118
+static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
119
+ MMUAccessType access_type, ARMMMUIdx mmu_idx,
120
+ hwaddr *phys_ptr, MemTxAttrs *txattrs,
121
+ int *prot, uint32_t *fsr)
122
+{
123
+ uint32_t secure = regime_is_secure(env, mmu_idx);
124
+ V8M_SAttributes sattrs = {};
125
+
126
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
127
+ v8m_security_lookup(env, address, access_type, mmu_idx, &sattrs);
128
+ if (access_type == MMU_INST_FETCH) {
129
+ /* Instruction fetches always use the MMU bank and the
130
+ * transaction attribute determined by the fetch address,
131
+ * regardless of CPU state. This is painful for QEMU
132
+ * to handle, because it would mean we need to encode
133
+ * into the mmu_idx not just the (user, negpri) information
134
+ * for the current security state but also that for the
135
+ * other security state, which would balloon the number
136
+ * of mmu_idx values needed alarmingly.
137
+ * Fortunately we can avoid this because it's not actually
138
+ * possible to arbitrarily execute code from memory with
139
+ * the wrong security attribute: it will always generate
140
+ * an exception of some kind or another, apart from the
141
+ * special case of an NS CPU executing an SG instruction
142
+ * in S&NSC memory. So we always just fail the translation
143
+ * here and sort things out in the exception handler
144
+ * (including possibly emulating an SG instruction).
145
+ */
146
+ if (sattrs.ns != !secure) {
147
+ *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
148
+ *phys_ptr = address;
149
+ *prot = 0;
150
+ return true;
151
+ }
152
+ } else {
153
+ /* For data accesses we always use the MMU bank indicated
154
+ * by the current CPU state, but the security attributes
155
+ * might downgrade a secure access to nonsecure.
156
+ */
157
+ if (sattrs.ns) {
158
+ txattrs->secure = false;
159
+ } else if (!secure) {
160
+ /* NS access to S memory must fault.
161
+ * Architecturally we should first check whether the
162
+ * MPU information for this address indicates that we
163
+ * are doing an unaligned access to Device memory, which
164
+ * should generate a UsageFault instead. QEMU does not
165
+ * currently check for that kind of unaligned access though.
166
+ * If we added it we would need to do so as a special case
167
+ * for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
168
+ */
169
+ *fsr = M_FAKE_FSR_SFAULT;
170
+ *phys_ptr = address;
171
+ *prot = 0;
172
+ return true;
173
+ }
174
+ }
175
+ }
176
+
177
+ return pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
178
+ txattrs, prot, fsr, NULL);
179
+}
180
+
181
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
182
MMUAccessType access_type, ARMMMUIdx mmu_idx,
183
hwaddr *phys_ptr, int *prot, uint32_t *fsr)
184
--
146
--
185
2.7.4
147
2.34.1
186
187
diff view generated by jsdifflib
1
Make get_phys_addr_pmsav8() return a fault type in the ARMMMUFaultInfo
1
Architecturally, the AArch32 MSR/MRS to/from banked register
2
structure, which we convert to the FSC at the callsite.
2
instructions are UNPREDICTABLE for attempts to access a banked
3
register that the guest could access in a more direct way (e.g.
4
using this insn to access r8_fiq when already in FIQ mode). QEMU has
5
chosen to UNDEF on all of these.
6
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
8
out that real hardware permits this, with the same effect as if the
9
guest had directly written to SPSR. Further, there is some
10
guest code out there that assumes it can do this, because it
11
happens to work on hardware: an example Cortex-R52 startup code
12
fragment uses this, and it got copied into various other places,
13
including Zephyr. Zephyr was fixed to not use this:
14
https://github.com/zephyrproject-rtos/zephyr/issues/47330
15
but other examples are still out there, like the selftest
16
binary for the MPS3-AN536.
17
18
For convenience of being able to run guest code, permit
19
this UNPREDICTABLE access instead of UNDEFing it.
3
20
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-9-git-send-email-peter.maydell@linaro.org
9
---
24
---
10
target/arm/helper.c | 29 ++++++++++++++++++-----------
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
11
1 file changed, 18 insertions(+), 11 deletions(-)
26
target/arm/tcg/translate.c | 19 +++++++++++------
27
2 files changed, 43 insertions(+), 19 deletions(-)
12
28
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
14
index XXXXXXX..XXXXXXX 100644
30
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
31
--- a/target/arm/tcg/op_helper.c
16
+++ b/target/arm/helper.c
32
+++ b/target/arm/tcg/op_helper.c
17
@@ -XXX,XX +XXX,XX @@ static void v8m_security_lookup(CPUARMState *env, uint32_t address,
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
18
static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
34
*/
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
35
int curmode = env->uncached_cpsr & CPSR_M;
20
hwaddr *phys_ptr, MemTxAttrs *txattrs,
36
21
- int *prot, uint32_t *fsr, uint32_t *mregion)
37
- if (regno == 17) {
22
+ int *prot, ARMMMUFaultInfo *fi, uint32_t *mregion)
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
23
{
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
24
/* Perform a PMSAv8 MPU lookup (without also doing the SAU check
40
- goto undef;
25
* that a full phys-to-virt translation does).
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
26
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
42
+ /*
27
/* Multiple regions match -- always a failure (unlike
43
+ * Handle Hyp target regs first because some are special cases
28
* PMSAv7 where highest-numbered-region wins)
44
+ * which don't want the usual "not accessible from tgtmode" check.
29
*/
45
+ */
30
- *fsr = 0x00d; /* permission fault */
46
+ switch (regno) {
31
+ fi->type = ARMFault_Permission;
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
32
+ fi->level = 1;
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
33
return true;
49
+ goto undef;
34
}
50
+ }
35
51
+ break;
36
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
52
+ case 13:
37
53
+ if (curmode != ARM_CPU_MODE_MON) {
38
if (!hit) {
54
+ goto undef;
39
/* background fault */
55
+ }
40
- *fsr = 0;
56
+ break;
41
+ fi->type = ARMFault_Background;
57
+ default:
42
return true;
58
+ g_assert_not_reached();
59
}
60
return;
43
}
61
}
44
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
45
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
46
}
63
}
47
}
64
}
48
65
49
- *fsr = 0x00d; /* Permission fault */
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
50
+ fi->type = ARMFault_Permission;
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
51
+ fi->level = 1;
68
- if (curmode != ARM_CPU_MODE_MON) {
52
return !(*prot & (1 << access_type));
69
- goto undef;
53
}
70
- }
54
71
- }
55
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
72
-
56
static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
73
return;
57
MMUAccessType access_type, ARMMMUIdx mmu_idx,
74
58
hwaddr *phys_ptr, MemTxAttrs *txattrs,
75
undef:
59
- int *prot, uint32_t *fsr)
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
60
+ int *prot, ARMMMUFaultInfo *fi)
77
61
{
78
switch (regno) {
62
uint32_t secure = regime_is_secure(env, mmu_idx);
79
case 16: /* SPSRs */
63
V8M_SAttributes sattrs = {};
80
- env->banked_spsr[bank_number(tgtmode)] = value;
64
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
65
* (including possibly emulating an SG instruction).
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
66
*/
83
+ env->spsr = value;
67
if (sattrs.ns != !secure) {
84
+ } else {
68
- *fsr = sattrs.nsc ? M_FAKE_FSR_NSC_EXEC : M_FAKE_FSR_SFAULT;
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
69
+ if (sattrs.nsc) {
86
+ }
70
+ fi->type = ARMFault_QEMU_NSCExec;
87
break;
71
+ } else {
88
case 17: /* ELR_Hyp */
72
+ fi->type = ARMFault_QEMU_SFault;
89
env->elr_el[2] = value;
73
+ }
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
74
*phys_ptr = address;
91
75
*prot = 0;
92
switch (regno) {
76
return true;
93
case 16: /* SPSRs */
77
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
94
- return env->banked_spsr[bank_number(tgtmode)];
78
* If we added it we would need to do so as a special case
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
79
* for M_FAKE_FSR_SFAULT in arm_v7m_cpu_do_interrupt().
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
80
*/
97
+ return env->spsr;
81
- *fsr = M_FAKE_FSR_SFAULT;
98
+ } else {
82
+ fi->type = ARMFault_QEMU_SFault;
99
+ return env->banked_spsr[bank_number(tgtmode)];
83
*phys_ptr = address;
100
+ }
84
*prot = 0;
101
case 17: /* ELR_Hyp */
85
return true;
102
return env->elr_el[2];
86
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav8(CPUARMState *env, uint32_t address,
103
case 13:
87
}
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
88
105
index XXXXXXX..XXXXXXX 100644
89
return pmsav8_mpu_lookup(env, address, access_type, mmu_idx, phys_ptr,
106
--- a/target/arm/tcg/translate.c
90
- txattrs, prot, fsr, NULL);
107
+++ b/target/arm/tcg/translate.c
91
+ txattrs, prot, fi, NULL);
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
92
}
109
break;
93
110
case ARM_CPU_MODE_HYP:
94
static bool get_phys_addr_pmsav5(CPUARMState *env, uint32_t address,
111
/*
95
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
96
if (arm_feature(env, ARM_FEATURE_V8)) {
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
97
/* PMSAv8 */
114
- * can be accessed also from Hyp mode, so forbid accesses from
98
ret = get_phys_addr_pmsav8(env, address, access_type, mmu_idx,
115
- * EL0 or EL1.
99
- phys_ptr, attrs, prot, fsr);
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
100
+ phys_ptr, attrs, prot, fi);
117
+ * can forbid accesses from EL2 or below.
101
+ *fsr = arm_fi_to_sfsc(fi);
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
102
} else if (arm_feature(env, ARM_FEATURE_V7)) {
119
+ * accesses from EL0 or EL1.
103
/* PMSAv7 */
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
104
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
105
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
122
+ * mode. However there is some real-world code that will do
106
uint32_t tt_resp;
123
+ * it because at least some hardware happens to permit the
107
bool r, rw, nsr, nsrw, mrvalid;
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
108
int prot;
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
109
+ ARMMMUFaultInfo fi = {};
126
+ * this (incorrect) guest code to run.
110
MemTxAttrs attrs = {};
127
*/
111
hwaddr phys_addr;
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
112
- uint32_t fsr;
129
- (s->current_el < 3 && *regno != 17)) {
113
ARMMMUIdx mmu_idx;
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
114
uint32_t mregion;
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
115
bool targetpriv;
132
goto undef;
116
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
133
}
117
if (arm_current_el(env) != 0 || alt) {
134
break;
118
/* We can ignore the return value as prot is always set */
119
pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
120
- &phys_addr, &attrs, &prot, &fsr, &mregion);
121
+ &phys_addr, &attrs, &prot, &fi, &mregion);
122
if (mregion == -1) {
123
mrvalid = false;
124
mregion = 0;
125
--
135
--
126
2.7.4
136
2.34.1
127
128
diff view generated by jsdifflib
1
All the callers of arm_ldq_ptw() and arm_ldl_ptw() ignore the value
1
We currently guard the CFG3 register read with
2
that those functions store in the fsr argument on failure: if they
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
return failure to their callers they will always overwrite the fsr
3
which is clearly wrong as it is never true.
4
value with something else.
5
4
6
Remove the argument from these functions and S1_ptw_translate().
5
This register is present on all board types except AN524
7
This will simplify removing fsr from the calling functions.
6
and AN527; correct the condition.
8
7
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
12
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
13
Message-id: 1512503192-2239-3-git-send-email-peter.maydell@linaro.org
14
---
13
---
15
target/arm/helper.c | 24 +++++++++++-------------
14
hw/misc/mps2-scc.c | 2 +-
16
1 file changed, 11 insertions(+), 13 deletions(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
17
16
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
19
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/helper.c
19
--- a/hw/misc/mps2-scc.c
21
+++ b/target/arm/helper.c
20
+++ b/hw/misc/mps2-scc.c
22
@@ -XXX,XX +XXX,XX @@ static bool get_level1_table_address(CPUARMState *env, ARMMMUIdx mmu_idx,
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
23
/* Translate a S1 pagetable walk through S2 if needed. */
22
r = s->cfg2;
24
static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
23
break;
25
hwaddr addr, MemTxAttrs txattrs,
24
case A_CFG3:
26
- uint32_t *fsr,
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
27
ARMMMUFaultInfo *fi)
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
28
{
27
/* CFG3 reserved on AN524 */
29
if ((mmu_idx == ARMMMUIdx_S1NSE0 || mmu_idx == ARMMMUIdx_S1NSE1) &&
28
goto bad_offset;
30
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
31
hwaddr s2pa;
32
int s2prot;
33
int ret;
34
+ uint32_t fsr;
35
36
ret = get_phys_addr_lpae(env, addr, 0, ARMMMUIdx_S2NS, &s2pa,
37
- &txattrs, &s2prot, &s2size, fsr, fi, NULL);
38
+ &txattrs, &s2prot, &s2size, &fsr, fi, NULL);
39
if (ret) {
40
fi->s2addr = addr;
41
fi->stage2 = true;
42
@@ -XXX,XX +XXX,XX @@ static hwaddr S1_ptw_translate(CPUARMState *env, ARMMMUIdx mmu_idx,
43
* (but not if it was for a debug access).
44
*/
45
static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
46
- ARMMMUIdx mmu_idx, uint32_t *fsr,
47
- ARMMMUFaultInfo *fi)
48
+ ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
49
{
50
ARMCPU *cpu = ARM_CPU(cs);
51
CPUARMState *env = &cpu->env;
52
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
53
54
attrs.secure = is_secure;
55
as = arm_addressspace(cs, attrs);
56
- addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi);
57
+ addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
58
if (fi->s1ptw) {
59
return 0;
60
}
61
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_ldl_ptw(CPUState *cs, hwaddr addr, bool is_secure,
62
}
63
64
static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
65
- ARMMMUIdx mmu_idx, uint32_t *fsr,
66
- ARMMMUFaultInfo *fi)
67
+ ARMMMUIdx mmu_idx, ARMMMUFaultInfo *fi)
68
{
69
ARMCPU *cpu = ARM_CPU(cs);
70
CPUARMState *env = &cpu->env;
71
@@ -XXX,XX +XXX,XX @@ static uint64_t arm_ldq_ptw(CPUState *cs, hwaddr addr, bool is_secure,
72
73
attrs.secure = is_secure;
74
as = arm_addressspace(cs, attrs);
75
- addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fsr, fi);
76
+ addr = S1_ptw_translate(env, mmu_idx, addr, attrs, fi);
77
if (fi->s1ptw) {
78
return 0;
79
}
80
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
81
goto do_fault;
82
}
83
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
84
- mmu_idx, fsr, fi);
85
+ mmu_idx, fi);
86
type = (desc & 3);
87
domain = (desc >> 5) & 0x0f;
88
if (regime_el(env, mmu_idx) == 1) {
89
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v5(CPUARMState *env, uint32_t address,
90
table = (desc & 0xfffff000) | ((address >> 8) & 0xffc);
91
}
92
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
93
- mmu_idx, fsr, fi);
94
+ mmu_idx, fi);
95
switch (desc & 3) {
96
case 0: /* Page translation fault. */
97
code = 7;
98
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
99
goto do_fault;
100
}
101
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
102
- mmu_idx, fsr, fi);
103
+ mmu_idx, fi);
104
type = (desc & 3);
105
if (type == 0 || (type == 3 && !arm_feature(env, ARM_FEATURE_PXN))) {
106
/* Section translation fault, or attempt to use the encoding
107
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
108
/* Lookup l2 entry. */
109
table = (desc & 0xfffffc00) | ((address >> 10) & 0x3fc);
110
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
111
- mmu_idx, fsr, fi);
112
+ mmu_idx, fi);
113
ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
114
switch (desc & 3) {
115
case 0: /* Page translation fault. */
116
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
117
descaddr |= (address >> (stride * (4 - level))) & indexmask;
118
descaddr &= ~7ULL;
119
nstable = extract32(tableattrs, 4, 1);
120
- descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fsr, fi);
121
+ descriptor = arm_ldq_ptw(cs, descaddr, !nstable, mmu_idx, fi);
122
if (fi->s1ptw) {
123
goto do_fault;
124
}
29
}
125
--
30
--
126
2.7.4
31
2.34.1
127
32
128
33
diff view generated by jsdifflib
1
Currently get_phys_addr() and its various subfunctions return
1
The MPS SCC device has a lot of different flavours for the various
2
a hard-coded fault status register value for translation
2
different MPS FPGA images, which look mostly similar but have
3
failures. This is awkward because FSR values these days may
3
differences in how particular registers are handled. Currently we
4
be either long-descriptor format or short-descriptor format.
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
Worse, the right FSR type to use doesn't depend only on the
5
as we add more board types this is getting a bit hard to read.
6
translation table being walked -- some cases, like fault
7
info reported to AArch32 EL2 for some kinds of ATS operation,
8
must be in long-descriptor format even if the translation
9
table being walked was short format. We can't get those cases
10
right with our current approach.
11
6
12
Provide fields in the ARMMMUFaultInfo struct which allow
7
Factor out the conditions into some functions which we can
13
get_phys_addr() to provide sufficient information for a caller to
8
give more descriptive names to.
14
construct an FSR value themselves, and utility functions which do
15
this for both long and short format FSR values, as a first step in
16
switching get_phys_addr() and its children to only returning the
17
failure cause in the ARMMMUFaultInfo struct.
18
9
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
22
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
23
Message-id: 1512503192-2239-2-git-send-email-peter.maydell@linaro.org
24
---
14
---
25
target/arm/internals.h | 185 +++++++++++++++++++++++++++++++++++++++++++++++++
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
26
1 file changed, 185 insertions(+)
16
1 file changed, 31 insertions(+), 14 deletions(-)
27
17
28
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
29
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
30
--- a/target/arm/internals.h
20
--- a/hw/misc/mps2-scc.c
31
+++ b/target/arm/internals.h
21
+++ b/hw/misc/mps2-scc.c
32
@@ -XXX,XX +XXX,XX @@ static inline void arm_clear_exclusive(CPUARMState *env)
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
23
return extract32(s->id, 4, 8);
33
}
24
}
34
25
35
/**
26
+/* Is CFG_REG2 present? */
36
+ * ARMFaultType: type of an ARM MMU fault
27
+static bool have_cfg2(MPS2SCC *s)
37
+ * This corresponds to the v8A pseudocode's Fault enumeration,
38
+ * with extensions for QEMU internal conditions.
39
+ */
40
+typedef enum ARMFaultType {
41
+ ARMFault_None,
42
+ ARMFault_AccessFlag,
43
+ ARMFault_Alignment,
44
+ ARMFault_Background,
45
+ ARMFault_Domain,
46
+ ARMFault_Permission,
47
+ ARMFault_Translation,
48
+ ARMFault_AddressSize,
49
+ ARMFault_SyncExternal,
50
+ ARMFault_SyncExternalOnWalk,
51
+ ARMFault_SyncParity,
52
+ ARMFault_SyncParityOnWalk,
53
+ ARMFault_AsyncParity,
54
+ ARMFault_AsyncExternal,
55
+ ARMFault_Debug,
56
+ ARMFault_TLBConflict,
57
+ ARMFault_Lockdown,
58
+ ARMFault_Exclusive,
59
+ ARMFault_ICacheMaint,
60
+ ARMFault_QEMU_NSCExec, /* v8M: NS executing in S&NSC memory */
61
+ ARMFault_QEMU_SFault, /* v8M: SecureFault INVTRAN, INVEP or AUVIOL */
62
+} ARMFaultType;
63
+
64
+/**
65
* ARMMMUFaultInfo: Information describing an ARM MMU Fault
66
+ * @type: Type of fault
67
+ * @level: Table walk level (for translation, access flag and permission faults)
68
+ * @domain: Domain of the fault address (for non-LPAE CPUs only)
69
* @s2addr: Address that caused a fault at stage 2
70
* @stage2: True if we faulted at stage 2
71
* @s1ptw: True if we faulted at stage 2 while doing a stage 1 page-table walk
72
@@ -XXX,XX +XXX,XX @@ static inline void arm_clear_exclusive(CPUARMState *env)
73
*/
74
typedef struct ARMMMUFaultInfo ARMMMUFaultInfo;
75
struct ARMMMUFaultInfo {
76
+ ARMFaultType type;
77
target_ulong s2addr;
78
+ int level;
79
+ int domain;
80
bool stage2;
81
bool s1ptw;
82
bool ea;
83
};
84
85
+/**
86
+ * arm_fi_to_sfsc: Convert fault info struct to short-format FSC
87
+ * Compare pseudocode EncodeSDFSC(), though unlike that function
88
+ * we set up a whole FSR-format code including domain field and
89
+ * putting the high bit of the FSC into bit 10.
90
+ */
91
+static inline uint32_t arm_fi_to_sfsc(ARMMMUFaultInfo *fi)
92
+{
28
+{
93
+ uint32_t fsc;
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
94
+
95
+ switch (fi->type) {
96
+ case ARMFault_None:
97
+ return 0;
98
+ case ARMFault_AccessFlag:
99
+ fsc = fi->level == 1 ? 0x3 : 0x6;
100
+ break;
101
+ case ARMFault_Alignment:
102
+ fsc = 0x1;
103
+ break;
104
+ case ARMFault_Permission:
105
+ fsc = fi->level == 1 ? 0xd : 0xf;
106
+ break;
107
+ case ARMFault_Domain:
108
+ fsc = fi->level == 1 ? 0x9 : 0xb;
109
+ break;
110
+ case ARMFault_Translation:
111
+ fsc = fi->level == 1 ? 0x5 : 0x7;
112
+ break;
113
+ case ARMFault_SyncExternal:
114
+ fsc = 0x8 | (fi->ea << 12);
115
+ break;
116
+ case ARMFault_SyncExternalOnWalk:
117
+ fsc = fi->level == 1 ? 0xc : 0xe;
118
+ fsc |= (fi->ea << 12);
119
+ break;
120
+ case ARMFault_SyncParity:
121
+ fsc = 0x409;
122
+ break;
123
+ case ARMFault_SyncParityOnWalk:
124
+ fsc = fi->level == 1 ? 0x40c : 0x40e;
125
+ break;
126
+ case ARMFault_AsyncParity:
127
+ fsc = 0x408;
128
+ break;
129
+ case ARMFault_AsyncExternal:
130
+ fsc = 0x406 | (fi->ea << 12);
131
+ break;
132
+ case ARMFault_Debug:
133
+ fsc = 0x2;
134
+ break;
135
+ case ARMFault_TLBConflict:
136
+ fsc = 0x400;
137
+ break;
138
+ case ARMFault_Lockdown:
139
+ fsc = 0x404;
140
+ break;
141
+ case ARMFault_Exclusive:
142
+ fsc = 0x405;
143
+ break;
144
+ case ARMFault_ICacheMaint:
145
+ fsc = 0x4;
146
+ break;
147
+ case ARMFault_Background:
148
+ fsc = 0x0;
149
+ break;
150
+ case ARMFault_QEMU_NSCExec:
151
+ fsc = M_FAKE_FSR_NSC_EXEC;
152
+ break;
153
+ case ARMFault_QEMU_SFault:
154
+ fsc = M_FAKE_FSR_SFAULT;
155
+ break;
156
+ default:
157
+ /* Other faults can't occur in a context that requires a
158
+ * short-format status code.
159
+ */
160
+ g_assert_not_reached();
161
+ }
162
+
163
+ fsc |= (fi->domain << 4);
164
+ return fsc;
165
+}
30
+}
166
+
31
+
167
+/**
32
+/* Is CFG_REG3 present? */
168
+ * arm_fi_to_lfsc: Convert fault info struct to long-format FSC
33
+static bool have_cfg3(MPS2SCC *s)
169
+ * Compare pseudocode EncodeLDFSC(), though unlike that function
170
+ * we fill in also the LPAE bit 9 of a DFSR format.
171
+ */
172
+static inline uint32_t arm_fi_to_lfsc(ARMMMUFaultInfo *fi)
173
+{
34
+{
174
+ uint32_t fsc;
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
175
+
176
+ switch (fi->type) {
177
+ case ARMFault_None:
178
+ return 0;
179
+ case ARMFault_AddressSize:
180
+ fsc = fi->level & 3;
181
+ break;
182
+ case ARMFault_AccessFlag:
183
+ fsc = (fi->level & 3) | (0x2 << 2);
184
+ break;
185
+ case ARMFault_Permission:
186
+ fsc = (fi->level & 3) | (0x3 << 2);
187
+ break;
188
+ case ARMFault_Translation:
189
+ fsc = (fi->level & 3) | (0x1 << 2);
190
+ break;
191
+ case ARMFault_SyncExternal:
192
+ fsc = 0x10 | (fi->ea << 12);
193
+ break;
194
+ case ARMFault_SyncExternalOnWalk:
195
+ fsc = (fi->level & 3) | (0x5 << 2) | (fi->ea << 12);
196
+ break;
197
+ case ARMFault_SyncParity:
198
+ fsc = 0x18;
199
+ break;
200
+ case ARMFault_SyncParityOnWalk:
201
+ fsc = (fi->level & 3) | (0x7 << 2);
202
+ break;
203
+ case ARMFault_AsyncParity:
204
+ fsc = 0x19;
205
+ break;
206
+ case ARMFault_AsyncExternal:
207
+ fsc = 0x11 | (fi->ea << 12);
208
+ break;
209
+ case ARMFault_Alignment:
210
+ fsc = 0x21;
211
+ break;
212
+ case ARMFault_Debug:
213
+ fsc = 0x22;
214
+ break;
215
+ case ARMFault_TLBConflict:
216
+ fsc = 0x30;
217
+ break;
218
+ case ARMFault_Lockdown:
219
+ fsc = 0x34;
220
+ break;
221
+ case ARMFault_Exclusive:
222
+ fsc = 0x35;
223
+ break;
224
+ default:
225
+ /* Other faults can't occur in a context that requires a
226
+ * long-format status code.
227
+ */
228
+ g_assert_not_reached();
229
+ }
230
+
231
+ fsc |= 1 << 9;
232
+ return fsc;
233
+}
36
+}
234
+
37
+
235
/* Do a page table walk and add page to TLB if possible */
38
+/* Is CFG_REG5 present? */
236
bool arm_tlb_fill(CPUState *cpu, vaddr address,
39
+static bool have_cfg5(MPS2SCC *s)
237
MMUAccessType access_type, int mmu_idx,
40
+{
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
42
+}
43
+
44
+/* Is CFG_REG6 present? */
45
+static bool have_cfg6(MPS2SCC *s)
46
+{
47
+ return scc_partno(s) == 0x524;
48
+}
49
+
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
52
*/
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
54
r = s->cfg1;
55
break;
56
case A_CFG2:
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
58
- /* CFG2 reserved on other boards */
59
+ if (!have_cfg2(s)) {
60
goto bad_offset;
61
}
62
r = s->cfg2;
63
break;
64
case A_CFG3:
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
66
- /* CFG3 reserved on AN524 */
67
+ if (!have_cfg3(s)) {
68
goto bad_offset;
69
}
70
/* These are user-settable DIP switches on the board. We don't
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
72
r = s->cfg4;
73
break;
74
case A_CFG5:
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
76
- /* CFG5 reserved on other boards */
77
+ if (!have_cfg5(s)) {
78
goto bad_offset;
79
}
80
r = s->cfg5;
81
break;
82
case A_CFG6:
83
- if (scc_partno(s) != 0x524) {
84
- /* CFG6 reserved on other boards */
85
+ if (!have_cfg6(s)) {
86
goto bad_offset;
87
}
88
r = s->cfg6;
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
90
}
91
break;
92
case A_CFG2:
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
94
- /* CFG2 reserved on other boards */
95
+ if (!have_cfg2(s)) {
96
goto bad_offset;
97
}
98
/* AN524: QSPI Select signal */
99
s->cfg2 = value;
100
break;
101
case A_CFG5:
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
103
- /* CFG5 reserved on other boards */
104
+ if (!have_cfg5(s)) {
105
goto bad_offset;
106
}
107
/* AN524: ACLK frequency in Hz */
108
s->cfg5 = value;
109
break;
110
case A_CFG6:
111
- if (scc_partno(s) != 0x524) {
112
- /* CFG6 reserved on other boards */
113
+ if (!have_cfg6(s)) {
114
goto bad_offset;
115
}
116
/* AN524: Clock divider for BRAM */
238
--
117
--
239
2.7.4
118
2.34.1
240
119
241
120
diff view generated by jsdifflib
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
2
minor differences in the behaviour of the CFG registers depending on
3
Add support for continuous read out of the RDSR and READ_FSR status
3
the image. In many cases we don't really care about the functionality
4
registers until the chip select is deasserted. This feature is supported
4
controlled by these registers and a reads-as-written or similar
5
by amongst others 1 or more flashtypes manufactured by Numonyx (Micron),
5
behaviour is sufficient for the moment.
6
Windbond, SST, Gigadevice, Eon and Macronix.
6
7
7
For the AN536 the required behaviour is:
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
9
Acked-by: Marcin Krzemiński<mar.krzeminski@gmail.com>
9
* A_CFG0 has CPU reset and halt bits
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
- implement as reads-as-written for the moment
11
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
* A_CFG1 has flash or ATCM address 0 remap handling
12
Message-id: 20171126231634.9531-2-frasse.iglesias@gmail.com
12
- QEMU doesn't model this; implement as reads-as-written
13
* A_CFG2 has QSPI select (like AN524)
14
- implemented (no behaviour, as with AN524)
15
* A_CFG3 is MCC_MSB_ADDR "additional MCC addressing bits"
16
- QEMU doesn't care about these, so use the existing
17
RAZ behaviour for convenience
18
* A_CFG4 is board rev (like all other images)
19
- no change needed
20
* A_CFG5 is ACLK frq in hz (like AN524)
21
- implemented as reads-as-written, as for other boards
22
* A_CFG6 is core 0 vector table base address
23
- implemented as reads-as-written for the moment
24
* A_CFG7 is core 1 vector table base address
25
- implemented as reads-as-written for the moment
26
27
Make the changes necessary for this; leave TODO comments where
28
appropriate to indicate where we might want to come back and
29
implement things like CPU reset.
30
31
The other aspects of the device specific to this FPGA image (like the
32
values of the board ID and similar registers) will be set via the
33
device's qdev properties.
34
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
14
---
39
---
15
hw/block/m25p80.c | 39 ++++++++++++++++++++++++++++++++++++++-
40
include/hw/misc/mps2-scc.h | 1 +
16
1 file changed, 38 insertions(+), 1 deletion(-)
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
17
42
2 files changed, 92 insertions(+), 10 deletions(-)
18
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
43
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
19
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/block/m25p80.c
46
--- a/include/hw/misc/mps2-scc.h
21
+++ b/hw/block/m25p80.c
47
+++ b/include/hw/misc/mps2-scc.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct Flash {
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
23
uint8_t data[M25P80_INTERNAL_DATA_BUFFER_SZ];
49
uint32_t cfg4;
24
uint32_t len;
50
uint32_t cfg5;
25
uint32_t pos;
51
uint32_t cfg6;
26
+ bool data_read_loop;
52
+ uint32_t cfg7;
27
uint8_t needed_bytes;
53
uint32_t cfgdata_rtn;
28
uint8_t cmd_in_progress;
54
uint32_t cfgdata_out;
29
uint32_t cur_addr;
55
uint32_t cfgctrl;
30
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
31
}
57
index XXXXXXX..XXXXXXX 100644
32
s->pos = 0;
58
--- a/hw/misc/mps2-scc.c
33
s->len = 1;
59
+++ b/hw/misc/mps2-scc.c
34
+ s->data_read_loop = true;
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
35
s->state = STATE_READING_DATA;
61
REG32(CFG4, 0x10)
36
break;
62
REG32(CFG5, 0x14)
37
63
REG32(CFG6, 0x18)
38
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
64
+REG32(CFG7, 0x1c)
39
}
65
REG32(CFGDATA_RTN, 0xa0)
40
s->pos = 0;
66
REG32(CFGDATA_OUT, 0xa4)
41
s->len = 1;
67
REG32(CFGCTRL, 0xa8)
42
+ s->data_read_loop = true;
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
43
s->state = STATE_READING_DATA;
69
/* Is CFG_REG2 present? */
44
break;
70
static bool have_cfg2(MPS2SCC *s)
45
71
{
46
@@ -XXX,XX +XXX,XX @@ static int m25p80_cs(SSISlave *ss, bool select)
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
47
s->pos = 0;
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
48
s->state = STATE_IDLE;
74
+ scc_partno(s) == 0x536;
49
flash_sync_dirty(s, -1);
75
}
50
+ s->data_read_loop = false;
76
51
}
77
/* Is CFG_REG3 present? */
52
78
static bool have_cfg3(MPS2SCC *s)
53
DB_PRINT_L(0, "%sselect\n", select ? "de" : "");
79
{
54
@@ -XXX,XX +XXX,XX @@ static uint32_t m25p80_transfer8(SSISlave *ss, uint32_t tx)
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
55
s->pos++;
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
56
if (s->pos == s->len) {
82
+ scc_partno(s) != 0x536;
57
s->pos = 0;
83
}
58
- s->state = STATE_IDLE;
84
59
+ if (!s->data_read_loop) {
85
/* Is CFG_REG5 present? */
60
+ s->state = STATE_IDLE;
86
static bool have_cfg5(MPS2SCC *s)
87
{
88
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
89
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
90
+ scc_partno(s) == 0x536;
91
}
92
93
/* Is CFG_REG6 present? */
94
static bool have_cfg6(MPS2SCC *s)
95
{
96
- return scc_partno(s) == 0x524;
97
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x536;
98
+}
99
+
100
+/* Is CFG_REG7 present? */
101
+static bool have_cfg7(MPS2SCC *s)
102
+{
103
+ return scc_partno(s) == 0x536;
104
+}
105
+
106
+/* Does CFG_REG0 drive the 'remap' GPIO output? */
107
+static bool cfg0_is_remap(MPS2SCC *s)
108
+{
109
+ return scc_partno(s) != 0x536;
110
+}
111
+
112
+/* Is CFG_REG1 driving a set of LEDs? */
113
+static bool cfg1_is_leds(MPS2SCC *s)
114
+{
115
+ return scc_partno(s) != 0x536;
116
}
117
118
/* Handle a write via the SYS_CFG channel to the specified function/device.
119
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
120
if (!have_cfg3(s)) {
121
goto bad_offset;
122
}
123
- /* These are user-settable DIP switches on the board. We don't
124
+ /*
125
+ * These are user-settable DIP switches on the board. We don't
126
* model that, so just return zeroes.
127
+ *
128
+ * TODO: for AN536 this is MCC_MSB_ADDR "additional MCC addressing
129
+ * bits". These change which part of the DDR4 the motherboard
130
+ * configuration controller can see in its memory map (see the
131
+ * appnote section 2.4). QEMU doesn't model the MCC at all, so these
132
+ * bits are not interesting to us; read-as-zero is as good as anything
133
+ * else.
134
*/
135
r = 0;
136
break;
137
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
138
}
139
r = s->cfg6;
140
break;
141
+ case A_CFG7:
142
+ if (!have_cfg7(s)) {
143
+ goto bad_offset;
144
+ }
145
+ r = s->cfg7;
146
+ break;
147
case A_CFGDATA_RTN:
148
r = s->cfgdata_rtn;
149
break;
150
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
151
* we always reflect bit 0 in the 'remap' GPIO output line,
152
* and let the board wire it up or not as it chooses.
153
* TODO on some boards bit 1 is CPU_WAIT.
154
+ *
155
+ * TODO: on the AN536 this register controls reset and halt
156
+ * for both CPUs. For the moment we don't implement this, so the
157
+ * register just reads as written.
158
*/
159
s->cfg0 = value;
160
- qemu_set_irq(s->remap, s->cfg0 & 1);
161
+ if (cfg0_is_remap(s)) {
162
+ qemu_set_irq(s->remap, s->cfg0 & 1);
163
+ }
164
break;
165
case A_CFG1:
166
s->cfg1 = value;
167
- for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
168
- led_set_state(s->led[i], extract32(value, i, 1));
169
+ /*
170
+ * On most boards this register drives LEDs.
171
+ *
172
+ * TODO: for AN536 this controls whether flash and ATCM are
173
+ * enabled or disabled on reset. QEMU doesn't model this, and
174
+ * always wires up RAM in the ATCM area and ROM in the flash area.
175
+ */
176
+ if (cfg1_is_leds(s)) {
177
+ for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) {
178
+ led_set_state(s->led[i], extract32(value, i, 1));
61
+ }
179
+ }
62
}
180
}
63
break;
181
break;
64
182
case A_CFG2:
65
@@ -XXX,XX +XXX,XX @@ static Property m25p80_properties[] = {
183
if (!have_cfg2(s)) {
66
DEFINE_PROP_END_OF_LIST(),
184
goto bad_offset;
67
};
185
}
68
186
- /* AN524: QSPI Select signal */
69
+static int m25p80_pre_load(void *opaque)
187
+ /* AN524, AN536: QSPI Select signal */
70
+{
188
s->cfg2 = value;
71
+ Flash *s = (Flash *)opaque;
189
break;
72
+
190
case A_CFG5:
73
+ s->data_read_loop = false;
191
if (!have_cfg5(s)) {
74
+ return 0;
192
goto bad_offset;
75
+}
193
}
76
+
194
- /* AN524: ACLK frequency in Hz */
77
+static bool m25p80_data_read_loop_needed(void *opaque)
195
+ /* AN524, AN536: ACLK frequency in Hz */
78
+{
196
s->cfg5 = value;
79
+ Flash *s = (Flash *)opaque;
197
break;
80
+
198
case A_CFG6:
81
+ return s->data_read_loop;
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
82
+}
200
goto bad_offset;
83
+
201
}
84
+static const VMStateDescription vmstate_m25p80_data_read_loop = {
202
/* AN524: Clock divider for BRAM */
85
+ .name = "m25p80/data_read_loop",
203
+ /* AN536: Core 0 vector table base address */
204
+ s->cfg6 = value;
205
+ break;
206
+ case A_CFG7:
207
+ if (!have_cfg7(s)) {
208
+ goto bad_offset;
209
+ }
210
+ /* AN536: Core 1 vector table base address */
211
s->cfg6 = value;
212
break;
213
case A_CFGDATA_OUT:
214
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_finalize(Object *obj)
215
g_free(s->oscclk_reset);
216
}
217
218
+static bool cfg7_needed(void *opaque)
219
+{
220
+ MPS2SCC *s = opaque;
221
+
222
+ return have_cfg7(s);
223
+}
224
+
225
+static const VMStateDescription vmstate_cfg7 = {
226
+ .name = "mps2-scc/cfg7",
86
+ .version_id = 1,
227
+ .version_id = 1,
87
+ .minimum_version_id = 1,
228
+ .minimum_version_id = 1,
88
+ .needed = m25p80_data_read_loop_needed,
229
+ .needed = cfg7_needed,
89
+ .fields = (VMStateField[]) {
230
+ .fields = (const VMStateField[]) {
90
+ VMSTATE_BOOL(data_read_loop, Flash),
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
91
+ VMSTATE_END_OF_LIST()
232
+ VMSTATE_END_OF_LIST()
92
+ }
233
+ }
93
+};
234
+};
94
+
235
+
95
static const VMStateDescription vmstate_m25p80 = {
236
static const VMStateDescription mps2_scc_vmstate = {
96
.name = "m25p80",
237
.name = "mps2-scc",
97
.version_id = 0,
238
.version_id = 3,
98
.minimum_version_id = 0,
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
99
.pre_save = m25p80_pre_save,
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
100
+ .pre_load = m25p80_pre_load,
241
0, vmstate_info_uint32, uint32_t),
101
.fields = (VMStateField[]) {
102
VMSTATE_UINT8(state, Flash),
103
VMSTATE_UINT8_ARRAY(data, Flash, M25P80_INTERNAL_DATA_BUFFER_SZ),
104
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m25p80 = {
105
VMSTATE_UINT8(spansion_cr3nv, Flash),
106
VMSTATE_UINT8(spansion_cr4nv, Flash),
107
VMSTATE_END_OF_LIST()
242
VMSTATE_END_OF_LIST()
108
+ },
243
+ },
109
+ .subsections = (const VMStateDescription * []) {
244
+ .subsections = (const VMStateDescription * const []) {
110
+ &vmstate_m25p80_data_read_loop,
245
+ &vmstate_cfg7,
111
+ NULL
246
+ NULL
112
}
247
}
113
};
248
};
114
249
115
--
250
--
116
2.7.4
251
2.34.1
117
252
118
253
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Add support for SST READ ID 0x90/0xAB commands for reading out the flash
4
manufacturer ID and device ID.
5
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
8
Message-id: 20171126231634.9531-3-frasse.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/block/m25p80.c | 32 ++++++++++++++++++++++++++++++++
12
1 file changed, 32 insertions(+)
13
14
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/block/m25p80.c
17
+++ b/hw/block/m25p80.c
18
@@ -XXX,XX +XXX,XX @@ typedef enum {
19
DPP = 0xa2,
20
QPP = 0x32,
21
QPP_4 = 0x34,
22
+ RDID_90 = 0x90,
23
+ RDID_AB = 0xab,
24
25
ERASE_4K = 0x20,
26
ERASE4_4K = 0x21,
27
@@ -XXX,XX +XXX,XX @@ typedef enum {
28
MAN_MACRONIX,
29
MAN_NUMONYX,
30
MAN_WINBOND,
31
+ MAN_SST,
32
MAN_GENERIC,
33
} Manufacturer;
34
35
@@ -XXX,XX +XXX,XX @@ static inline Manufacturer get_man(Flash *s)
36
return MAN_SPANSION;
37
case 0xC2:
38
return MAN_MACRONIX;
39
+ case 0xBF:
40
+ return MAN_SST;
41
default:
42
return MAN_GENERIC;
43
}
44
@@ -XXX,XX +XXX,XX @@ static void complete_collecting_data(Flash *s)
45
case WEVCR:
46
s->enh_volatile_cfg = s->data[0];
47
break;
48
+ case RDID_90:
49
+ case RDID_AB:
50
+ if (get_man(s) == MAN_SST) {
51
+ if (s->cur_addr <= 1) {
52
+ if (s->cur_addr) {
53
+ s->data[0] = s->pi->id[2];
54
+ s->data[1] = s->pi->id[0];
55
+ } else {
56
+ s->data[0] = s->pi->id[0];
57
+ s->data[1] = s->pi->id[2];
58
+ }
59
+ s->pos = 0;
60
+ s->len = 2;
61
+ s->data_read_loop = true;
62
+ s->state = STATE_READING_DATA;
63
+ } else {
64
+ qemu_log_mask(LOG_GUEST_ERROR,
65
+ "M25P80: Invalid read id address\n");
66
+ }
67
+ } else {
68
+ qemu_log_mask(LOG_GUEST_ERROR,
69
+ "M25P80: Read id (command 0x90/0xAB) is not supported"
70
+ " by device\n");
71
+ }
72
+ break;
73
default:
74
break;
75
}
76
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
77
case PP4:
78
case PP4_4:
79
case DIE_ERASE:
80
+ case RDID_90:
81
+ case RDID_AB:
82
s->needed_bytes = get_addr_length(s);
83
s->pos = 0;
84
s->len = 0;
85
--
86
2.7.4
87
88
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Add support for the bank address register access commands (BRRD/BRWR) and
4
the BULK_ERASE (0x60) command.
5
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Acked-by: Marcin Krzemiński <mar.krzeminski@gmail.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20171126231634.9531-4-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/block/m25p80.c | 7 +++++++
14
1 file changed, 7 insertions(+)
15
16
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/block/m25p80.c
19
+++ b/hw/block/m25p80.c
20
@@ -XXX,XX +XXX,XX @@ typedef enum {
21
WRDI = 0x4,
22
RDSR = 0x5,
23
WREN = 0x6,
24
+ BRRD = 0x16,
25
+ BRWR = 0x17,
26
JEDEC_READ = 0x9f,
27
+ BULK_ERASE_60 = 0x60,
28
BULK_ERASE = 0xc7,
29
READ_FSR = 0x70,
30
RDCR = 0x15,
31
@@ -XXX,XX +XXX,XX @@ static void complete_collecting_data(Flash *s)
32
s->write_enable = false;
33
}
34
break;
35
+ case BRWR:
36
case EXTEND_ADDR_WRITE:
37
s->ear = s->data[0];
38
break;
39
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
40
s->state = STATE_READING_DATA;
41
break;
42
43
+ case BULK_ERASE_60:
44
case BULK_ERASE:
45
if (s->write_enable) {
46
DB_PRINT_L(0, "chip erase\n");
47
@@ -XXX,XX +XXX,XX @@ static void decode_new_cmd(Flash *s, uint32_t value)
48
case EX_4BYTE_ADDR:
49
s->four_bytes_address_mode = false;
50
break;
51
+ case BRRD:
52
case EXTEND_ADDR_READ:
53
s->data[0] = s->ear;
54
s->pos = 0;
55
s->len = 1;
56
s->state = STATE_READING_DATA;
57
break;
58
+ case BRWR:
59
case EXTEND_ADDR_WRITE:
60
if (s->write_enable) {
61
s->needed_bytes = 1;
62
--
63
2.7.4
64
65
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Move the FlashCMD enum, XilinxQSPIPS and XilinxSPIPSClass structures to the
4
header for consistency (struct XilinxSPIPS is found there). Also move out
5
a define and remove two double included headers (while touching the code).
6
Finally, add 4 byte address commands to the FlashCMD enum.
7
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
12
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
13
Message-id: 20171126231634.9531-6-frasse.iglesias@gmail.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
16
include/hw/ssi/xilinx_spips.h | 34 ++++++++++++++++++++++++++++++++++
17
hw/ssi/xilinx_spips.c | 35 -----------------------------------
18
2 files changed, 34 insertions(+), 35 deletions(-)
19
20
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/ssi/xilinx_spips.h
23
+++ b/include/hw/ssi/xilinx_spips.h
24
@@ -XXX,XX +XXX,XX @@ typedef struct XilinxSPIPS XilinxSPIPS;
25
26
#define XLNX_SPIPS_R_MAX (0x100 / 4)
27
28
+/* Bite off 4k chunks at a time */
29
+#define LQSPI_CACHE_SIZE 1024
30
+
31
+typedef enum {
32
+ READ = 0x3, READ_4 = 0x13,
33
+ FAST_READ = 0xb, FAST_READ_4 = 0x0c,
34
+ DOR = 0x3b, DOR_4 = 0x3c,
35
+ QOR = 0x6b, QOR_4 = 0x6c,
36
+ DIOR = 0xbb, DIOR_4 = 0xbc,
37
+ QIOR = 0xeb, QIOR_4 = 0xec,
38
+
39
+ PP = 0x2, PP_4 = 0x12,
40
+ DPP = 0xa2,
41
+ QPP = 0x32, QPP_4 = 0x34,
42
+} FlashCMD;
43
+
44
struct XilinxSPIPS {
45
SysBusDevice parent_obj;
46
47
@@ -XXX,XX +XXX,XX @@ struct XilinxSPIPS {
48
uint32_t regs[XLNX_SPIPS_R_MAX];
49
};
50
51
+typedef struct {
52
+ XilinxSPIPS parent_obj;
53
+
54
+ uint8_t lqspi_buf[LQSPI_CACHE_SIZE];
55
+ hwaddr lqspi_cached_addr;
56
+ Error *migration_blocker;
57
+ bool mmio_execution_enabled;
58
+} XilinxQSPIPS;
59
+
60
+typedef struct XilinxSPIPSClass {
61
+ SysBusDeviceClass parent_class;
62
+
63
+ const MemoryRegionOps *reg_ops;
64
+
65
+ uint32_t rx_fifo_size;
66
+ uint32_t tx_fifo_size;
67
+} XilinxSPIPSClass;
68
+
69
#define TYPE_XILINX_SPIPS "xlnx.ps7-spi"
70
#define TYPE_XILINX_QSPIPS "xlnx.ps7-qspi"
71
72
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
73
index XXXXXXX..XXXXXXX 100644
74
--- a/hw/ssi/xilinx_spips.c
75
+++ b/hw/ssi/xilinx_spips.c
76
@@ -XXX,XX +XXX,XX @@
77
#include "sysemu/sysemu.h"
78
#include "hw/ptimer.h"
79
#include "qemu/log.h"
80
-#include "qemu/fifo8.h"
81
-#include "hw/ssi/ssi.h"
82
#include "qemu/bitops.h"
83
#include "hw/ssi/xilinx_spips.h"
84
#include "qapi/error.h"
85
@@ -XXX,XX +XXX,XX @@
86
87
/* 16MB per linear region */
88
#define LQSPI_ADDRESS_BITS 24
89
-/* Bite off 4k chunks at a time */
90
-#define LQSPI_CACHE_SIZE 1024
91
92
#define SNOOP_CHECKING 0xFF
93
#define SNOOP_NONE 0xFE
94
#define SNOOP_STRIPING 0
95
96
-typedef enum {
97
- READ = 0x3,
98
- FAST_READ = 0xb,
99
- DOR = 0x3b,
100
- QOR = 0x6b,
101
- DIOR = 0xbb,
102
- QIOR = 0xeb,
103
-
104
- PP = 0x2,
105
- DPP = 0xa2,
106
- QPP = 0x32,
107
-} FlashCMD;
108
-
109
-typedef struct {
110
- XilinxSPIPS parent_obj;
111
-
112
- uint8_t lqspi_buf[LQSPI_CACHE_SIZE];
113
- hwaddr lqspi_cached_addr;
114
- Error *migration_blocker;
115
- bool mmio_execution_enabled;
116
-} XilinxQSPIPS;
117
-
118
-typedef struct XilinxSPIPSClass {
119
- SysBusDeviceClass parent_class;
120
-
121
- const MemoryRegionOps *reg_ops;
122
-
123
- uint32_t rx_fifo_size;
124
- uint32_t tx_fifo_size;
125
-} XilinxSPIPSClass;
126
-
127
static inline int num_effective_busses(XilinxSPIPS *s)
128
{
129
return (s->regs[R_LQSPI_CFG] & LQSPI_CFG_SEP_BUS &&
130
--
131
2.7.4
132
133
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Update striping functionality to be big-endian bit order (as according to
4
the Zynq-7000 Technical Reference Manual). Output thereafter the even bits
5
into the flash memory connected to the lower QSPI bus and the odd bits into
6
the flash memory connected to the upper QSPI bus.
7
8
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
9
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
10
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
11
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
12
Message-id: 20171126231634.9531-7-frasse.iglesias@gmail.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/ssi/xilinx_spips.c | 19 ++++++++++---------
16
1 file changed, 10 insertions(+), 9 deletions(-)
17
18
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/ssi/xilinx_spips.c
21
+++ b/hw/ssi/xilinx_spips.c
22
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_reset(DeviceState *d)
23
xilinx_spips_update_cs_lines(s);
24
}
25
26
-/* N way (num) in place bit striper. Lay out row wise bits (LSB to MSB)
27
+/* N way (num) in place bit striper. Lay out row wise bits (MSB to LSB)
28
* column wise (from element 0 to N-1). num is the length of x, and dir
29
* reverses the direction of the transform. Best illustrated by example:
30
* Each digit in the below array is a single bit (num == 3):
31
*
32
- * {{ 76543210, } ----- stripe (dir == false) -----> {{ FCheb630, }
33
- * { hgfedcba, } { GDAfc741, }
34
- * { HGFEDCBA, }} <---- upstripe (dir == true) ----- { HEBgda52, }}
35
+ * {{ 76543210, } ----- stripe (dir == false) -----> {{ 741gdaFC, }
36
+ * { hgfedcba, } { 630fcHEB, }
37
+ * { HGFEDCBA, }} <---- upstripe (dir == true) ----- { 52hebGDA, }}
38
*/
39
40
static inline void stripe8(uint8_t *x, int num, bool dir)
41
@@ -XXX,XX +XXX,XX @@ static inline void stripe8(uint8_t *x, int num, bool dir)
42
uint8_t r[num];
43
memset(r, 0, sizeof(uint8_t) * num);
44
int idx[2] = {0, 0};
45
- int bit[2] = {0, 0};
46
+ int bit[2] = {0, 7};
47
int d = dir;
48
49
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
50
- for (bit[0] = 0; bit[0] < 8; ++bit[0]) {
51
- r[idx[d]] |= x[idx[!d]] & 1 << bit[!d] ? 1 << bit[d] : 0;
52
+ for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
53
+ r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
54
idx[1] = (idx[1] + 1) % num;
55
if (!idx[1]) {
56
- bit[1]++;
57
+ bit[1]--;
58
}
59
}
60
}
61
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
62
}
63
64
for (i = 0; i < num_effective_busses(s); ++i) {
65
+ int bus = num_effective_busses(s) - 1 - i;
66
DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]);
67
- tx_rx[i] = ssi_transfer(s->spi[i], (uint32_t)tx_rx[i]);
68
+ tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]);
69
DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]);
70
}
71
72
--
73
2.7.4
74
75
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Add support for 4 byte addresses in the LQSPI and correct LQSPI_CFG_SEP_BUS.
4
5
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
6
Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
7
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Message-id: 20171126231634.9531-11-frasse.iglesias@gmail.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/ssi/xilinx_spips.c | 6 +++++-
13
1 file changed, 5 insertions(+), 1 deletion(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@
20
#define R_LQSPI_CFG_RESET 0x03A002EB
21
#define LQSPI_CFG_LQ_MODE (1U << 31)
22
#define LQSPI_CFG_TWO_MEM (1 << 30)
23
-#define LQSPI_CFG_SEP_BUS (1 << 30)
24
+#define LQSPI_CFG_SEP_BUS (1 << 29)
25
#define LQSPI_CFG_U_PAGE (1 << 28)
26
+#define LQSPI_CFG_ADDR4 (1 << 27)
27
#define LQSPI_CFG_MODE_EN (1 << 25)
28
#define LQSPI_CFG_MODE_WIDTH 8
29
#define LQSPI_CFG_MODE_SHIFT 16
30
@@ -XXX,XX +XXX,XX @@ static void lqspi_load_cache(void *opaque, hwaddr addr)
31
fifo8_push(&s->tx_fifo, s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE);
32
/* read address */
33
DB_PRINT_L(0, "pushing read address %06x\n", flash_addr);
34
+ if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_ADDR4) {
35
+ fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 24));
36
+ }
37
fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 16));
38
fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 8));
39
fifo8_push(&s->tx_fifo, (uint8_t)flash_addr);
40
--
41
2.7.4
42
43
diff view generated by jsdifflib
Deleted patch
1
From: Francisco Iglesias <frasse.iglesias@gmail.com>
2
1
3
Don't set TX FIFO UNDERFLOW interrupt after transmitting the commands.
4
Also update interrupts after reading out the interrupt status.
5
6
Signed-off-by: Francisco Iglesias <frasse.iglesias@gmail.com>
7
Acked-by: Alistair Francis <alistair.francis@xilinx.com>
8
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
Tested-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
10
Message-id: 20171126231634.9531-12-frasse.iglesias@gmail.com
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
13
hw/ssi/xilinx_spips.c | 4 +---
14
1 file changed, 1 insertion(+), 3 deletions(-)
15
16
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/ssi/xilinx_spips.c
19
+++ b/hw/ssi/xilinx_spips.c
20
@@ -XXX,XX +XXX,XX @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s)
21
uint8_t addr_length;
22
23
if (fifo8_is_empty(&s->tx_fifo)) {
24
- if (!(s->regs[R_LQSPI_CFG] & LQSPI_CFG_LQ_MODE)) {
25
- s->regs[R_INTR_STATUS] |= IXR_TX_FIFO_UNDERFLOW;
26
- }
27
xilinx_spips_update_ixr(s);
28
return;
29
} else if (s->snoop_state == SNOOP_STRIPING) {
30
@@ -XXX,XX +XXX,XX @@ static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,
31
ret = s->regs[addr] & IXR_ALL;
32
s->regs[addr] = 0;
33
DB_PRINT_L(0, "addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);
34
+ xilinx_spips_update_ixr(s);
35
return ret;
36
case R_INTR_MASK:
37
mask = IXR_ALL;
38
--
39
2.7.4
40
41
diff view generated by jsdifflib
Deleted patch
1
For v8M it is possible for the CONTROL.SPSEL bit value and the
2
current stack to be out of sync. This means we need to update
3
the checks used in reads and writes of the PSP and MSP special
4
registers to use v7m_using_psp() rather than directly checking
5
the SPSEL bit in the control register.
6
1
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 1512153879-5291-2-git-send-email-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
12
target/arm/helper.c | 10 ++++------
13
1 file changed, 4 insertions(+), 6 deletions(-)
14
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
18
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
20
21
switch (reg) {
22
case 8: /* MSP */
23
- return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
24
- env->v7m.other_sp : env->regs[13];
25
+ return v7m_using_psp(env) ? env->v7m.other_sp : env->regs[13];
26
case 9: /* PSP */
27
- return (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) ?
28
- env->regs[13] : env->v7m.other_sp;
29
+ return v7m_using_psp(env) ? env->regs[13] : env->v7m.other_sp;
30
case 16: /* PRIMASK */
31
return env->v7m.primask[env->v7m.secure];
32
case 17: /* BASEPRI */
33
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
34
}
35
break;
36
case 8: /* MSP */
37
- if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
38
+ if (v7m_using_psp(env)) {
39
env->v7m.other_sp = val;
40
} else {
41
env->regs[13] = val;
42
}
43
break;
44
case 9: /* PSP */
45
- if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_SPSEL_MASK) {
46
+ if (v7m_using_psp(env)) {
47
env->regs[13] = val;
48
} else {
49
env->v7m.other_sp = val;
50
--
51
2.7.4
52
53
diff view generated by jsdifflib
Deleted patch
1
For M profile, we currently have an mmu index MNegPri for
2
"requested execution priority negative". This fails to
3
distinguish "requested execution priority negative, privileged"
4
from "requested execution priority negative, usermode", but
5
the two can return different results for MPU lookups. Fix this
6
by splitting MNegPri into MNegPriPriv and MNegPriUser, and
7
similarly for the Secure equivalent MSNegPri.
8
1
9
This takes us from 6 M profile MMU modes to 8, which means
10
we need to bump NB_MMU_MODES; this is OK since the point
11
where we are forced to reduce TLB sizes is 9 MMU modes.
12
13
(It would in theory be possible to stick with 6 MMU indexes:
14
{mpu-disabled,user,privileged} x {secure,nonsecure} since
15
in the MPU-disabled case the result of an MPU lookup is
16
always the same for both user and privileged code. However
17
we would then need to rework the TB flags handling to put
18
user/priv into the TB flags separately from the mmuidx.
19
Adding an extra couple of mmu indexes is simpler.)
20
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 1512153879-5291-5-git-send-email-peter.maydell@linaro.org
24
---
25
target/arm/cpu.h | 54 ++++++++++++++++++++++++++++++--------------------
26
target/arm/internals.h | 6 ++++--
27
target/arm/helper.c | 11 ++++++----
28
target/arm/translate.c | 8 ++++++--
29
4 files changed, 50 insertions(+), 29 deletions(-)
30
31
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
32
index XXXXXXX..XXXXXXX 100644
33
--- a/target/arm/cpu.h
34
+++ b/target/arm/cpu.h
35
@@ -XXX,XX +XXX,XX @@ enum {
36
#define ARM_CPU_VIRQ 2
37
#define ARM_CPU_VFIQ 3
38
39
-#define NB_MMU_MODES 7
40
+#define NB_MMU_MODES 8
41
/* ARM-specific extra insn start words:
42
* 1: Conditional execution bits
43
* 2: Partial exception syndrome for data aborts
44
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
45
* They have the following different MMU indexes:
46
* User
47
* Privileged
48
- * Execution priority negative (this is like privileged, but the
49
- * MPU HFNMIENA bit means that it may have different access permission
50
- * check results to normal privileged code, so can't share a TLB).
51
+ * User, execution priority negative (ie the MPU HFNMIENA bit may apply)
52
+ * Privileged, execution priority negative (ditto)
53
* If the CPU supports the v8M Security Extension then there are also:
54
* Secure User
55
* Secure Privileged
56
- * Secure, execution priority negative
57
+ * Secure User, execution priority negative
58
+ * Secure Privileged, execution priority negative
59
*
60
* The ARMMMUIdx and the mmu index value used by the core QEMU TLB code
61
* are not quite the same -- different CPU types (most notably M profile
62
@@ -XXX,XX +XXX,XX @@ static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
63
* The constant names here are patterned after the general style of the names
64
* of the AT/ATS operations.
65
* The values used are carefully arranged to make mmu_idx => EL lookup easy.
66
+ * For M profile we arrange them to have a bit for priv, a bit for negpri
67
+ * and a bit for secure.
68
*/
69
#define ARM_MMU_IDX_A 0x10 /* A profile */
70
#define ARM_MMU_IDX_NOTLB 0x20 /* does not have a TLB */
71
#define ARM_MMU_IDX_M 0x40 /* M profile */
72
73
+/* meanings of the bits for M profile mmu idx values */
74
+#define ARM_MMU_IDX_M_PRIV 0x1
75
+#define ARM_MMU_IDX_M_NEGPRI 0x2
76
+#define ARM_MMU_IDX_M_S 0x4
77
+
78
#define ARM_MMU_IDX_TYPE_MASK (~0x7)
79
#define ARM_MMU_IDX_COREIDX_MASK 0x7
80
81
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdx {
82
ARMMMUIdx_S2NS = 6 | ARM_MMU_IDX_A,
83
ARMMMUIdx_MUser = 0 | ARM_MMU_IDX_M,
84
ARMMMUIdx_MPriv = 1 | ARM_MMU_IDX_M,
85
- ARMMMUIdx_MNegPri = 2 | ARM_MMU_IDX_M,
86
- ARMMMUIdx_MSUser = 3 | ARM_MMU_IDX_M,
87
- ARMMMUIdx_MSPriv = 4 | ARM_MMU_IDX_M,
88
- ARMMMUIdx_MSNegPri = 5 | ARM_MMU_IDX_M,
89
+ ARMMMUIdx_MUserNegPri = 2 | ARM_MMU_IDX_M,
90
+ ARMMMUIdx_MPrivNegPri = 3 | ARM_MMU_IDX_M,
91
+ ARMMMUIdx_MSUser = 4 | ARM_MMU_IDX_M,
92
+ ARMMMUIdx_MSPriv = 5 | ARM_MMU_IDX_M,
93
+ ARMMMUIdx_MSUserNegPri = 6 | ARM_MMU_IDX_M,
94
+ ARMMMUIdx_MSPrivNegPri = 7 | ARM_MMU_IDX_M,
95
/* Indexes below here don't have TLBs and are used only for AT system
96
* instructions or for the first stage of an S12 page table walk.
97
*/
98
@@ -XXX,XX +XXX,XX @@ typedef enum ARMMMUIdxBit {
99
ARMMMUIdxBit_S2NS = 1 << 6,
100
ARMMMUIdxBit_MUser = 1 << 0,
101
ARMMMUIdxBit_MPriv = 1 << 1,
102
- ARMMMUIdxBit_MNegPri = 1 << 2,
103
- ARMMMUIdxBit_MSUser = 1 << 3,
104
- ARMMMUIdxBit_MSPriv = 1 << 4,
105
- ARMMMUIdxBit_MSNegPri = 1 << 5,
106
+ ARMMMUIdxBit_MUserNegPri = 1 << 2,
107
+ ARMMMUIdxBit_MPrivNegPri = 1 << 3,
108
+ ARMMMUIdxBit_MSUser = 1 << 4,
109
+ ARMMMUIdxBit_MSPriv = 1 << 5,
110
+ ARMMMUIdxBit_MSUserNegPri = 1 << 6,
111
+ ARMMMUIdxBit_MSPrivNegPri = 1 << 7,
112
} ARMMMUIdxBit;
113
114
#define MMU_USER_IDX 0
115
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
116
case ARM_MMU_IDX_A:
117
return mmu_idx & 3;
118
case ARM_MMU_IDX_M:
119
- return (mmu_idx == ARMMMUIdx_MUser || mmu_idx == ARMMMUIdx_MSUser)
120
- ? 0 : 1;
121
+ return mmu_idx & ARM_MMU_IDX_M_PRIV;
122
default:
123
g_assert_not_reached();
124
}
125
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
126
bool secstate)
127
{
128
int el = arm_current_el(env);
129
- ARMMMUIdx mmu_idx;
130
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
131
132
- if (el == 0) {
133
- mmu_idx = secstate ? ARMMMUIdx_MSUser : ARMMMUIdx_MUser;
134
- } else {
135
- mmu_idx = secstate ? ARMMMUIdx_MSPriv : ARMMMUIdx_MPriv;
136
+ if (el != 0) {
137
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
138
}
139
140
if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
141
- mmu_idx = secstate ? ARMMMUIdx_MSNegPri : ARMMMUIdx_MNegPri;
142
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
143
+ }
144
+
145
+ if (secstate) {
146
+ mmu_idx |= ARM_MMU_IDX_M_S;
147
}
148
149
return mmu_idx;
150
diff --git a/target/arm/internals.h b/target/arm/internals.h
151
index XXXXXXX..XXXXXXX 100644
152
--- a/target/arm/internals.h
153
+++ b/target/arm/internals.h
154
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_secure(CPUARMState *env, ARMMMUIdx mmu_idx)
155
case ARMMMUIdx_S1NSE1:
156
case ARMMMUIdx_S1E2:
157
case ARMMMUIdx_S2NS:
158
+ case ARMMMUIdx_MPrivNegPri:
159
+ case ARMMMUIdx_MUserNegPri:
160
case ARMMMUIdx_MPriv:
161
- case ARMMMUIdx_MNegPri:
162
case ARMMMUIdx_MUser:
163
return false;
164
case ARMMMUIdx_S1E3:
165
case ARMMMUIdx_S1SE0:
166
case ARMMMUIdx_S1SE1:
167
+ case ARMMMUIdx_MSPrivNegPri:
168
+ case ARMMMUIdx_MSUserNegPri:
169
case ARMMMUIdx_MSPriv:
170
- case ARMMMUIdx_MSNegPri:
171
case ARMMMUIdx_MSUser:
172
return true;
173
default:
174
diff --git a/target/arm/helper.c b/target/arm/helper.c
175
index XXXXXXX..XXXXXXX 100644
176
--- a/target/arm/helper.c
177
+++ b/target/arm/helper.c
178
@@ -XXX,XX +XXX,XX @@ static inline uint32_t regime_el(CPUARMState *env, ARMMMUIdx mmu_idx)
179
case ARMMMUIdx_S1SE1:
180
case ARMMMUIdx_S1NSE0:
181
case ARMMMUIdx_S1NSE1:
182
+ case ARMMMUIdx_MPrivNegPri:
183
+ case ARMMMUIdx_MUserNegPri:
184
case ARMMMUIdx_MPriv:
185
- case ARMMMUIdx_MNegPri:
186
case ARMMMUIdx_MUser:
187
+ case ARMMMUIdx_MSPrivNegPri:
188
+ case ARMMMUIdx_MSUserNegPri:
189
case ARMMMUIdx_MSPriv:
190
- case ARMMMUIdx_MSNegPri:
191
case ARMMMUIdx_MSUser:
192
return 1;
193
default:
194
@@ -XXX,XX +XXX,XX @@ static inline bool regime_translation_disabled(CPUARMState *env,
195
(R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) {
196
case R_V7M_MPU_CTRL_ENABLE_MASK:
197
/* Enabled, but not for HardFault and NMI */
198
- return mmu_idx == ARMMMUIdx_MNegPri ||
199
- mmu_idx == ARMMMUIdx_MSNegPri;
200
+ return mmu_idx & ARM_MMU_IDX_M_NEGPRI;
201
case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK:
202
/* Enabled for all cases */
203
return false;
204
@@ -XXX,XX +XXX,XX @@ static inline bool regime_is_user(CPUARMState *env, ARMMMUIdx mmu_idx)
205
case ARMMMUIdx_S1NSE0:
206
case ARMMMUIdx_MUser:
207
case ARMMMUIdx_MSUser:
208
+ case ARMMMUIdx_MUserNegPri:
209
+ case ARMMMUIdx_MSUserNegPri:
210
return true;
211
default:
212
return false;
213
diff --git a/target/arm/translate.c b/target/arm/translate.c
214
index XXXXXXX..XXXXXXX 100644
215
--- a/target/arm/translate.c
216
+++ b/target/arm/translate.c
217
@@ -XXX,XX +XXX,XX @@ static inline int get_a32_user_mem_index(DisasContext *s)
218
return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
219
case ARMMMUIdx_MUser:
220
case ARMMMUIdx_MPriv:
221
- case ARMMMUIdx_MNegPri:
222
return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
223
+ case ARMMMUIdx_MUserNegPri:
224
+ case ARMMMUIdx_MPrivNegPri:
225
+ return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
226
case ARMMMUIdx_MSUser:
227
case ARMMMUIdx_MSPriv:
228
- case ARMMMUIdx_MSNegPri:
229
return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
230
+ case ARMMMUIdx_MSUserNegPri:
231
+ case ARMMMUIdx_MSPrivNegPri:
232
+ return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
233
case ARMMMUIdx_S2NS:
234
default:
235
g_assert_not_reached();
236
--
237
2.7.4
238
239
diff view generated by jsdifflib
1
From: Zhaoshenglong <zhaoshenglong@huawei.com>
1
The AN536 is another FPGA image for the MPS3 development board. Unlike
2
2
the existing FPGA images we already model, this board uses a Cortex-R
3
Since I'm not working as an assignee in Linaro, replace the Linaro email
3
family CPU, and it does not use any equivalent to the M-profile
4
address with my personal one.
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
5
It's therefore more convenient for us to model it as a completely
6
Signed-off-by: Zhaoshenglong <zhaoshenglong@huawei.com>
6
separate C file.
7
Message-id: 1513058845-9768-1-git-send-email-zhaoshenglong@huawei.com
7
8
This commit adds the basic skeleton of the board model, and the
9
code to create all the RAM and ROM. We assume that we're probably
10
going to want to add more images in future, so use the same
11
base class/subclass setup that mps2-tz.c uses, even though at
12
the moment there's only a single subclass.
13
14
Following commits will add the CPUs and the peripherals.
15
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Message-id: 20240206132931.38376-9-peter.maydell@linaro.org
9
---
19
---
10
MAINTAINERS | 2 +-
20
MAINTAINERS | 3 +-
11
1 file changed, 1 insertion(+), 1 deletion(-)
21
configs/devices/arm-softmmu/default.mak | 1 +
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
23
hw/arm/Kconfig | 5 +
24
hw/arm/meson.build | 1 +
25
5 files changed, 248 insertions(+), 1 deletion(-)
26
create mode 100644 hw/arm/mps3r.c
12
27
13
diff --git a/MAINTAINERS b/MAINTAINERS
28
diff --git a/MAINTAINERS b/MAINTAINERS
14
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
15
--- a/MAINTAINERS
30
--- a/MAINTAINERS
16
+++ b/MAINTAINERS
31
+++ b/MAINTAINERS
17
@@ -XXX,XX +XXX,XX @@ F: include/hw/*/xlnx*.h
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
18
33
F: hw/pci-host/designware.c
19
ARM ACPI Subsystem
34
F: include/hw/pci-host/designware.h
20
M: Shannon Zhao <zhaoshenglong@huawei.com>
35
21
-M: Shannon Zhao <shannon.zhao@linaro.org>
36
-MPS2
22
+M: Shannon Zhao <shannon.zhaosl@gmail.com>
37
+MPS2 / MPS3
38
M: Peter Maydell <peter.maydell@linaro.org>
23
L: qemu-arm@nongnu.org
39
L: qemu-arm@nongnu.org
24
S: Maintained
40
S: Maintained
25
F: hw/arm/virt-acpi-build.c
41
F: hw/arm/mps2.c
42
F: hw/arm/mps2-tz.c
43
+F: hw/arm/mps3r.c
44
F: hw/misc/mps2-*.c
45
F: include/hw/misc/mps2-*.h
46
F: hw/arm/armsse.c
47
diff --git a/configs/devices/arm-softmmu/default.mak b/configs/devices/arm-softmmu/default.mak
48
index XXXXXXX..XXXXXXX 100644
49
--- a/configs/devices/arm-softmmu/default.mak
50
+++ b/configs/devices/arm-softmmu/default.mak
51
@@ -XXX,XX +XXX,XX @@ CONFIG_ARM_VIRT=y
52
# CONFIG_INTEGRATOR=n
53
# CONFIG_FSL_IMX31=n
54
# CONFIG_MUSICPAL=n
55
+# CONFIG_MPS3R=n
56
# CONFIG_MUSCA=n
57
# CONFIG_CHEETAH=n
58
# CONFIG_SX1=n
59
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
60
new file mode 100644
61
index XXXXXXX..XXXXXXX
62
--- /dev/null
63
+++ b/hw/arm/mps3r.c
64
@@ -XXX,XX +XXX,XX @@
65
+/*
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
68
+ *
69
+ * Copyright (c) 2017 Linaro Limited
70
+ * Written by Peter Maydell
71
+ *
72
+ * This program is free software; you can redistribute it and/or modify
73
+ * it under the terms of the GNU General Public License version 2 or
74
+ * (at your option) any later version.
75
+ */
76
+
77
+/*
78
+ * The MPS3 is an FPGA based dev board. This file handles FPGA images
79
+ * which use the Cortex-R CPUs. We model these separately from the
80
+ * M-profile images, because on M-profile the FPGA image is based on
81
+ * a "Subsystem for Embedded" which is similar to an SoC, whereas
82
+ * the R-profile FPGA images don't have that abstraction layer.
83
+ *
84
+ * We model the following FPGA images here:
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
86
+ *
87
+ * Application Note AN536:
88
+ * https://developer.arm.com/documentation/dai0536/latest/
89
+ */
90
+
91
+#include "qemu/osdep.h"
92
+#include "qemu/units.h"
93
+#include "qapi/error.h"
94
+#include "exec/address-spaces.h"
95
+#include "cpu.h"
96
+#include "hw/boards.h"
97
+#include "hw/arm/boot.h"
98
+
99
+/* Define the layout of RAM and ROM in a board */
100
+typedef struct RAMInfo {
101
+ const char *name;
102
+ hwaddr base;
103
+ hwaddr size;
104
+ int mrindex; /* index into rams[]; -1 for the system RAM block */
105
+ int flags;
106
+} RAMInfo;
107
+
108
+/*
109
+ * The MPS3 DDR is 3GiB, but on a 32-bit host QEMU doesn't permit
110
+ * emulation of that much guest RAM, so artificially make it smaller.
111
+ */
112
+#if HOST_LONG_BITS == 32
113
+#define MPS3_DDR_SIZE (1 * GiB)
114
+#else
115
+#define MPS3_DDR_SIZE (3 * GiB)
116
+#endif
117
+
118
+/*
119
+ * Flag values:
120
+ * IS_MAIN: this is the main machine RAM
121
+ * IS_ROM: this area is read-only
122
+ */
123
+#define IS_MAIN 1
124
+#define IS_ROM 2
125
+
126
+#define MPS3R_RAM_MAX 9
127
+
128
+typedef enum MPS3RFPGAType {
129
+ FPGA_AN536,
130
+} MPS3RFPGAType;
131
+
132
+struct MPS3RMachineClass {
133
+ MachineClass parent;
134
+ MPS3RFPGAType fpga_type;
135
+ const RAMInfo *raminfo;
136
+};
137
+
138
+struct MPS3RMachineState {
139
+ MachineState parent;
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
141
+};
142
+
143
+#define TYPE_MPS3R_MACHINE "mps3r"
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
145
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
147
+
148
+static const RAMInfo an536_raminfo[] = {
149
+ {
150
+ .name = "ATCM",
151
+ .base = 0x00000000,
152
+ .size = 0x00008000,
153
+ .mrindex = 0,
154
+ }, {
155
+ /* We model the QSPI flash as simple ROM for now */
156
+ .name = "QSPI",
157
+ .base = 0x08000000,
158
+ .size = 0x00800000,
159
+ .flags = IS_ROM,
160
+ .mrindex = 1,
161
+ }, {
162
+ .name = "BRAM",
163
+ .base = 0x10000000,
164
+ .size = 0x00080000,
165
+ .mrindex = 2,
166
+ }, {
167
+ .name = "DDR",
168
+ .base = 0x20000000,
169
+ .size = MPS3_DDR_SIZE,
170
+ .mrindex = -1,
171
+ }, {
172
+ .name = "ATCM0",
173
+ .base = 0xee000000,
174
+ .size = 0x00008000,
175
+ .mrindex = 3,
176
+ }, {
177
+ .name = "BTCM0",
178
+ .base = 0xee100000,
179
+ .size = 0x00008000,
180
+ .mrindex = 4,
181
+ }, {
182
+ .name = "CTCM0",
183
+ .base = 0xee200000,
184
+ .size = 0x00008000,
185
+ .mrindex = 5,
186
+ }, {
187
+ .name = "ATCM1",
188
+ .base = 0xee400000,
189
+ .size = 0x00008000,
190
+ .mrindex = 6,
191
+ }, {
192
+ .name = "BTCM1",
193
+ .base = 0xee500000,
194
+ .size = 0x00008000,
195
+ .mrindex = 7,
196
+ }, {
197
+ .name = "CTCM1",
198
+ .base = 0xee600000,
199
+ .size = 0x00008000,
200
+ .mrindex = 8,
201
+ }, {
202
+ .name = NULL,
203
+ }
204
+};
205
+
206
+static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
207
+ const RAMInfo *raminfo)
208
+{
209
+ /* Return an initialized MemoryRegion for the RAMInfo. */
210
+ MemoryRegion *ram;
211
+
212
+ if (raminfo->mrindex < 0) {
213
+ /* Means this RAMInfo is for QEMU's "system memory" */
214
+ MachineState *machine = MACHINE(mms);
215
+ assert(!(raminfo->flags & IS_ROM));
216
+ return machine->ram;
217
+ }
218
+
219
+ assert(raminfo->mrindex < MPS3R_RAM_MAX);
220
+ ram = &mms->ram[raminfo->mrindex];
221
+
222
+ memory_region_init_ram(ram, NULL, raminfo->name,
223
+ raminfo->size, &error_fatal);
224
+ if (raminfo->flags & IS_ROM) {
225
+ memory_region_set_readonly(ram, true);
226
+ }
227
+ return ram;
228
+}
229
+
230
+static void mps3r_common_init(MachineState *machine)
231
+{
232
+ MPS3RMachineState *mms = MPS3R_MACHINE(machine);
233
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
234
+ MemoryRegion *sysmem = get_system_memory();
235
+
236
+ for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
237
+ MemoryRegion *mr = mr_for_raminfo(mms, ri);
238
+ memory_region_add_subregion(sysmem, ri->base, mr);
239
+ }
240
+}
241
+
242
+static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
243
+{
244
+ /*
245
+ * Set mc->default_ram_size and default_ram_id from the
246
+ * information in mmc->raminfo.
247
+ */
248
+ MachineClass *mc = MACHINE_CLASS(mmc);
249
+ const RAMInfo *p;
250
+
251
+ for (p = mmc->raminfo; p->name; p++) {
252
+ if (p->mrindex < 0) {
253
+ /* Found the entry for "system memory" */
254
+ mc->default_ram_size = p->size;
255
+ mc->default_ram_id = p->name;
256
+ return;
257
+ }
258
+ }
259
+ g_assert_not_reached();
260
+}
261
+
262
+static void mps3r_class_init(ObjectClass *oc, void *data)
263
+{
264
+ MachineClass *mc = MACHINE_CLASS(oc);
265
+
266
+ mc->init = mps3r_common_init;
267
+}
268
+
269
+static void mps3r_an536_class_init(ObjectClass *oc, void *data)
270
+{
271
+ MachineClass *mc = MACHINE_CLASS(oc);
272
+ MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc);
273
+ static const char * const valid_cpu_types[] = {
274
+ ARM_CPU_TYPE_NAME("cortex-r52"),
275
+ NULL
276
+ };
277
+
278
+ mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
279
+ mc->default_cpus = 2;
280
+ mc->min_cpus = mc->default_cpus;
281
+ mc->max_cpus = mc->default_cpus;
282
+ mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
283
+ mc->valid_cpu_types = valid_cpu_types;
284
+ mmc->raminfo = an536_raminfo;
285
+ mps3r_set_default_ram_info(mmc);
286
+}
287
+
288
+static const TypeInfo mps3r_machine_types[] = {
289
+ {
290
+ .name = TYPE_MPS3R_MACHINE,
291
+ .parent = TYPE_MACHINE,
292
+ .abstract = true,
293
+ .instance_size = sizeof(MPS3RMachineState),
294
+ .class_size = sizeof(MPS3RMachineClass),
295
+ .class_init = mps3r_class_init,
296
+ }, {
297
+ .name = TYPE_MPS3R_AN536_MACHINE,
298
+ .parent = TYPE_MPS3R_MACHINE,
299
+ .class_init = mps3r_an536_class_init,
300
+ },
301
+};
302
+
303
+DEFINE_TYPES(mps3r_machine_types);
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
305
index XXXXXXX..XXXXXXX 100644
306
--- a/hw/arm/Kconfig
307
+++ b/hw/arm/Kconfig
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
309
select PFLASH_CFI01
310
select SMC91C111
311
312
+config MPS3R
313
+ bool
314
+ default y
315
+ depends on TCG && ARM
316
+
317
config MUSCA
318
bool
319
default y
320
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
321
index XXXXXXX..XXXXXXX 100644
322
--- a/hw/arm/meson.build
323
+++ b/hw/arm/meson.build
324
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c'))
325
arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c'))
326
arm_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mainstone.c'))
327
arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c'))
328
+arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c'))
329
arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c'))
330
arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c'))
331
arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c'))
26
--
332
--
27
2.7.4
333
2.34.1
28
334
29
335
diff view generated by jsdifflib
1
For the v8M security extension, there should be two systick
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
devices, which use separate banked systick exceptions. The
2
the mps3-an536 board.
3
register interface is banked in the same way as for other
4
banked registers, including the existence of an NS alias
5
region for secure code to access the nonsecure timer.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
9
Message-id: 1512154296-5652-3-git-send-email-peter.maydell@linaro.org
10
---
6
---
11
include/hw/intc/armv7m_nvic.h | 4 +-
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
12
hw/intc/armv7m_nvic.c | 90 ++++++++++++++++++++++++++++++++++++-------
8
1 file changed, 177 insertions(+), 3 deletions(-)
13
2 files changed, 80 insertions(+), 14 deletions(-)
14
9
15
diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
16
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/intc/armv7m_nvic.h
12
--- a/hw/arm/mps3r.c
18
+++ b/include/hw/intc/armv7m_nvic.h
13
+++ b/hw/arm/mps3r.c
19
@@ -XXX,XX +XXX,XX @@ typedef struct NVICState {
14
@@ -XXX,XX +XXX,XX @@
20
15
#include "qemu/osdep.h"
21
MemoryRegion sysregmem;
16
#include "qemu/units.h"
22
MemoryRegion sysreg_ns_mem;
17
#include "qapi/error.h"
23
+ MemoryRegion systickmem;
18
+#include "qapi/qmp/qlist.h"
24
+ MemoryRegion systick_ns_mem;
19
#include "exec/address-spaces.h"
25
MemoryRegion container;
20
#include "cpu.h"
26
21
#include "hw/boards.h"
27
uint32_t num_irq;
22
+#include "hw/qdev-properties.h"
28
qemu_irq excpout;
23
#include "hw/arm/boot.h"
29
qemu_irq sysresetreq;
24
+#include "hw/arm/bsa.h"
30
25
+#include "hw/intc/arm_gicv3.h"
31
- SysTickState systick;
26
32
+ SysTickState systick[M_REG_NUM_BANKS];
27
/* Define the layout of RAM and ROM in a board */
33
} NVICState;
28
typedef struct RAMInfo {
34
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
35
#endif
30
#define IS_ROM 2
36
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
31
37
index XXXXXXX..XXXXXXX 100644
32
#define MPS3R_RAM_MAX 9
38
--- a/hw/intc/armv7m_nvic.c
33
+#define MPS3R_CPU_MAX 2
39
+++ b/hw/intc/armv7m_nvic.c
34
+
40
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps nvic_sysreg_ns_ops = {
35
+#define PERIPHBASE 0xf0000000
41
.endianness = DEVICE_NATIVE_ENDIAN,
36
+#define NUM_SPIS 96
37
38
typedef enum MPS3RFPGAType {
39
FPGA_AN536,
40
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineClass {
41
MachineClass parent;
42
MPS3RFPGAType fpga_type;
43
const RAMInfo *raminfo;
44
+ hwaddr loader_start;
42
};
45
};
43
46
44
+static MemTxResult nvic_systick_write(void *opaque, hwaddr addr,
47
struct MPS3RMachineState {
45
+ uint64_t value, unsigned size,
48
MachineState parent;
46
+ MemTxAttrs attrs)
49
+ struct arm_boot_info bootinfo;
50
MemoryRegion ram[MPS3R_RAM_MAX];
51
+ Object *cpu[MPS3R_CPU_MAX];
52
+ MemoryRegion cpu_sysmem[MPS3R_CPU_MAX];
53
+ MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
54
+ MemoryRegion cpu_ram[MPS3R_CPU_MAX];
55
+ GICv3State gic;
56
};
57
58
#define TYPE_MPS3R_MACHINE "mps3r"
59
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
60
return ram;
61
}
62
63
+/*
64
+ * There is no defined secondary boot protocol for Linux for the AN536,
65
+ * because real hardware has a restriction that atomic operations between
66
+ * the two CPUs do not function correctly, and so true SMP is not
67
+ * possible. Therefore for cases where the user is directly booting
68
+ * a kernel, we treat the system as essentially uniprocessor, and
69
+ * put the secondary CPU into power-off state (as if the user on the
70
+ * real hardware had configured the secondary to be halted via the
71
+ * SCC config registers).
72
+ *
73
+ * Note that the default secondary boot code would not work here anyway
74
+ * as it assumes a GICv2, and we have a GICv3.
75
+ */
76
+static void mps3r_write_secondary_boot(ARMCPU *cpu,
77
+ const struct arm_boot_info *info)
47
+{
78
+{
48
+ NVICState *s = opaque;
79
+ /*
49
+ MemoryRegion *mr;
80
+ * Power the secondary CPU off. This means we don't need to write any
50
+
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
51
+ /* Direct the access to the correct systick */
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
52
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
53
+ return memory_region_dispatch_write(mr, addr, value, size, attrs);
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
85
+ */
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
87
+ if (cs != first_cpu) {
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
89
+ &error_abort);
90
+ }
91
+ }
54
+}
92
+}
55
+
93
+
56
+static MemTxResult nvic_systick_read(void *opaque, hwaddr addr,
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
57
+ uint64_t *data, unsigned size,
95
+ const struct arm_boot_info *info)
58
+ MemTxAttrs attrs)
59
+{
96
+{
60
+ NVICState *s = opaque;
97
+ /* We don't need to do anything here because the CPU will be off */
61
+ MemoryRegion *mr;
62
+
63
+ /* Direct the access to the correct systick */
64
+ mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
65
+ return memory_region_dispatch_read(mr, addr, data, size, attrs);
66
+}
98
+}
67
+
99
+
68
+static const MemoryRegionOps nvic_systick_ops = {
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
69
+ .read_with_attrs = nvic_systick_read,
101
+{
70
+ .write_with_attrs = nvic_systick_write,
102
+ MachineState *machine = MACHINE(mms);
71
+ .endianness = DEVICE_NATIVE_ENDIAN,
103
+ DeviceState *gicdev;
72
+};
104
+ QList *redist_region_count;
73
+
105
+
74
static int nvic_post_load(void *opaque, int version_id)
106
+ object_initialize_child(OBJECT(mms), "gic", &mms->gic, TYPE_ARM_GICV3);
107
+ gicdev = DEVICE(&mms->gic);
108
+ qdev_prop_set_uint32(gicdev, "num-cpu", machine->smp.cpus);
109
+ qdev_prop_set_uint32(gicdev, "num-irq", NUM_SPIS + GIC_INTERNAL);
110
+ redist_region_count = qlist_new();
111
+ qlist_append_int(redist_region_count, machine->smp.cpus);
112
+ qdev_prop_set_array(gicdev, "redist-region-count", redist_region_count);
113
+ object_property_set_link(OBJECT(&mms->gic), "sysmem",
114
+ OBJECT(sysmem), &error_fatal);
115
+ sysbus_realize(SYS_BUS_DEVICE(&mms->gic), &error_fatal);
116
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 0, PERIPHBASE);
117
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->gic), 1, PERIPHBASE + 0x100000);
118
+ /*
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
122
+ */
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
127
+ int irq;
128
+ /*
129
+ * Mapping from the output timer irq lines from the CPU to the
130
+ * GIC PPI inputs used for this board. This isn't a BSA board,
131
+ * but it uses the standard convention for the PPI numbers.
132
+ */
133
+ const int timer_irq[] = {
134
+ [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,
135
+ [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,
136
+ [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ,
137
+ };
138
+
139
+ for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
140
+ qdev_connect_gpio_out(cpudev, irq,
141
+ qdev_get_gpio_in(gicdev,
142
+ intidbase + timer_irq[irq]));
143
+ }
144
+
145
+ qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0,
146
+ qdev_get_gpio_in(gicdev,
147
+ intidbase + ARCH_GIC_MAINT_IRQ));
148
+
149
+ qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
150
+ qdev_get_gpio_in(gicdev,
151
+ intidbase + VIRTUAL_PMU_IRQ));
152
+
153
+ sysbus_connect_irq(gicsbd, i,
154
+ qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
155
+ sysbus_connect_irq(gicsbd, i + machine->smp.cpus,
156
+ qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
157
+ sysbus_connect_irq(gicsbd, i + 2 * machine->smp.cpus,
158
+ qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
159
+ sysbus_connect_irq(gicsbd, i + 3 * machine->smp.cpus,
160
+ qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
161
+ }
162
+}
163
+
164
static void mps3r_common_init(MachineState *machine)
75
{
165
{
76
NVICState *s = opaque;
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
77
@@ -XXX,XX +XXX,XX @@ static void nvic_systick_trigger(void *opaque, int n, int level)
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
78
/* SysTick just asked us to pend its exception.
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
79
* (This is different from an external interrupt line's
169
memory_region_add_subregion(sysmem, ri->base, mr);
80
* behaviour.)
81
- * TODO: when we implement the banked systicks we must make
82
- * this pend the correct banked exception.
83
+ * n == 0 : NonSecure systick
84
+ * n == 1 : Secure systick
85
*/
86
- armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, false);
87
+ armv7m_nvic_set_pending(s, ARMV7M_EXCP_SYSTICK, n);
88
}
170
}
171
+
172
+ assert(machine->smp.cpus <= MPS3R_CPU_MAX);
173
+ for (int i = 0; i < machine->smp.cpus; i++) {
174
+ g_autofree char *sysmem_name = g_strdup_printf("cpu-%d-memory", i);
175
+ g_autofree char *ramname = g_strdup_printf("cpu-%d-memory", i);
176
+ g_autofree char *alias_name = g_strdup_printf("sysmem-alias-%d", i);
177
+
178
+ /*
179
+ * Each CPU has some private RAM/peripherals, so create the container
180
+ * which will house those, with the whole-machine system memory being
181
+ * used where there's no CPU-specific device. Note that we need the
182
+ * sysmem_alias aliases because we can't put one MR (the original
183
+ * 'sysmem') into more than one other MR.
184
+ */
185
+ memory_region_init(&mms->cpu_sysmem[i], OBJECT(machine),
186
+ sysmem_name, UINT64_MAX);
187
+ memory_region_init_alias(&mms->sysmem_alias[i], OBJECT(machine),
188
+ alias_name, sysmem, 0, UINT64_MAX);
189
+ memory_region_add_subregion_overlap(&mms->cpu_sysmem[i], 0,
190
+ &mms->sysmem_alias[i], -1);
191
+
192
+ mms->cpu[i] = object_new(machine->cpu_type);
193
+ object_property_set_link(mms->cpu[i], "memory",
194
+ OBJECT(&mms->cpu_sysmem[i]), &error_abort);
195
+ object_property_set_int(mms->cpu[i], "reset-cbar",
196
+ PERIPHBASE, &error_abort);
197
+ qdev_realize(DEVICE(mms->cpu[i]), NULL, &error_fatal);
198
+ object_unref(mms->cpu[i]);
199
+
200
+ /* Per-CPU RAM */
201
+ memory_region_init_ram(&mms->cpu_ram[i], NULL, ramname,
202
+ 0x1000, &error_fatal);
203
+ memory_region_add_subregion(&mms->cpu_sysmem[i], 0xe7c01000,
204
+ &mms->cpu_ram[i]);
205
+ }
206
+
207
+ create_gic(mms, sysmem);
208
+
209
+ mms->bootinfo.ram_size = machine->ram_size;
210
+ mms->bootinfo.board_id = -1;
211
+ mms->bootinfo.loader_start = mmc->loader_start;
212
+ mms->bootinfo.write_secondary_boot = mps3r_write_secondary_boot;
213
+ mms->bootinfo.secondary_cpu_reset_hook = mps3r_secondary_cpu_reset;
214
+ arm_load_kernel(ARM_CPU(mms->cpu[0]), machine, &mms->bootinfo);
89
}
215
}
90
216
91
static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
92
{
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
93
NVICState *s = NVIC(dev);
219
/* Found the entry for "system memory" */
94
- SysBusDevice *systick_sbd;
220
mc->default_ram_size = p->size;
95
Error *err = NULL;
221
mc->default_ram_id = p->name;
96
int regionlen;
222
+ mmc->loader_start = p->base;
97
223
return;
98
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
224
}
99
/* include space for internal exception vectors */
100
s->num_irq += NVIC_FIRST_IRQ;
101
102
- object_property_set_bool(OBJECT(&s->systick), true, "realized", &err);
103
+ object_property_set_bool(OBJECT(&s->systick[M_REG_NS]), true,
104
+ "realized", &err);
105
if (err != NULL) {
106
error_propagate(errp, err);
107
return;
108
}
225
}
109
- systick_sbd = SYS_BUS_DEVICE(&s->systick);
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
110
- sysbus_connect_irq(systick_sbd, 0,
227
};
111
- qdev_get_gpio_in_named(dev, "systick-trigger", 0));
228
112
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_NS]), 0,
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
113
+ qdev_get_gpio_in_named(dev, "systick-trigger",
230
- mc->default_cpus = 2;
114
+ M_REG_NS));
231
- mc->min_cpus = mc->default_cpus;
115
+
232
- mc->max_cpus = mc->default_cpus;
116
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) {
233
+ /*
117
+ /* We couldn't init the secure systick device in instance_init
234
+ * In the real FPGA image there are always two cores, but the standard
118
+ * as we didn't know then if the CPU had the security extensions;
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
119
+ * so we have to do it here.
236
+ * that the second core is held in reset and halted. Many images built for
120
+ */
237
+ * the board do not expect the second core to run at startup (especially
121
+ object_initialize(&s->systick[M_REG_S], sizeof(s->systick[M_REG_S]),
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
122
+ TYPE_SYSTICK);
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
123
+ qdev_set_parent_bus(DEVICE(&s->systick[M_REG_S]), sysbus_get_default());
240
+ *
124
+
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
125
+ object_property_set_bool(OBJECT(&s->systick[M_REG_S]), true,
242
+ * with the default being -smp 1. This seems a more intuitive UI for
126
+ "realized", &err);
243
+ * QEMU users than, for instance, having a machine property to allow
127
+ if (err != NULL) {
244
+ * the user to set the initial value of the SYSCON 0x000 register.
128
+ error_propagate(errp, err);
129
+ return;
130
+ }
131
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->systick[M_REG_S]), 0,
132
+ qdev_get_gpio_in_named(dev, "systick-trigger",
133
+ M_REG_S));
134
+ }
135
136
/* The NVIC and System Control Space (SCS) starts at 0xe000e000
137
* and looks like this:
138
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_realize(DeviceState *dev, Error **errp)
139
memory_region_init_io(&s->sysregmem, OBJECT(s), &nvic_sysreg_ops, s,
140
"nvic_sysregs", 0x1000);
141
memory_region_add_subregion(&s->container, 0, &s->sysregmem);
142
+
143
+ memory_region_init_io(&s->systickmem, OBJECT(s),
144
+ &nvic_systick_ops, s,
145
+ "nvic_systick", 0xe0);
146
+
147
memory_region_add_subregion_overlap(&s->container, 0x10,
148
- sysbus_mmio_get_region(systick_sbd, 0),
149
- 1);
150
+ &s->systickmem, 1);
151
152
if (arm_feature(&s->cpu->env, ARM_FEATURE_V8)) {
153
memory_region_init_io(&s->sysreg_ns_mem, OBJECT(s),
154
&nvic_sysreg_ns_ops, &s->sysregmem,
155
"nvic_sysregs_ns", 0x1000);
156
memory_region_add_subregion(&s->container, 0x20000, &s->sysreg_ns_mem);
157
+ memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
158
+ &nvic_sysreg_ns_ops, &s->systickmem,
159
+ "nvic_systick_ns", 0xe0);
160
+ memory_region_add_subregion_overlap(&s->container, 0x20010,
161
+ &s->systick_ns_mem, 1);
162
}
163
164
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->container);
165
@@ -XXX,XX +XXX,XX @@ static void armv7m_nvic_instance_init(Object *obj)
166
NVICState *nvic = NVIC(obj);
167
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
168
169
- object_initialize(&nvic->systick, sizeof(nvic->systick), TYPE_SYSTICK);
170
- qdev_set_parent_bus(DEVICE(&nvic->systick), sysbus_get_default());
171
+ object_initialize(&nvic->systick[M_REG_NS],
172
+ sizeof(nvic->systick[M_REG_NS]), TYPE_SYSTICK);
173
+ qdev_set_parent_bus(DEVICE(&nvic->systick[M_REG_NS]), sysbus_get_default());
174
+ /* We can't initialize the secure systick here, as we don't know
175
+ * yet if we need it.
176
+ */
245
+ */
177
246
+ mc->default_cpus = 1;
178
sysbus_init_irq(sbd, &nvic->excpout);
247
+ mc->min_cpus = 1;
179
qdev_init_gpio_out_named(dev, &nvic->sysresetreq, "SYSRESETREQ", 1);
248
+ mc->max_cpus = 2;
180
- qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger", 1);
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
181
+ qdev_init_gpio_in_named(dev, nvic_systick_trigger, "systick-trigger",
250
mc->valid_cpu_types = valid_cpu_types;
182
+ M_REG_NUM_BANKS);
251
mmc->raminfo = an536_raminfo;
183
}
184
185
static void armv7m_nvic_class_init(ObjectClass *klass, void *data)
186
--
252
--
187
2.7.4
253
2.34.1
188
189
diff view generated by jsdifflib
1
The TT instruction is going to need to look up the MMU index
1
This board has a lot of UARTs: there is one UART per CPU in the
2
for a specified security and privilege state. Refactor the
2
per-CPU peripheral part of the address map, whose interrupts are
3
existing arm_v7m_mmu_idx_for_secstate() into a version that
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
lets you specify the privilege state and one that uses the
4
normal part of the peripheral space, whose interrupts are shared
5
current state of the CPU.
5
peripheral interrupts.
6
7
Connect and wire them all up; this involves some OR gates where
8
multiple overflow interrupts are wired into one GIC input.
6
9
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 1512153879-5291-6-git-send-email-peter.maydell@linaro.org
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
10
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
11
---
13
---
12
target/arm/cpu.h | 21 ++++++++++++++++-----
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
13
1 file changed, 16 insertions(+), 5 deletions(-)
15
1 file changed, 94 insertions(+)
14
16
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
19
--- a/hw/arm/mps3r.c
18
+++ b/target/arm/cpu.h
20
+++ b/hw/arm/mps3r.c
19
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
21
@@ -XXX,XX +XXX,XX @@
22
#include "qapi/qmp/qlist.h"
23
#include "exec/address-spaces.h"
24
#include "cpu.h"
25
+#include "sysemu/sysemu.h"
26
#include "hw/boards.h"
27
+#include "hw/or-irq.h"
28
#include "hw/qdev-properties.h"
29
#include "hw/arm/boot.h"
30
#include "hw/arm/bsa.h"
31
+#include "hw/char/cmsdk-apb-uart.h"
32
#include "hw/intc/arm_gicv3.h"
33
34
/* Define the layout of RAM and ROM in a board */
35
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
37
#define MPS3R_RAM_MAX 9
38
#define MPS3R_CPU_MAX 2
39
+#define MPS3R_UART_MAX 4 /* shared UART count */
40
41
#define PERIPHBASE 0xf0000000
42
#define NUM_SPIS 96
43
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
44
MemoryRegion sysmem_alias[MPS3R_CPU_MAX];
45
MemoryRegion cpu_ram[MPS3R_CPU_MAX];
46
GICv3State gic;
47
+ /* per-CPU UARTs followed by the shared UARTs */
48
+ CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
49
+ OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
50
+ OrIRQState uart_oflow;
51
};
52
53
#define TYPE_MPS3R_MACHINE "mps3r"
54
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
55
56
OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
57
58
+/*
59
+ * Main clock frequency CLK in Hz (50MHz). In the image there are also
60
+ * ACLK, MCLK, GPUCLK and PERIPHCLK at the same frequency; for our
61
+ * model we just roll them all into one.
62
+ */
63
+#define CLK_FRQ 50000000
64
+
65
static const RAMInfo an536_raminfo[] = {
66
{
67
.name = "ATCM",
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
20
}
69
}
21
}
70
}
22
71
23
-/* Return the MMU index for a v7M CPU in the specified security state */
72
+/*
24
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
25
- bool secstate)
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
26
+/* Return the MMU index for a v7M CPU in the specified security and
27
+ * privilege state
28
+ */
75
+ */
29
+static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
30
+ bool secstate,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
31
+ bool priv)
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
32
{
79
+ qemu_irq combirq)
33
- int el = arm_current_el(env);
34
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
35
36
- if (el != 0) {
37
+ if (priv) {
38
mmu_idx |= ARM_MMU_IDX_M_PRIV;
39
}
40
41
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
42
return mmu_idx;
43
}
44
45
+/* Return the MMU index for a v7M CPU in the specified security state */
46
+static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
47
+ bool secstate)
48
+{
80
+{
49
+ bool priv = arm_current_el(env) != 0;
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
82
+ SysBusDevice *sbd;
50
+
83
+
51
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
86
+ TYPE_CMSDK_APB_UART);
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
88
+ qdev_prop_set_chr(DEVICE(&mms->uart[uartno]), "chardev", serial_hd(uartno));
89
+ sbd = SYS_BUS_DEVICE(&mms->uart[uartno]);
90
+ sysbus_realize(sbd, &error_fatal);
91
+ memory_region_add_subregion(mem, baseaddr,
92
+ sysbus_mmio_get_region(sbd, 0));
93
+ sysbus_connect_irq(sbd, 0, txirq);
94
+ sysbus_connect_irq(sbd, 1, rxirq);
95
+ sysbus_connect_irq(sbd, 2, txoverirq);
96
+ sysbus_connect_irq(sbd, 3, rxoverirq);
97
+ sysbus_connect_irq(sbd, 4, combirq);
52
+}
98
+}
53
+
99
+
54
/* Determine the current mmu_idx to use for normal loads/stores */
100
static void mps3r_common_init(MachineState *machine)
55
static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
56
{
101
{
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
104
MemoryRegion *sysmem = get_system_memory();
105
+ DeviceState *gicdev;
106
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
110
}
111
112
create_gic(mms, sysmem);
113
+ gicdev = DEVICE(&mms->gic);
114
+
115
+ /*
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
118
+ */
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
122
+ DeviceState *orgate;
123
+
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
126
+ TYPE_OR_IRQ);
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
129
+ qdev_realize(orgate, NULL, &error_fatal);
130
+ qdev_connect_gpio_out(orgate, 0,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
132
+
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
135
+ qdev_get_gpio_in(gicdev, intidbase + 16), /* rx */
136
+ qdev_get_gpio_in(orgate, 0), /* txover */
137
+ qdev_get_gpio_in(orgate, 1), /* rxover */
138
+ qdev_get_gpio_in(gicdev, intidbase + 18) /* combined */);
139
+ }
140
+ /*
141
+ * UARTs 2 to 5 are whole-system; all overflow IRQs are ORed
142
+ * together into IRQ 17
143
+ */
144
+ object_initialize_child(OBJECT(mms), "uart-oflow-orgate",
145
+ &mms->uart_oflow, TYPE_OR_IRQ);
146
+ qdev_prop_set_uint32(DEVICE(&mms->uart_oflow), "num-lines",
147
+ MPS3R_UART_MAX * 2);
148
+ qdev_realize(DEVICE(&mms->uart_oflow), NULL, &error_fatal);
149
+ qdev_connect_gpio_out(DEVICE(&mms->uart_oflow), 0,
150
+ qdev_get_gpio_in(gicdev, 17));
151
+
152
+ for (int i = 0; i < MPS3R_UART_MAX; i++) {
153
+ hwaddr baseaddr = 0xe0205000 + i * 0x1000;
154
+ int rxirq = 5 + i * 2, txirq = 6 + i * 2, combirq = 13 + i;
155
+
156
+ create_uart(mms, i + MPS3R_CPU_MAX, sysmem, baseaddr,
157
+ qdev_get_gpio_in(gicdev, txirq),
158
+ qdev_get_gpio_in(gicdev, rxirq),
159
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2),
160
+ qdev_get_gpio_in(DEVICE(&mms->uart_oflow), i * 2 + 1),
161
+ qdev_get_gpio_in(gicdev, combirq));
162
+ }
163
164
mms->bootinfo.ram_size = machine->ram_size;
165
mms->bootinfo.board_id = -1;
57
--
166
--
58
2.7.4
167
2.34.1
59
168
60
169
diff view generated by jsdifflib
1
Implement the TT instruction which queries the security
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
state and access permissions of a memory location.
2
board. These are all simple devices that just need to be created and
3
wired up.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 1512153879-5291-8-git-send-email-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper.h | 2 +
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
9
target/arm/helper.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 59 insertions(+)
10
target/arm/translate.c | 29 ++++++++++++-
11
3 files changed, 138 insertions(+), 1 deletion(-)
12
11
13
diff --git a/target/arm/helper.h b/target/arm/helper.h
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.h
14
--- a/hw/arm/mps3r.c
16
+++ b/target/arm/helper.h
15
+++ b/hw/arm/mps3r.c
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_mrs, i32, env, i32)
16
@@ -XXX,XX +XXX,XX @@
18
DEF_HELPER_2(v7m_bxns, void, env, i32)
17
#include "sysemu/sysemu.h"
19
DEF_HELPER_2(v7m_blxns, void, env, i32)
18
#include "hw/boards.h"
20
19
#include "hw/or-irq.h"
21
+DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
20
+#include "hw/qdev-clock.h"
21
#include "hw/qdev-properties.h"
22
#include "hw/arm/boot.h"
23
#include "hw/arm/bsa.h"
24
#include "hw/char/cmsdk-apb-uart.h"
25
+#include "hw/i2c/arm_sbcon_i2c.h"
26
#include "hw/intc/arm_gicv3.h"
27
+#include "hw/misc/unimp.h"
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
30
31
/* Define the layout of RAM and ROM in a board */
32
typedef struct RAMInfo {
33
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
34
CMSDKAPBUART uart[MPS3R_CPU_MAX + MPS3R_UART_MAX];
35
OrIRQState cpu_uart_oflow[MPS3R_CPU_MAX];
36
OrIRQState uart_oflow;
37
+ CMSDKAPBWatchdog watchdog;
38
+ CMSDKAPBDualTimer dualtimer;
39
+ ArmSbconI2CState i2c[5];
40
+ Clock *clk;
41
};
42
43
#define TYPE_MPS3R_MACHINE "mps3r"
44
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
45
MemoryRegion *sysmem = get_system_memory();
46
DeviceState *gicdev;
47
48
+ mms->clk = clock_new(OBJECT(machine), "CLK");
49
+ clock_set_hz(mms->clk, CLK_FRQ);
22
+
50
+
23
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
24
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
25
DEF_HELPER_2(get_cp_reg, i32, env, ptr)
53
memory_region_add_subregion(sysmem, ri->base, mr);
26
diff --git a/target/arm/helper.c b/target/arm/helper.c
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
27
index XXXXXXX..XXXXXXX 100644
55
qdev_get_gpio_in(gicdev, combirq));
28
--- a/target/arm/helper.c
29
+++ b/target/arm/helper.c
30
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
31
g_assert_not_reached();
32
}
33
34
+uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
35
+{
36
+ /* The TT instructions can be used by unprivileged code, but in
37
+ * user-only emulation we don't have the MPU.
38
+ * Luckily since we know we are NonSecure unprivileged (and that in
39
+ * turn means that the A flag wasn't specified), all the bits in the
40
+ * register must be zero:
41
+ * IREGION: 0 because IRVALID is 0
42
+ * IRVALID: 0 because NS
43
+ * S: 0 because NS
44
+ * NSRW: 0 because NS
45
+ * NSR: 0 because NS
46
+ * RW: 0 because unpriv and A flag not set
47
+ * R: 0 because unpriv and A flag not set
48
+ * SRVALID: 0 because NS
49
+ * MRVALID: 0 because unpriv and A flag not set
50
+ * SREGION: 0 becaus SRVALID is 0
51
+ * MREGION: 0 because MRVALID is 0
52
+ */
53
+ return 0;
54
+}
55
+
56
void switch_mode(CPUARMState *env, int mode)
57
{
58
ARMCPU *cpu = arm_env_get_cpu(env);
59
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
60
}
56
}
61
}
57
62
58
+ for (int i = 0; i < 4; i++) {
63
+uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
59
+ /* CMSDK GPIO controllers */
64
+{
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
65
+ /* Implement the TT instruction. op is bits [7:6] of the insn. */
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
66
+ bool forceunpriv = op & 1;
67
+ bool alt = op & 2;
68
+ V8M_SAttributes sattrs = {};
69
+ uint32_t tt_resp;
70
+ bool r, rw, nsr, nsrw, mrvalid;
71
+ int prot;
72
+ MemTxAttrs attrs = {};
73
+ hwaddr phys_addr;
74
+ uint32_t fsr;
75
+ ARMMMUIdx mmu_idx;
76
+ uint32_t mregion;
77
+ bool targetpriv;
78
+ bool targetsec = env->v7m.secure;
79
+
80
+ /* Work out what the security state and privilege level we're
81
+ * interested in is...
82
+ */
83
+ if (alt) {
84
+ targetsec = !targetsec;
85
+ }
62
+ }
86
+
63
+
87
+ if (forceunpriv) {
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
88
+ targetpriv = false;
65
+ TYPE_CMSDK_APB_WATCHDOG);
89
+ } else {
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
90
+ targetpriv = arm_v7m_is_handler_mode(env) ||
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
91
+ !(env->v7m.control[targetsec] & R_V7M_CONTROL_NPRIV_MASK);
68
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->watchdog), 0,
69
+ qdev_get_gpio_in(gicdev, 0));
70
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->watchdog), 0, 0xe0100000);
71
+
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
73
+ TYPE_CMSDK_APB_DUALTIMER);
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
77
+ qdev_get_gpio_in(gicdev, 3));
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 1,
79
+ qdev_get_gpio_in(gicdev, 1));
80
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 2,
81
+ qdev_get_gpio_in(gicdev, 2));
82
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->dualtimer), 0, 0xe0101000);
83
+
84
+ for (int i = 0; i < ARRAY_SIZE(mms->i2c); i++) {
85
+ static const hwaddr i2cbase[] = {0xe0102000, /* Touch */
86
+ 0xe0103000, /* Audio */
87
+ 0xe0107000, /* Shield0 */
88
+ 0xe0108000, /* Shield1 */
89
+ 0xe0109000}; /* DDR4 EEPROM */
90
+ g_autofree char *s = g_strdup_printf("i2c%d", i);
91
+
92
+ object_initialize_child(OBJECT(mms), s, &mms->i2c[i],
93
+ TYPE_ARM_SBCON_I2C);
94
+ sysbus_realize(SYS_BUS_DEVICE(&mms->i2c[i]), &error_fatal);
95
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->i2c[i]), 0, i2cbase[i]);
96
+ if (i != 2 && i != 3) {
97
+ /*
98
+ * internal-only bus: mark it full to avoid user-created
99
+ * i2c devices being plugged into it.
100
+ */
101
+ qbus_mark_full(qdev_get_child_bus(DEVICE(&mms->i2c[i]), "i2c"));
102
+ }
92
+ }
103
+ }
93
+
104
+
94
+ /* ...and then figure out which MMU index this is */
105
mms->bootinfo.ram_size = machine->ram_size;
95
+ mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targetsec, targetpriv);
106
mms->bootinfo.board_id = -1;
96
+
107
mms->bootinfo.loader_start = mmc->loader_start;
97
+ /* We know that the MPU and SAU don't care about the access type
98
+ * for our purposes beyond that we don't want to claim to be
99
+ * an insn fetch, so we arbitrarily call this a read.
100
+ */
101
+
102
+ /* MPU region info only available for privileged or if
103
+ * inspecting the other MPU state.
104
+ */
105
+ if (arm_current_el(env) != 0 || alt) {
106
+ /* We can ignore the return value as prot is always set */
107
+ pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
108
+ &phys_addr, &attrs, &prot, &fsr, &mregion);
109
+ if (mregion == -1) {
110
+ mrvalid = false;
111
+ mregion = 0;
112
+ } else {
113
+ mrvalid = true;
114
+ }
115
+ r = prot & PAGE_READ;
116
+ rw = prot & PAGE_WRITE;
117
+ } else {
118
+ r = false;
119
+ rw = false;
120
+ mrvalid = false;
121
+ mregion = 0;
122
+ }
123
+
124
+ if (env->v7m.secure) {
125
+ v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
126
+ nsr = sattrs.ns && r;
127
+ nsrw = sattrs.ns && rw;
128
+ } else {
129
+ sattrs.ns = true;
130
+ nsr = false;
131
+ nsrw = false;
132
+ }
133
+
134
+ tt_resp = (sattrs.iregion << 24) |
135
+ (sattrs.irvalid << 23) |
136
+ ((!sattrs.ns) << 22) |
137
+ (nsrw << 21) |
138
+ (nsr << 20) |
139
+ (rw << 19) |
140
+ (r << 18) |
141
+ (sattrs.srvalid << 17) |
142
+ (mrvalid << 16) |
143
+ (sattrs.sregion << 8) |
144
+ mregion;
145
+
146
+ return tt_resp;
147
+}
148
+
149
#endif
150
151
void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)
152
diff --git a/target/arm/translate.c b/target/arm/translate.c
153
index XXXXXXX..XXXXXXX 100644
154
--- a/target/arm/translate.c
155
+++ b/target/arm/translate.c
156
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
157
if (insn & (1 << 22)) {
158
/* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
159
* - load/store doubleword, load/store exclusive, ldacq/strel,
160
- * table branch.
161
+ * table branch, TT.
162
*/
163
if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
164
arm_dc_feature(s, ARM_FEATURE_V8)) {
165
@@ -XXX,XX +XXX,XX @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
166
} else if ((insn & (1 << 23)) == 0) {
167
/* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
168
* - load/store exclusive word
169
+ * - TT (v8M only)
170
*/
171
if (rs == 15) {
172
+ if (!(insn & (1 << 20)) &&
173
+ arm_dc_feature(s, ARM_FEATURE_M) &&
174
+ arm_dc_feature(s, ARM_FEATURE_V8)) {
175
+ /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
176
+ * - TT (v8M only)
177
+ */
178
+ bool alt = insn & (1 << 7);
179
+ TCGv_i32 addr, op, ttresp;
180
+
181
+ if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
182
+ /* we UNDEF for these UNPREDICTABLE cases */
183
+ goto illegal_op;
184
+ }
185
+
186
+ if (alt && !s->v8m_secure) {
187
+ goto illegal_op;
188
+ }
189
+
190
+ addr = load_reg(s, rn);
191
+ op = tcg_const_i32(extract32(insn, 6, 2));
192
+ ttresp = tcg_temp_new_i32();
193
+ gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
194
+ tcg_temp_free_i32(addr);
195
+ tcg_temp_free_i32(op);
196
+ store_reg(s, rd, ttresp);
197
+ }
198
goto illegal_op;
199
}
200
addr = tcg_temp_local_new_i32();
201
--
108
--
202
2.7.4
109
2.34.1
203
110
204
111
diff view generated by jsdifflib
1
Make get_phys_addr_pmsav7() return a fault type in the ARMMMUFaultInfo
1
Add the remaining devices (or unimplemented-device stubs) for
2
structure, which we convert to the FSC at the callsite.
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
QSPI write-config block, and ethernet.
3
4
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-8-git-send-email-peter.maydell@linaro.org
9
---
8
---
10
target/arm/helper.c | 11 +++++++----
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 7 insertions(+), 4 deletions(-)
10
1 file changed, 74 insertions(+)
12
11
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
14
--- a/hw/arm/mps3r.c
16
+++ b/target/arm/helper.c
15
+++ b/hw/arm/mps3r.c
17
@@ -XXX,XX +XXX,XX @@ static inline bool m_is_system_region(CPUARMState *env, uint32_t address)
16
@@ -XXX,XX +XXX,XX @@
18
17
#include "hw/char/cmsdk-apb-uart.h"
19
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
18
#include "hw/i2c/arm_sbcon_i2c.h"
20
MMUAccessType access_type, ARMMMUIdx mmu_idx,
19
#include "hw/intc/arm_gicv3.h"
21
- hwaddr *phys_ptr, int *prot, uint32_t *fsr)
20
+#include "hw/misc/mps2-scc.h"
22
+ hwaddr *phys_ptr, int *prot,
21
+#include "hw/misc/mps2-fpgaio.h"
23
+ ARMMMUFaultInfo *fi)
22
#include "hw/misc/unimp.h"
23
+#include "hw/net/lan9118.h"
24
+#include "hw/rtc/pl031.h"
25
+#include "hw/ssi/pl022.h"
26
#include "hw/timer/cmsdk-apb-dualtimer.h"
27
#include "hw/watchdog/cmsdk-apb-watchdog.h"
28
29
@@ -XXX,XX +XXX,XX @@ struct MPS3RMachineState {
30
CMSDKAPBWatchdog watchdog;
31
CMSDKAPBDualTimer dualtimer;
32
ArmSbconI2CState i2c[5];
33
+ PL022State spi[3];
34
+ MPS2SCC scc;
35
+ MPS2FPGAIO fpgaio;
36
+ UnimplementedDeviceState i2s_audio;
37
+ PL031State rtc;
38
Clock *clk;
39
};
40
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
42
}
43
};
44
45
+static const int an536_oscclk[] = {
46
+ 24000000, /* 24MHz reference for RTC and timers */
47
+ 50000000, /* 50MHz ACLK */
48
+ 50000000, /* 50MHz MCLK */
49
+ 50000000, /* 50MHz GPUCLK */
50
+ 24576000, /* 24.576MHz AUDCLK */
51
+ 23750000, /* 23.75MHz HDLCDCLK */
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
53
+};
54
+
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
56
const RAMInfo *raminfo)
24
{
57
{
25
ARMCPU *cpu = arm_env_get_cpu(env);
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
26
int n;
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
27
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
60
MemoryRegion *sysmem = get_system_memory();
28
if (n == -1) { /* no hits */
61
DeviceState *gicdev;
29
if (!pmsav7_use_background_region(cpu, mmu_idx, is_user)) {
62
+ QList *oscclk;
30
/* background fault */
63
31
- *fsr = 0;
64
mms->clk = clock_new(OBJECT(machine), "CLK");
32
+ fi->type = ARMFault_Background;
65
clock_set_hz(mms->clk, CLK_FRQ);
33
return true;
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
34
}
35
get_phys_addr_pmsav7_default(env, mmu_idx, address, prot);
36
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
37
}
67
}
38
}
68
}
39
69
40
- *fsr = 0x00d; /* Permission fault */
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
41
+ fi->type = ARMFault_Permission;
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
42
+ fi->level = 1;
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
43
return !(*prot & (1 << access_type));
73
+
44
}
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
45
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
46
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
47
} else if (arm_feature(env, ARM_FEATURE_V7)) {
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
48
/* PMSAv7 */
78
+ qdev_get_gpio_in(gicdev, 22 + i));
49
ret = get_phys_addr_pmsav7(env, address, access_type, mmu_idx,
79
+ }
50
- phys_ptr, prot, fsr);
80
+
51
+ phys_ptr, prot, fi);
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
52
+ *fsr = arm_fi_to_sfsc(fi);
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
53
} else {
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
54
/* Pre-v7 MPU */
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
55
ret = get_phys_addr_pmsav5(env, address, access_type, mmu_idx,
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
86
+ oscclk = qlist_new();
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
89
+ }
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
93
+
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
95
+
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
97
+ TYPE_MPS2_FPGAIO);
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
99
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "num-leds", 10);
100
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-switches", true);
101
+ qdev_prop_set_bit(DEVICE(&mms->fpgaio), "has-dbgctrl", false);
102
+ sysbus_realize(SYS_BUS_DEVICE(&mms->fpgaio), &error_fatal);
103
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->fpgaio), 0, 0xe0202000);
104
+
105
+ create_unimplemented_device("clcd", 0xe0209000, 0x1000);
106
+
107
+ object_initialize_child(OBJECT(mms), "rtc", &mms->rtc, TYPE_PL031);
108
+ sysbus_realize(SYS_BUS_DEVICE(&mms->rtc), &error_fatal);
109
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->rtc), 0, 0xe020a000);
110
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->rtc), 0,
111
+ qdev_get_gpio_in(gicdev, 4));
112
+
113
+ /*
114
+ * In hardware this is a LAN9220; the LAN9118 is software compatible
115
+ * except that it doesn't support the checksum-offload feature.
116
+ */
117
+ lan9118_init(0xe0300000,
118
+ qdev_get_gpio_in(gicdev, 18));
119
+
120
+ create_unimplemented_device("usb", 0xe0301000, 0x1000);
121
+ create_unimplemented_device("qspi-write-config", 0xe0600000, 0x1000);
122
+
123
mms->bootinfo.ram_size = machine->ram_size;
124
mms->bootinfo.board_id = -1;
125
mms->bootinfo.loader_start = mmc->loader_start;
56
--
126
--
57
2.7.4
127
2.34.1
58
128
59
129
diff view generated by jsdifflib
1
Make get_phys_addr_v6() return a fault type in the ARMMMUFaultInfo
1
Add documentation for the mps3-an536 board type.
2
structure, which we convert to the FSC at the callsite.
3
2
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
7
Tested-by: Stefano Stabellini <sstabellini@kernel.org>
8
Message-id: 1512503192-2239-5-git-send-email-peter.maydell@linaro.org
9
---
6
---
10
target/arm/helper.c | 40 ++++++++++++++++++++++------------------
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
11
1 file changed, 22 insertions(+), 18 deletions(-)
8
1 file changed, 34 insertions(+), 3 deletions(-)
12
9
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
14
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
12
--- a/docs/system/arm/mps2.rst
16
+++ b/target/arm/helper.c
13
+++ b/docs/system/arm/mps2.rst
17
@@ -XXX,XX +XXX,XX @@ do_fault:
14
@@ -XXX,XX +XXX,XX @@
18
static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
19
MMUAccessType access_type, ARMMMUIdx mmu_idx,
16
-=========================================================================================================================================================
20
hwaddr *phys_ptr, MemTxAttrs *attrs, int *prot,
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
21
- target_ulong *page_size, uint32_t *fsr,
18
+=========================================================================================================================================================================
22
- ARMMMUFaultInfo *fi)
19
23
+ target_ulong *page_size, ARMMMUFaultInfo *fi)
20
-These board models all use Arm M-profile CPUs.
24
{
21
+These board models use Arm M-profile or R-profile CPUs.
25
CPUState *cs = CPU(arm_env_get_cpu(env));
22
26
- int code;
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
27
+ int level = 1;
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
28
uint32_t table;
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
29
uint32_t desc;
26
30
uint32_t xn;
27
QEMU models the following FPGA images:
31
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
28
32
/* Lookup l1 descriptor. */
29
+FPGA images using M-profile CPUs:
33
if (!get_level1_table_address(env, mmu_idx, &table, address)) {
34
/* Section translation fault if page walk is disabled by PD0 or PD1 */
35
- code = 5;
36
+ fi->type = ARMFault_Translation;
37
goto do_fault;
38
}
39
desc = arm_ldl_ptw(cs, table, regime_is_secure(env, mmu_idx),
40
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
41
/* Section translation fault, or attempt to use the encoding
42
* which is Reserved on implementations without PXN.
43
*/
44
- code = 5;
45
+ fi->type = ARMFault_Translation;
46
goto do_fault;
47
}
48
if ((type == 1) || !(desc & (1 << 18))) {
49
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
50
} else {
51
dacr = env->cp15.dacr_s;
52
}
53
+ if (type == 1) {
54
+ level = 2;
55
+ }
56
domain_prot = (dacr >> (domain * 2)) & 3;
57
if (domain_prot == 0 || domain_prot == 2) {
58
- if (type != 1) {
59
- code = 9; /* Section domain fault. */
60
- } else {
61
- code = 11; /* Page domain fault. */
62
- }
63
+ /* Section or Page domain fault */
64
+ fi->type = ARMFault_Domain;
65
goto do_fault;
66
}
67
if (type != 1) {
68
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
69
ap = ((desc >> 10) & 3) | ((desc >> 13) & 4);
70
xn = desc & (1 << 4);
71
pxn = desc & 1;
72
- code = 13;
73
ns = extract32(desc, 19, 1);
74
} else {
75
if (arm_feature(env, ARM_FEATURE_PXN)) {
76
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
77
ap = ((desc >> 4) & 3) | ((desc >> 7) & 4);
78
switch (desc & 3) {
79
case 0: /* Page translation fault. */
80
- code = 7;
81
+ fi->type = ARMFault_Translation;
82
goto do_fault;
83
case 1: /* 64k page. */
84
phys_addr = (desc & 0xffff0000) | (address & 0xffff);
85
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
86
/* Never happens, but compiler isn't smart enough to tell. */
87
abort();
88
}
89
- code = 15;
90
}
91
if (domain_prot == 3) {
92
*prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
93
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
94
if (pxn && !regime_is_user(env, mmu_idx)) {
95
xn = 1;
96
}
97
- if (xn && access_type == MMU_INST_FETCH)
98
+ if (xn && access_type == MMU_INST_FETCH) {
99
+ fi->type = ARMFault_Permission;
100
goto do_fault;
101
+ }
102
103
if (arm_feature(env, ARM_FEATURE_V6K) &&
104
(regime_sctlr(env, mmu_idx) & SCTLR_AFE)) {
105
/* The simplified model uses AP[0] as an access control bit. */
106
if ((ap & 1) == 0) {
107
/* Access flag fault. */
108
- code = (code == 15) ? 6 : 3;
109
+ fi->type = ARMFault_AccessFlag;
110
goto do_fault;
111
}
112
*prot = simple_ap_to_rw_prot(env, mmu_idx, ap >> 1);
113
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
114
}
115
if (!(*prot & (1 << access_type))) {
116
/* Access permission fault. */
117
+ fi->type = ARMFault_Permission;
118
goto do_fault;
119
}
120
}
121
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_v6(CPUARMState *env, uint32_t address,
122
*phys_ptr = phys_addr;
123
return false;
124
do_fault:
125
- *fsr = code | (domain << 4);
126
+ fi->domain = domain;
127
+ fi->level = level;
128
return true;
129
}
130
131
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr(CPUARMState *env, target_ulong address,
132
return get_phys_addr_lpae(env, address, access_type, mmu_idx, phys_ptr,
133
attrs, prot, page_size, fsr, fi, cacheattrs);
134
} else if (regime_sctlr(env, mmu_idx) & SCTLR_XP) {
135
- return get_phys_addr_v6(env, address, access_type, mmu_idx, phys_ptr,
136
- attrs, prot, page_size, fsr, fi);
137
+ bool ret = get_phys_addr_v6(env, address, access_type, mmu_idx,
138
+ phys_ptr, attrs, prot, page_size, fi);
139
+
30
+
140
+ *fsr = arm_fi_to_sfsc(fi);
31
``mps2-an385``
141
+ return ret;
32
Cortex-M3 as documented in Arm Application Note AN385
142
} else {
33
``mps2-an386``
143
bool ret = get_phys_addr_v5(env, address, access_type, mmu_idx,
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
144
phys_ptr, prot, page_size, fi);
35
``mps3-an547``
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
37
38
+FPGA images using R-profile CPUs:
39
+
40
+``mps3-an536``
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
42
+
43
Differences between QEMU and real hardware:
44
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
47
flash, but only as simple ROM, so attempting to rewrite the flash
48
from the guest will fail
49
- QEMU does not model the USB controller in MPS3 boards
50
+- AN536 does not support runtime control of CPU reset and halt via
51
+ the SCC CFG_REG0 register.
52
+- AN536 does not support enabling or disabling the flash and ATCM
53
+ interfaces via the SCC CFG_REG1 register.
54
+- AN536 does not support setting of the initial vector table
55
+ base address via the SCC CFG_REG6 and CFG_REG7 register config,
56
+ and does not provide a mechanism for specifying these values at
57
+ startup, so all guest images must be built to start from TCM
58
+ (i.e. to expect the interrupt vector base at 0 from reset).
59
+- AN536 defaults to only creating a single CPU; this is the equivalent
60
+ of the way the real FPGA image usually runs with the second Cortex-R52
61
+ held in halt via the initial SCC CFG_REG0 register setting. You can
62
+ create the second CPU with ``-smp 2``; both CPUs will then start
63
+ execution immediately on startup.
64
+
65
+Note that for the AN536 the first UART is accessible only by
66
+CPU0, and the second UART is accessible only by CPU1. The
67
+first UART accessible shared between both CPUs is the third
68
+UART. Guest software might therefore be built to use either
69
+the first UART or the third UART; if you don't see any output
70
+from the UART you are looking at, try one of the others.
71
+(Even if the AN536 machine is started with a single CPU and so
72
+no "CPU1-only UART", the UART numbering remains the same,
73
+with the third UART being the first of the shared ones.)
74
75
Machine-specific options
76
""""""""""""""""""""""""
145
--
77
--
146
2.7.4
78
2.34.1
147
79
148
80
diff view generated by jsdifflib