1
Last pullreq before 6.0 softfreeze: a few minor feature patches,
1
The following changes since commit 5767815218efd3cbfd409505ed824d5f356044ae:
2
some bugfixes, some cleanups.
3
2
4
-- PMM
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)
5
6
The following changes since commit 6f34661b6c97a37a5efc27d31c037ddeda4547e2:
7
8
Merge remote-tracking branch 'remotes/vivier2/tags/trivial-branch-for-6.0-pull-request' into staging (2021-03-11 18:55:27 +0000)
9
4
10
are available in the Git repository at:
5
are available in the Git repository at:
11
6
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20210312-1
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240215
13
8
14
for you to fetch changes up to 41f09f2e9f09e4dd386d84174a6dcb5136af17ca:
9
for you to fetch changes up to f780e63fe731b058fe52d43653600d8729a1b5f2:
15
10
16
hw/display/pxa2xx: Inline template header (2021-03-12 13:26:08 +0000)
11
docs: Add documentation for the mps3-an536 board (2024-02-15 14:32:39 +0000)
17
12
18
----------------------------------------------------------------
13
----------------------------------------------------------------
19
target-arm queue:
14
target-arm queue:
20
* versal: Support XRAMs and XRAM controller
15
* hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
21
* smmu: Various minor bug fixes
16
* linux-user/aarch64: Choose SYNC as the preferred MTE mode
22
* SVE emulation: fix bugs handling odd vector lengths
17
* Fix some errors in SVE/SME handling of MTE tags
23
* allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value
18
* hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
24
* tests/acceptance: fix orangepi-pc acceptance tests
19
* hw/block/tc58128: Don't emit deprecation warning under qtest
25
* hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
20
* tests/qtest: Fix handling of npcm7xx and GMAC tests
26
* hw/arm/virt: KVM: The IPA lower bound is 32
21
* hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
27
* npcm7xx: support MFT module
22
* tests/qtest/npcm7xx_emc-test: Connect all NICs to a backend
28
* pl110, pxa2xx_lcd: tidy up template headers
23
* Don't assert on vmload/vmsave of M-profile CPUs
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)
29
30
30
----------------------------------------------------------------
31
----------------------------------------------------------------
31
Andrew Jones (2):
32
Luc Michel (1):
32
accel: kvm: Fix kvm_type invocation
33
hw/arm/smmuv3: add support for stage 1 access fault
33
hw/arm/virt: KVM: The IPA lower bound is 32
34
34
35
Edgar E. Iglesias (2):
35
Nabih Estefan (1):
36
hw/misc: versal: Add a model of the XRAM controller
36
tests/qtest: Fix GMAC test to run on a machine in upstream QEMU
37
hw/arm: versal: Add support for the XRAMs
38
37
39
Eric Auger (7):
38
Peter Maydell (22):
40
intel_iommu: Fix mask may be uninitialized in vtd_context_device_invalidate
39
hw/pci-host/raven.c: Mark raven_io_ops as implementing unaligned accesses
41
dma: Introduce dma_aligned_pow2_mask()
40
hw/block/tc58128: Don't emit deprecation warning under qtest
42
virtio-iommu: Handle non power of 2 range invalidations
41
tests/qtest/meson.build: Don't include qtests_npcm7xx in qtests_aarch64
43
hw/arm/smmu-common: Fix smmu_iotlb_inv_iova when asid is not set
42
tests/qtest/bios-tables-test: Allow changes to virt GTDT
44
hw/arm/smmuv3: Enforce invalidation on a power of two range
43
hw/arm/virt: Wire up non-secure EL2 virtual timer IRQ
45
hw/arm/smmuv3: Fix SMMU_CMD_CFGI_STE_RANGE handling
44
tests/qtest/bios-tables-tests: Update virt golden reference
46
hw/arm/smmuv3: Uniformize sid traces
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
47
61
48
Hao Wu (5):
62
Philippe Mathieu-Daudé (5):
49
hw/misc: Add GPIOs for duty in NPCM7xx PWM
63
hw/arm/xilinx_zynq: Wire FIQ between CPU <> GIC
50
hw/misc: Add NPCM7XX MFT Module
64
hw/arm/stellaris: Convert ADC controller to Resettable interface
51
hw/arm: Add MFT device to NPCM7xx Soc
65
hw/arm/stellaris: Convert I2C controller to Resettable interface
52
hw/arm: Connect PWM fans in NPCM7XX boards
66
hw/arm/stellaris: Add missing QOM 'machine' parent
53
tests/qtest: Test PWM fan RPM using MFT in PWM test
67
hw/arm/stellaris: Add missing QOM 'SoC' parent
54
68
55
Niek Linnenbank (5):
69
Richard Henderson (6):
56
hw/net/allwinner-sun8i-emac: traverse transmit queue using TX_CUR_DESC register value
70
linux-user/aarch64: Choose SYNC as the preferred MTE mode
57
tests/acceptance/boot_linux_console: remove Armbian 19.11.3 bionic test for orangepi-pc machine
71
target/arm: Fix nregs computation in do_{ld,st}_zpa
58
tests/acceptance/boot_linux_console: change URL for test_arm_orangepi_bionic_20_08
72
target/arm: Adjust and validate mtedesc sizem1
59
tests/acceptance: update sunxi kernel from armbian to 5.10.16
73
target/arm: Split out make_svemte_desc
60
tests/acceptance: drop ARMBIAN_ARTIFACTS_CACHED condition for orangepi-pc, cubieboard tests
74
target/arm: Handle mte in do_ldrq, do_ldro
75
target/arm: Fix SVE/SME gross MTE suppression checks
61
76
62
Peter Maydell (9):
77
MAINTAINERS | 3 +-
63
hw/display/pl110: Remove dead code for non-32-bpp surfaces
78
docs/system/arm/mps2.rst | 37 +-
64
hw/display/pl110: Pull included-once parts of template header into pl110.c
79
configs/devices/arm-softmmu/default.mak | 1 +
65
hw/display/pl110: Remove use of BITS from pl110_template.h
80
hw/arm/smmuv3-internal.h | 1 +
66
hw/display/pxa2xx_lcd: Remove dead code for non-32-bpp surfaces
81
include/hw/arm/smmu-common.h | 1 +
67
hw/display/pxa2xx_lcd: Remove dest_width state field
82
include/hw/arm/virt.h | 2 +
68
hw/display/pxa2xx: Remove use of BITS in pxa2xx_template.h
83
include/hw/misc/mps2-scc.h | 1 +
69
hw/display/pxa2xx: Apply brace-related coding style fixes to template header
84
linux-user/aarch64/target_prctl.h | 29 +-
70
hw/display/pxa2xx: Apply whitespace-only coding style fixes to template header
85
target/arm/internals.h | 2 +-
71
hw/display/pxa2xx: Inline template header
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
72
115
73
Philippe Mathieu-Daudé (1):
74
hw/timer/sse-timer: Propagate eventual error in sse_timer_realize()
75
76
Richard Henderson (8):
77
target/arm: Fix sve_uzp_p vs odd vector lengths
78
target/arm: Fix sve_zip_p vs odd vector lengths
79
target/arm: Fix sve_punpk_p vs odd vector lengths
80
target/arm: Update find_last_active for PREDDESC
81
target/arm: Update BRKA, BRKB, BRKN for PREDDESC
82
target/arm: Update CNTP for PREDDESC
83
target/arm: Update WHILE for PREDDESC
84
target/arm: Update sve reduction vs simd_desc
85
86
docs/system/arm/nuvoton.rst | 2 +-
87
docs/system/arm/xlnx-versal-virt.rst | 1 +
88
hw/arm/smmu-internal.h | 5 +
89
hw/display/pl110_template.h | 120 +-------
90
hw/display/pxa2xx_template.h | 447 ---------------------------
91
include/hw/arm/npcm7xx.h | 13 +-
92
include/hw/arm/xlnx-versal.h | 13 +
93
include/hw/boards.h | 1 +
94
include/hw/misc/npcm7xx_mft.h | 70 +++++
95
include/hw/misc/npcm7xx_pwm.h | 4 +-
96
include/hw/misc/xlnx-versal-xramc.h | 97 ++++++
97
include/sysemu/dma.h | 12 +
98
target/arm/kvm_arm.h | 6 +-
99
accel/kvm/kvm-all.c | 2 +
100
hw/arm/npcm7xx.c | 45 ++-
101
hw/arm/npcm7xx_boards.c | 99 ++++++
102
hw/arm/smmu-common.c | 32 +-
103
hw/arm/smmuv3.c | 58 ++--
104
hw/arm/virt.c | 23 +-
105
hw/arm/xlnx-versal.c | 36 +++
106
hw/display/pl110.c | 123 +++++---
107
hw/display/pxa2xx_lcd.c | 520 ++++++++++++++++++++++++++-----
108
hw/i386/intel_iommu.c | 32 +-
109
hw/misc/npcm7xx_mft.c | 540 +++++++++++++++++++++++++++++++++
110
hw/misc/npcm7xx_pwm.c | 4 +
111
hw/misc/xlnx-versal-xramc.c | 253 +++++++++++++++
112
hw/net/allwinner-sun8i-emac.c | 62 ++--
113
hw/timer/sse-timer.c | 1 +
114
hw/virtio/virtio-iommu.c | 19 +-
115
softmmu/dma-helpers.c | 26 ++
116
target/arm/kvm.c | 4 +-
117
target/arm/sve_helper.c | 107 ++++---
118
target/arm/translate-sve.c | 26 +-
119
tests/qtest/npcm7xx_pwm-test.c | 205 ++++++++++++-
120
hw/arm/trace-events | 24 +-
121
hw/misc/meson.build | 2 +
122
hw/misc/trace-events | 8 +
123
tests/acceptance/boot_linux_console.py | 120 +++-----
124
tests/acceptance/replay_kernel.py | 10 +-
125
39 files changed, 2235 insertions(+), 937 deletions(-)
126
delete mode 100644 hw/display/pxa2xx_template.h
127
create mode 100644 include/hw/misc/npcm7xx_mft.h
128
create mode 100644 include/hw/misc/xlnx-versal-xramc.h
129
create mode 100644 hw/misc/npcm7xx_mft.c
130
create mode 100644 hw/misc/xlnx-versal-xramc.c
131
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
Similarly to commits dadbb58f59..5ae79fe825 for other ARM boards,
4
using these field macros for predicates.
4
connect FIQ output of the GIC CPU interfaces to the CPU.
5
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Message-id: 20210309155305.11301-8-richard.henderson@linaro.org
7
Message-id: 20240130152548.17855-1-philmd@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
target/arm/sve_helper.c | 4 ++--
11
hw/arm/xilinx_zynq.c | 2 ++
12
target/arm/translate-sve.c | 7 ++++---
12
1 file changed, 2 insertions(+)
13
2 files changed, 6 insertions(+), 5 deletions(-)
14
13
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
14
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
16
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sve_helper.c
16
--- a/hw/arm/xilinx_zynq.c
18
+++ b/target/arm/sve_helper.c
17
+++ b/hw/arm/xilinx_zynq.c
19
@@ -XXX,XX +XXX,XX @@ uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
18
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
20
19
sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE);
21
uint32_t HELPER(sve_while)(void *vd, uint32_t count, uint32_t pred_desc)
20
sysbus_connect_irq(busdev, 0,
22
{
21
qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
23
- uintptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
22
+ sysbus_connect_irq(busdev, 1,
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
23
+ qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ));
25
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
24
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
25
for (n = 0; n < 64; n++) {
27
uint64_t esz_mask = pred_esz_masks[esz];
26
pic[n] = qdev_get_gpio_in(dev, n);
28
ARMPredicateReg *d = vd;
29
uint32_t flags;
30
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate-sve.c
33
+++ b/target/arm/translate-sve.c
34
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
35
TCGv_i64 op0, op1, t0, t1, tmax;
36
TCGv_i32 t2, t3;
37
TCGv_ptr ptr;
38
- unsigned desc, vsz = vec_full_reg_size(s);
39
+ unsigned vsz = vec_full_reg_size(s);
40
+ unsigned desc = 0;
41
TCGCond cond;
42
43
if (!sve_access_check(s)) {
44
@@ -XXX,XX +XXX,XX @@ static bool trans_WHILE(DisasContext *s, arg_WHILE *a)
45
/* Scale elements to bits. */
46
tcg_gen_shli_i32(t2, t2, a->esz);
47
48
- desc = (vsz / 8) - 2;
49
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, a->esz);
50
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, vsz / 8);
51
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
52
t3 = tcg_const_i32(desc);
53
54
ptr = tcg_temp_new_ptr();
55
--
27
--
56
2.20.1
28
2.34.1
57
29
58
30
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
The API does not generate an error for setting ASYNC | SYNC; that merely
4
using these field macros for predicates.
4
constrains the selection vs the per-cpu default. For qemu linux-user,
5
choose SYNC as the default.
5
6
7
Cc: qemu-stable@nongnu.org
8
Reported-by: Gustavo Romero <gustavo.romero@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-7-richard.henderson@linaro.org
10
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@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
target/arm/sve_helper.c | 6 +++---
14
linux-user/aarch64/target_prctl.h | 29 +++++++++++++++++------------
12
target/arm/translate-sve.c | 6 +++---
15
1 file changed, 17 insertions(+), 12 deletions(-)
13
2 files changed, 6 insertions(+), 6 deletions(-)
14
16
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
17
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
16
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sve_helper.c
19
--- a/linux-user/aarch64/target_prctl.h
18
+++ b/target/arm/sve_helper.c
20
+++ b/linux-user/aarch64/target_prctl.h
19
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
21
@@ -XXX,XX +XXX,XX @@ static abi_long do_prctl_set_tagged_addr_ctrl(CPUArchState *env, abi_long arg2)
20
22
env->tagged_addr_enable = arg2 & PR_TAGGED_ADDR_ENABLE;
21
uint64_t HELPER(sve_cntp)(void *vn, void *vg, uint32_t pred_desc)
23
22
{
24
if (cpu_isar_feature(aa64_mte, cpu)) {
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
25
- switch (arg2 & PR_MTE_TCF_MASK) {
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
26
- case PR_MTE_TCF_NONE:
25
+ intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
27
- case PR_MTE_TCF_SYNC:
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
28
- case PR_MTE_TCF_ASYNC:
27
uint64_t *n = vn, *g = vg, sum = 0, mask = pred_esz_masks[esz];
29
- break;
28
intptr_t i;
30
- default:
29
31
- return -EINVAL;
30
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); ++i) {
32
- }
31
+ for (i = 0; i < words; ++i) {
33
-
32
uint64_t t = n[i] & g[i] & mask;
34
/*
33
sum += ctpop64(t);
35
* Write PR_MTE_TCF to SCTLR_EL1[TCF0].
34
}
36
- * Note that the syscall values are consistent with hw.
35
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
37
+ *
36
index XXXXXXX..XXXXXXX 100644
38
+ * The kernel has a per-cpu configuration for the sysadmin,
37
--- a/target/arm/translate-sve.c
39
+ * /sys/devices/system/cpu/cpu<N>/mte_tcf_preferred,
38
+++ b/target/arm/translate-sve.c
40
+ * which qemu does not implement.
39
@@ -XXX,XX +XXX,XX @@ static void do_cntp(DisasContext *s, TCGv_i64 val, int esz, int pn, int pg)
41
+ *
40
} else {
42
+ * Because there is no performance difference between the modes, and
41
TCGv_ptr t_pn = tcg_temp_new_ptr();
43
+ * because SYNC is most useful for debugging MTE errors, choose SYNC
42
TCGv_ptr t_pg = tcg_temp_new_ptr();
44
+ * as the preferred mode. With this preference, and the way the API
43
- unsigned desc;
45
+ * uses only two bits, there is no way for the program to select
44
+ unsigned desc = 0;
46
+ * ASYMM mode.
45
TCGv_i32 t_desc;
47
*/
46
48
- env->cp15.sctlr_el[1] =
47
- desc = psz - 2;
49
- deposit64(env->cp15.sctlr_el[1], 38, 2, arg2 >> PR_MTE_TCF_SHIFT);
48
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
50
+ unsigned tcf = 0;
49
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, psz);
51
+ if (arg2 & PR_MTE_TCF_SYNC) {
50
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, esz);
52
+ tcf = 1;
51
53
+ } else if (arg2 & PR_MTE_TCF_ASYNC) {
52
tcg_gen_addi_ptr(t_pn, cpu_env, pred_full_reg_offset(s, pn));
54
+ tcf = 2;
53
tcg_gen_addi_ptr(t_pg, cpu_env, pred_full_reg_offset(s, pg));
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].
54
--
60
--
55
2.20.1
61
2.34.1
56
57
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
The field is encoded as [0-3], which is convenient for
4
using these field macros for predicates.
4
indexing our array of function pointers, but the true
5
value is [1-4]. Adjust before calling do_mem_zpa.
5
6
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")
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-6-richard.henderson@linaro.org
13
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Message-id: 20240207025210.8837-3-richard.henderson@linaro.org
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
17
---
11
target/arm/sve_helper.c | 30 ++++++++++++++----------------
18
target/arm/tcg/translate-sve.c | 16 ++++++++--------
12
target/arm/translate-sve.c | 4 ++--
19
1 file changed, 8 insertions(+), 8 deletions(-)
13
2 files changed, 16 insertions(+), 18 deletions(-)
14
20
15
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
21
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
16
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/sve_helper.c
23
--- a/target/arm/tcg/translate-sve.c
18
+++ b/target/arm/sve_helper.c
24
+++ b/target/arm/tcg/translate-sve.c
19
@@ -XXX,XX +XXX,XX @@ static uint32_t do_zero(ARMPredicateReg *d, intptr_t oprsz)
25
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
20
void HELPER(sve_brkpa)(void *vd, void *vn, void *vm, void *vg,
26
TCGv_ptr t_pg;
21
uint32_t pred_desc)
27
int desc = 0;
22
{
28
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
29
- /*
24
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
30
- * For e.g. LD4, there are not enough arguments to pass all 4
25
if (last_active_pred(vn, vg, oprsz)) {
31
- * registers as pointers, so encode the regno into the data field.
26
compute_brk_z(vd, vm, vg, oprsz, true);
32
- * For consistency, do this even for LD1.
33
- */
34
+ assert(mte_n >= 1 && mte_n <= 4);
35
if (s->mte_active[0]) {
36
int msz = dtype_msz(dtype);
37
38
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
39
addr = clean_data_tbi(s, addr);
40
}
41
42
+ /*
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);
56
}
57
58
static bool trans_LD_zprr(DisasContext *s, arg_rprr_load *a)
59
@@ -XXX,XX +XXX,XX @@ static void do_st_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
60
if (nreg == 0) {
61
/* ST1 */
62
fn = fn_single[s->mte_active[0]][be][msz][esz];
63
- nreg = 1;
27
} else {
64
} else {
28
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_brkpa)(void *vd, void *vn, void *vm, void *vg,
65
/* ST2, ST3, ST4 -- msz == esz, enforced by encoding */
29
uint32_t HELPER(sve_brkpas)(void *vd, void *vn, void *vm, void *vg,
66
assert(msz == esz);
30
uint32_t pred_desc)
67
fn = fn_multiple[s->mte_active[0]][be][nreg - 1][msz];
31
{
68
}
32
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
69
assert(fn != NULL);
33
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
70
- do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg, true, fn);
34
if (last_active_pred(vn, vg, oprsz)) {
71
+ do_mem_zpa(s, zt, pg, addr, msz_dtype(s, msz), nreg + 1, true, fn);
35
return compute_brks_z(vd, vm, vg, oprsz, true);
36
} else {
37
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkpas)(void *vd, void *vn, void *vm, void *vg,
38
void HELPER(sve_brkpb)(void *vd, void *vn, void *vm, void *vg,
39
uint32_t pred_desc)
40
{
41
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
42
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
43
if (last_active_pred(vn, vg, oprsz)) {
44
compute_brk_z(vd, vm, vg, oprsz, false);
45
} else {
46
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_brkpb)(void *vd, void *vn, void *vm, void *vg,
47
uint32_t HELPER(sve_brkpbs)(void *vd, void *vn, void *vm, void *vg,
48
uint32_t pred_desc)
49
{
50
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
51
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
52
if (last_active_pred(vn, vg, oprsz)) {
53
return compute_brks_z(vd, vm, vg, oprsz, false);
54
} else {
55
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sve_brkpbs)(void *vd, void *vn, void *vm, void *vg,
56
57
void HELPER(sve_brka_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
58
{
59
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
60
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
61
compute_brk_z(vd, vn, vg, oprsz, true);
62
}
72
}
63
73
64
uint32_t HELPER(sve_brkas_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
74
static bool trans_ST_zprr(DisasContext *s, arg_rprr_store *a)
65
{
66
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
67
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
68
return compute_brks_z(vd, vn, vg, oprsz, true);
69
}
70
71
void HELPER(sve_brkb_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
72
{
73
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
74
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
75
compute_brk_z(vd, vn, vg, oprsz, false);
76
}
77
78
uint32_t HELPER(sve_brkbs_z)(void *vd, void *vn, void *vg, uint32_t pred_desc)
79
{
80
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
81
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
82
return compute_brks_z(vd, vn, vg, oprsz, false);
83
}
84
85
void HELPER(sve_brka_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
86
{
87
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
88
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
89
compute_brk_m(vd, vn, vg, oprsz, true);
90
}
91
92
uint32_t HELPER(sve_brkas_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
93
{
94
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
95
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
96
return compute_brks_m(vd, vn, vg, oprsz, true);
97
}
98
99
void HELPER(sve_brkb_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
100
{
101
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
102
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
103
compute_brk_m(vd, vn, vg, oprsz, false);
104
}
105
106
uint32_t HELPER(sve_brkbs_m)(void *vd, void *vn, void *vg, uint32_t pred_desc)
107
{
108
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
109
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
110
return compute_brks_m(vd, vn, vg, oprsz, false);
111
}
112
113
void HELPER(sve_brkn)(void *vd, void *vn, void *vg, uint32_t pred_desc)
114
{
115
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
116
-
117
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
118
if (!last_active_pred(vn, vg, oprsz)) {
119
do_zero(vd, oprsz);
120
}
121
@@ -XXX,XX +XXX,XX @@ static uint32_t predtest_ones(ARMPredicateReg *d, intptr_t oprsz,
122
123
uint32_t HELPER(sve_brkns)(void *vd, void *vn, void *vg, uint32_t pred_desc)
124
{
125
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
126
-
127
+ intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
128
if (last_active_pred(vn, vg, oprsz)) {
129
return predtest_ones(vd, oprsz, -1);
130
} else {
131
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
132
index XXXXXXX..XXXXXXX 100644
133
--- a/target/arm/translate-sve.c
134
+++ b/target/arm/translate-sve.c
135
@@ -XXX,XX +XXX,XX @@ static bool do_brk3(DisasContext *s, arg_rprr_s *a,
136
TCGv_ptr n = tcg_temp_new_ptr();
137
TCGv_ptr m = tcg_temp_new_ptr();
138
TCGv_ptr g = tcg_temp_new_ptr();
139
- TCGv_i32 t = tcg_const_i32(vsz - 2);
140
+ TCGv_i32 t = tcg_const_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz));
141
142
tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
143
tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
144
@@ -XXX,XX +XXX,XX @@ static bool do_brk2(DisasContext *s, arg_rpr_s *a,
145
TCGv_ptr d = tcg_temp_new_ptr();
146
TCGv_ptr n = tcg_temp_new_ptr();
147
TCGv_ptr g = tcg_temp_new_ptr();
148
- TCGv_i32 t = tcg_const_i32(vsz - 2);
149
+ TCGv_i32 t = tcg_const_i32(FIELD_DP32(0, PREDDESC, OPRSZ, vsz));
150
151
tcg_gen_addi_ptr(d, cpu_env, pred_full_reg_offset(s, a->rd));
152
tcg_gen_addi_ptr(n, cpu_env, pred_full_reg_offset(s, a->rn));
153
--
75
--
154
2.20.1
76
2.34.1
155
156
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Wrote too much with low-half zip (zip1) with vl % 512 != 0.
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).
4
7
5
Adjust all of the x + (y << s) to x | (y << s) as a style fix.
8
Cc: qemu-stable@nongnu.org
6
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
We only ever have exact overlap between D, M, and N. Therefore
8
we only need a single temporary, and we do not need to check for
9
partial overlap.
10
11
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210309155305.11301-3-richard.henderson@linaro.org
11
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Message-id: 20240207025210.8837-4-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
14
---
17
target/arm/sve_helper.c | 25 ++++++++++++++-----------
15
target/arm/internals.h | 2 +-
18
1 file changed, 14 insertions(+), 11 deletions(-)
16
target/arm/tcg/translate-sve.c | 7 ++++---
17
2 files changed, 5 insertions(+), 4 deletions(-)
19
18
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
19
diff --git a/target/arm/internals.h b/target/arm/internals.h
21
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/sve_helper.c
21
--- a/target/arm/internals.h
23
+++ b/target/arm/sve_helper.c
22
+++ b/target/arm/internals.h
24
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
23
@@ -XXX,XX +XXX,XX @@ FIELD(MTEDESC, TBI, 4, 2)
25
intptr_t oprsz = FIELD_EX32(pred_desc, PREDDESC, OPRSZ);
24
FIELD(MTEDESC, TCMA, 6, 2)
26
int esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
25
FIELD(MTEDESC, WRITE, 8, 1)
27
intptr_t high = FIELD_EX32(pred_desc, PREDDESC, DATA);
26
FIELD(MTEDESC, ALIGN, 9, 3)
28
+ int esize = 1 << esz;
27
-FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - 12) /* size - 1 */
29
uint64_t *d = vd;
28
+FIELD(MTEDESC, SIZEM1, 12, SIMD_DATA_BITS - SVE_MTEDESC_SHIFT - 12) /* size - 1 */
30
intptr_t i;
29
31
30
bool mte_probe(CPUARMState *env, uint32_t desc, uint64_t ptr);
32
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
31
uint64_t mte_check(CPUARMState *env, uint32_t desc, uint64_t ptr, uintptr_t ra);
33
mm = extract64(mm, high * half, half);
32
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
34
nn = expand_bits(nn, esz);
33
index XXXXXXX..XXXXXXX 100644
35
mm = expand_bits(mm, esz);
34
--- a/target/arm/tcg/translate-sve.c
36
- d[0] = nn + (mm << (1 << esz));
35
+++ b/target/arm/tcg/translate-sve.c
37
+ d[0] = nn | (mm << esize);
36
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
37
{
38
unsigned vsz = vec_full_reg_size(s);
39
TCGv_ptr t_pg;
40
+ uint32_t sizem1;
41
int desc = 0;
42
43
assert(mte_n >= 1 && mte_n <= 4);
44
+ sizem1 = (mte_n << dtype_msz(dtype)) - 1;
45
+ assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
46
if (s->mte_active[0]) {
47
- int msz = dtype_msz(dtype);
48
-
49
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
50
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
51
desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
52
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
53
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (mte_n << msz) - 1);
54
+ desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
55
desc <<= SVE_MTEDESC_SHIFT;
38
} else {
56
} else {
39
- ARMPredicateReg tmp_n, tmp_m;
57
addr = clean_data_tbi(s, addr);
40
+ ARMPredicateReg tmp;
41
42
/* We produce output faster than we consume input.
43
Therefore we must be mindful of possible overlap. */
44
- if ((vn - vd) < (uintptr_t)oprsz) {
45
- vn = memcpy(&tmp_n, vn, oprsz);
46
- }
47
- if ((vm - vd) < (uintptr_t)oprsz) {
48
- vm = memcpy(&tmp_m, vm, oprsz);
49
+ if (vd == vn) {
50
+ vn = memcpy(&tmp, vn, oprsz);
51
+ if (vd == vm) {
52
+ vm = vn;
53
+ }
54
+ } else if (vd == vm) {
55
+ vm = memcpy(&tmp, vm, oprsz);
56
}
57
if (high) {
58
high = oprsz >> 1;
59
}
60
61
- if ((high & 3) == 0) {
62
+ if ((oprsz & 7) == 0) {
63
uint32_t *n = vn, *m = vm;
64
high >>= 2;
65
66
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
67
+ for (i = 0; i < oprsz / 8; i++) {
68
uint64_t nn = n[H4(high + i)];
69
uint64_t mm = m[H4(high + i)];
70
71
nn = expand_bits(nn, esz);
72
mm = expand_bits(mm, esz);
73
- d[i] = nn + (mm << (1 << esz));
74
+ d[i] = nn | (mm << esize);
75
}
76
} else {
77
uint8_t *n = vn, *m = vm;
78
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_zip_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
79
80
nn = expand_bits(nn, esz);
81
mm = expand_bits(mm, esz);
82
- d16[H2(i)] = nn + (mm << (1 << esz));
83
+ d16[H2(i)] = nn | (mm << esize);
84
}
85
}
86
}
87
--
58
--
88
2.20.1
59
2.34.1
89
90
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Since b64ee454a4a0, all predicate operations should be
3
Share code that creates mtedesc and embeds within simd_desc.
4
using these field macros for predicates.
5
4
5
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20210309155305.11301-5-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@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
target/arm/sve_helper.c | 6 +++---
12
target/arm/tcg/translate-a64.h | 2 ++
12
target/arm/translate-sve.c | 7 +++----
13
target/arm/tcg/translate-sme.c | 15 +++--------
13
2 files changed, 6 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/target/arm/sve_helper.c b/target/arm/sve_helper.c
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/target/arm/sve_helper.c
19
--- a/target/arm/tcg/translate-a64.h
18
+++ b/target/arm/sve_helper.c
20
+++ b/target/arm/tcg/translate-a64.h
19
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_compact_d)(void *vd, void *vn, void *vg, uint32_t desc)
21
@@ -XXX,XX +XXX,XX @@ bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
20
*/
22
bool sve_access_check(DisasContext *s);
21
int32_t HELPER(sve_last_active_element)(void *vg, uint32_t pred_desc)
23
bool sme_enabled_check(DisasContext *s);
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);
60
+
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
71
};
72
73
-static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
74
- int dtype, uint32_t mte_n, bool is_write,
75
- gen_helper_gvec_mem *fn)
76
+uint32_t make_svemte_desc(DisasContext *s, unsigned vsz, uint32_t nregs,
77
+ uint32_t msz, bool is_write, uint32_t data)
22
{
78
{
23
- intptr_t oprsz = extract32(pred_desc, 0, SIMD_OPRSZ_BITS) + 2;
79
- unsigned vsz = vec_full_reg_size(s);
24
- intptr_t esz = extract32(pred_desc, SIMD_DATA_SHIFT, 2);
80
- TCGv_ptr t_pg;
25
+ intptr_t words = DIV_ROUND_UP(FIELD_EX32(pred_desc, PREDDESC, OPRSZ), 8);
81
uint32_t sizem1;
26
+ intptr_t esz = FIELD_EX32(pred_desc, PREDDESC, ESZ);
82
- int desc = 0;
27
83
+ uint32_t desc = 0;
28
- return last_active_element(vg, DIV_ROUND_UP(oprsz, 8), esz);
84
29
+ return last_active_element(vg, words, esz);
85
- assert(mte_n >= 1 && mte_n <= 4);
86
- sizem1 = (mte_n << dtype_msz(dtype)) - 1;
87
+ /* Assert all of the data fits, with or without MTE enabled. */
88
+ assert(nregs >= 1 && nregs <= 4);
89
+ sizem1 = (nregs << msz) - 1;
90
assert(sizem1 <= R_MTEDESC_SIZEM1_MASK >> R_MTEDESC_SIZEM1_SHIFT);
91
+ assert(data < 1u << SVE_MTEDESC_SHIFT);
92
+
93
if (s->mte_active[0]) {
94
desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
95
desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
96
@@ -XXX,XX +XXX,XX @@ static void do_mem_zpa(DisasContext *s, int zt, int pg, TCGv_i64 addr,
97
desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
98
desc = FIELD_DP32(desc, MTEDESC, SIZEM1, sizem1);
99
desc <<= SVE_MTEDESC_SHIFT;
100
- } else {
101
+ }
102
+ return simd_desc(vsz, vsz, desc | data);
103
+}
104
+
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)
108
+{
109
+ TCGv_ptr t_pg;
110
+ uint32_t desc;
111
+
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)
129
{
130
- unsigned vsz = vec_full_reg_size(s);
131
TCGv_ptr t_zm = tcg_temp_new_ptr();
132
TCGv_ptr t_pg = tcg_temp_new_ptr();
133
TCGv_ptr t_zt = tcg_temp_new_ptr();
134
- int desc = 0;
135
-
136
- if (s->mte_active[0]) {
137
- desc = FIELD_DP32(desc, MTEDESC, MIDX, get_mem_index(s));
138
- desc = FIELD_DP32(desc, MTEDESC, TBI, s->tbid);
139
- desc = FIELD_DP32(desc, MTEDESC, TCMA, s->tcma);
140
- desc = FIELD_DP32(desc, MTEDESC, WRITE, is_write);
141
- desc = FIELD_DP32(desc, MTEDESC, SIZEM1, (1 << msz) - 1);
142
- desc <<= SVE_MTEDESC_SHIFT;
143
- }
144
- desc = simd_desc(vsz, vsz, desc | scale);
145
+ uint32_t desc;
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));
30
}
153
}
31
154
32
void HELPER(sve_splice)(void *vd, void *vn, void *vm, void *vg, uint32_t desc)
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-sve.c
36
+++ b/target/arm/translate-sve.c
37
@@ -XXX,XX +XXX,XX @@ static void find_last_active(DisasContext *s, TCGv_i32 ret, int esz, int pg)
38
*/
39
TCGv_ptr t_p = tcg_temp_new_ptr();
40
TCGv_i32 t_desc;
41
- unsigned vsz = pred_full_reg_size(s);
42
- unsigned desc;
43
+ unsigned desc = 0;
44
45
- desc = vsz - 2;
46
- desc = deposit32(desc, SIMD_DATA_SHIFT, 2, esz);
47
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, pred_full_reg_size(s));
48
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, esz);
49
50
tcg_gen_addi_ptr(t_p, cpu_env, pred_full_reg_offset(s, pg));
51
t_desc = tcg_const_i32(desc);
52
--
155
--
53
2.20.1
156
2.34.1
54
55
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
Wrote too much with punpk1 with vl % 512 != 0.
3
These functions "use the standard load helpers", but
4
fail to clean_data_tbi or populate mtedesc.
4
5
6
Cc: qemu-stable@nongnu.org
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210309155305.11301-4-richard.henderson@linaro.org
9
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
10
Message-id: 20240207025210.8837-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/sve_helper.c | 4 ++--
13
target/arm/tcg/translate-sve.c | 15 +++++++++++++--
12
1 file changed, 2 insertions(+), 2 deletions(-)
14
1 file changed, 13 insertions(+), 2 deletions(-)
13
15
14
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
16
diff --git a/target/arm/tcg/translate-sve.c b/target/arm/tcg/translate-sve.c
15
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/sve_helper.c
18
--- a/target/arm/tcg/translate-sve.c
17
+++ b/target/arm/sve_helper.c
19
+++ b/target/arm/tcg/translate-sve.c
18
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_punpk_p)(void *vd, void *vn, uint32_t pred_desc)
20
@@ -XXX,XX +XXX,XX @@ static void do_ldrq(DisasContext *s, int zt, int pg, TCGv_i64 addr, int dtype)
19
high = oprsz >> 1;
21
unsigned vsz = vec_full_reg_size(s);
20
}
22
TCGv_ptr t_pg;
21
23
int poff;
22
- if ((high & 3) == 0) {
24
+ uint32_t desc;
23
+ if ((oprsz & 7) == 0) {
25
24
uint32_t *n = vn;
26
/* Load the first quadword using the normal predicated load helpers. */
25
high >>= 2;
27
+ if (!s->mte_active[0]) {
26
28
+ addr = clean_data_tbi(s, addr);
27
- for (i = 0; i < DIV_ROUND_UP(oprsz, 8); i++) {
29
+ }
28
+ for (i = 0; i < oprsz / 8; i++) {
30
+
29
uint64_t nn = n[H4(high + i)];
31
poff = pred_full_reg_offset(s, pg);
30
d[i] = expand_bits(nn, 0);
32
if (vsz > 16) {
31
}
33
/*
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.
32
--
72
--
33
2.20.1
73
2.34.1
34
35
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
With the reduction operations, we intentionally increase maxsz to
3
The TBI and TCMA bits are located within mtedesc, not desc.
4
the next power of 2, so as to fill out the reduction tree correctly.
5
Since e2e7168a214b, oprsz must equal maxsz, with exceptions for small
6
vectors, so this triggers an assertion for vector sizes > 32 that are
7
not themselves a power of 2.
8
4
9
Pass the power-of-two value in the simd_data field instead.
5
Cc: qemu-stable@nongnu.org
10
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20210309155305.11301-9-richard.henderson@linaro.org
8
Tested-by: Gustavo Romero <gustavo.romero@linaro.org>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20240207025210.8837-7-richard.henderson@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
11
---
16
target/arm/sve_helper.c | 2 +-
12
target/arm/tcg/sme_helper.c | 8 ++++----
17
target/arm/translate-sve.c | 2 +-
13
target/arm/tcg/sve_helper.c | 12 ++++++------
18
2 files changed, 2 insertions(+), 2 deletions(-)
14
2 files changed, 10 insertions(+), 10 deletions(-)
19
15
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
16
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
21
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/sve_helper.c
18
--- a/target/arm/tcg/sme_helper.c
23
+++ b/target/arm/sve_helper.c
19
+++ b/target/arm/tcg/sme_helper.c
24
@@ -XXX,XX +XXX,XX @@ static TYPE NAME##_reduce(TYPE *data, float_status *status, uintptr_t n) \
20
@@ -XXX,XX +XXX,XX @@ void sme_ld1_mte(CPUARMState *env, void *za, uint64_t *vg,
25
} \
21
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
26
uint64_t HELPER(NAME)(void *vn, void *vg, void *vs, uint32_t desc) \
22
27
{ \
23
/* Perform gross MTE suppression early. */
28
- uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_maxsz(desc); \
24
- if (!tbi_check(desc, bit55) ||
29
+ uintptr_t i, oprsz = simd_oprsz(desc), maxsz = simd_data(desc); \
25
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
30
TYPE data[sizeof(ARMVectorReg) / sizeof(TYPE)]; \
26
+ if (!tbi_check(mtedesc, bit55) ||
31
for (i = 0; i < oprsz; ) { \
27
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
32
uint16_t pg = *(uint16_t *)(vg + H1_2(i >> 3)); \
28
mtedesc = 0;
33
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
29
}
30
31
@@ -XXX,XX +XXX,XX @@ void sme_st1_mte(CPUARMState *env, void *za, uint64_t *vg, target_ulong addr,
32
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
33
34
/* Perform gross MTE suppression early. */
35
- if (!tbi_check(desc, bit55) ||
36
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
37
+ if (!tbi_check(mtedesc, bit55) ||
38
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
39
mtedesc = 0;
40
}
41
42
diff --git a/target/arm/tcg/sve_helper.c b/target/arm/tcg/sve_helper.c
34
index XXXXXXX..XXXXXXX 100644
43
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/translate-sve.c
44
--- a/target/arm/tcg/sve_helper.c
36
+++ b/target/arm/translate-sve.c
45
+++ b/target/arm/tcg/sve_helper.c
37
@@ -XXX,XX +XXX,XX @@ static void do_reduce(DisasContext *s, arg_rpr_esz *a,
46
@@ -XXX,XX +XXX,XX @@ void sve_ldN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
38
{
47
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
39
unsigned vsz = vec_full_reg_size(s);
48
40
unsigned p2vsz = pow2ceil(vsz);
49
/* Perform gross MTE suppression early. */
41
- TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, p2vsz, 0));
50
- if (!tbi_check(desc, bit55) ||
42
+ TCGv_i32 t_desc = tcg_const_i32(simd_desc(vsz, vsz, p2vsz));
51
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
43
TCGv_ptr t_zn, t_pg, status;
52
+ if (!tbi_check(mtedesc, bit55) ||
44
TCGv_i64 temp;
53
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
54
mtedesc = 0;
55
}
56
57
@@ -XXX,XX +XXX,XX @@ void sve_ldnfff1_r_mte(CPUARMState *env, void *vg, target_ulong addr,
58
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
59
60
/* Perform gross MTE suppression early. */
61
- if (!tbi_check(desc, bit55) ||
62
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
63
+ if (!tbi_check(mtedesc, bit55) ||
64
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
65
mtedesc = 0;
66
}
67
68
@@ -XXX,XX +XXX,XX @@ void sve_stN_r_mte(CPUARMState *env, uint64_t *vg, target_ulong addr,
69
desc = extract32(desc, 0, SIMD_DATA_SHIFT + SVE_MTEDESC_SHIFT);
70
71
/* Perform gross MTE suppression early. */
72
- if (!tbi_check(desc, bit55) ||
73
- tcma_check(desc, bit55, allocation_tag_from_addr(addr))) {
74
+ if (!tbi_check(mtedesc, bit55) ||
75
+ tcma_check(mtedesc, bit55, allocation_tag_from_addr(addr))) {
76
mtedesc = 0;
77
}
45
78
46
--
79
--
47
2.20.1
80
2.34.1
48
49
diff view generated by jsdifflib
1
We're about to move code from the template header into pxa2xx_lcd.c.
1
The raven_io_ops MemoryRegionOps is the only one in the source tree
2
Before doing that, make coding style fixes so checkpatch doesn't
2
which sets .valid.unaligned to indicate that it should support
3
complain about the patch which moves the code. This commit is
3
unaligned accesses and which does not also set .impl.unaligned to
4
whitespace changes only:
4
indicate that its read and write functions can do the unaligned
5
* avoid hard-coded tabs
5
handling themselves. This is a problem, because at the moment the
6
* fix ident on function prototypes
6
core memory system does not implement the support for handling
7
* no newline before open brace on array definitions
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).
8
10
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.
15
16
Fixes: 9a1839164c9c8f06 ("raven: Implement non-contiguous I/O region")
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
18
Tested-by: Cédric Le Goater <clg@redhat.com>
11
Message-id: 20210211141515.8755-9-peter.maydell@linaro.org
19
Reviewed-by: Cédric Le Goater <clg@redhat.com>
20
Message-id: 20240112134640.1775041-1-peter.maydell@linaro.org
12
---
21
---
13
hw/display/pxa2xx_template.h | 66 +++++++++++++++++-------------------
22
hw/pci-host/raven.c | 1 +
14
1 file changed, 32 insertions(+), 34 deletions(-)
23
1 file changed, 1 insertion(+)
15
24
16
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
25
diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c
17
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/display/pxa2xx_template.h
27
--- a/hw/pci-host/raven.c
19
+++ b/hw/display/pxa2xx_template.h
28
+++ b/hw/pci-host/raven.c
20
@@ -XXX,XX +XXX,XX @@
29
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps raven_io_ops = {
21
} while (0)
30
.write = raven_io_write,
22
31
.endianness = DEVICE_LITTLE_ENDIAN,
23
#ifdef HOST_WORDS_BIGENDIAN
32
.impl.max_access_size = 4,
24
-# define SWAP_WORDS    1
33
+ .impl.unaligned = true,
25
+# define SWAP_WORDS 1
34
.valid.unaligned = true,
26
#endif
27
28
-#define FN_2(x)        FN(x + 1) FN(x)
29
-#define FN_4(x)        FN_2(x + 2) FN_2(x)
30
+#define FN_2(x) FN(x + 1) FN(x)
31
+#define FN_4(x) FN_2(x + 2) FN_2(x)
32
33
-static void pxa2xx_draw_line2(void *opaque,
34
- uint8_t *dest, const uint8_t *src, int width, int deststep)
35
+static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
36
+ int width, int deststep)
37
{
38
uint32_t *palette = opaque;
39
uint32_t data;
40
while (width > 0) {
41
data = *(uint32_t *) src;
42
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
43
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
44
#ifdef SWAP_WORDS
45
FN_4(12)
46
FN_4(8)
47
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line2(void *opaque,
48
}
49
}
50
51
-static void pxa2xx_draw_line4(void *opaque,
52
- uint8_t *dest, const uint8_t *src, int width, int deststep)
53
+static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
54
+ int width, int deststep)
55
{
56
uint32_t *palette = opaque;
57
uint32_t data;
58
while (width > 0) {
59
data = *(uint32_t *) src;
60
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
61
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
62
#ifdef SWAP_WORDS
63
FN_2(6)
64
FN_2(4)
65
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line4(void *opaque,
66
}
67
}
68
69
-static void pxa2xx_draw_line8(void *opaque,
70
- uint8_t *dest, const uint8_t *src, int width, int deststep)
71
+static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
72
+ int width, int deststep)
73
{
74
uint32_t *palette = opaque;
75
uint32_t data;
76
while (width > 0) {
77
data = *(uint32_t *) src;
78
-#define FN(x)        COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
79
+#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
80
#ifdef SWAP_WORDS
81
FN(24)
82
FN(16)
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line8(void *opaque,
84
}
85
}
86
87
-static void pxa2xx_draw_line16(void *opaque,
88
- uint8_t *dest, const uint8_t *src, int width, int deststep)
89
+static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
90
+ int width, int deststep)
91
{
92
uint32_t data;
93
unsigned int r, g, b;
94
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16(void *opaque,
95
}
96
}
97
98
-static void pxa2xx_draw_line16t(void *opaque,
99
- uint8_t *dest, const uint8_t *src, int width, int deststep)
100
+static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
101
+ int width, int deststep)
102
{
103
uint32_t data;
104
unsigned int r, g, b;
105
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
106
}
107
}
108
109
-static void pxa2xx_draw_line18(void *opaque,
110
- uint8_t *dest, const uint8_t *src, int width, int deststep)
111
+static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
112
+ int width, int deststep)
113
{
114
uint32_t data;
115
unsigned int r, g, b;
116
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line18(void *opaque,
117
}
118
119
/* The wicked packed format */
120
-static void pxa2xx_draw_line18p(void *opaque,
121
- uint8_t *dest, const uint8_t *src, int width, int deststep)
122
+static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
123
+ int width, int deststep)
124
{
125
uint32_t data[3];
126
unsigned int r, g, b;
127
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line18p(void *opaque,
128
}
129
}
130
131
-static void pxa2xx_draw_line19(void *opaque,
132
- uint8_t *dest, const uint8_t *src, int width, int deststep)
133
+static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
134
+ int width, int deststep)
135
{
136
uint32_t data;
137
unsigned int r, g, b;
138
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19(void *opaque,
139
}
140
141
/* The wicked packed format */
142
-static void pxa2xx_draw_line19p(void *opaque,
143
- uint8_t *dest, const uint8_t *src, int width, int deststep)
144
+static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
145
+ int width, int deststep)
146
{
147
uint32_t data[3];
148
unsigned int r, g, b;
149
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
150
}
151
}
152
153
-static void pxa2xx_draw_line24(void *opaque,
154
- uint8_t *dest, const uint8_t *src, int width, int deststep)
155
+static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
156
+ int width, int deststep)
157
{
158
uint32_t data;
159
unsigned int r, g, b;
160
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24(void *opaque,
161
}
162
}
163
164
-static void pxa2xx_draw_line24t(void *opaque,
165
- uint8_t *dest, const uint8_t *src, int width, int deststep)
166
+static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
167
+ int width, int deststep)
168
{
169
uint32_t data;
170
unsigned int r, g, b;
171
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24t(void *opaque,
172
}
173
}
174
175
-static void pxa2xx_draw_line25(void *opaque,
176
- uint8_t *dest, const uint8_t *src, int width, int deststep)
177
+static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
178
+ int width, int deststep)
179
{
180
uint32_t data;
181
unsigned int r, g, b;
182
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line25(void *opaque,
183
}
184
185
/* Overlay planes disabled, no transparency */
186
-static drawfn pxa2xx_draw_fn_32[16] =
187
-{
188
+static drawfn pxa2xx_draw_fn_32[16] = {
189
[0 ... 0xf] = NULL,
190
[pxa_lcdc_2bpp] = pxa2xx_draw_line2,
191
[pxa_lcdc_4bpp] = pxa2xx_draw_line4,
192
@@ -XXX,XX +XXX,XX @@ static drawfn pxa2xx_draw_fn_32[16] =
193
};
35
};
194
36
195
/* Overlay planes enabled, transparency used */
196
-static drawfn pxa2xx_draw_fn_32t[16] =
197
-{
198
+static drawfn pxa2xx_draw_fn_32t[16] = {
199
[0 ... 0xf] = NULL,
200
[pxa_lcdc_4bpp] = pxa2xx_draw_line4,
201
[pxa_lcdc_8bpp] = pxa2xx_draw_line8,
202
--
37
--
203
2.20.1
38
2.34.1
204
39
205
40
diff view generated by jsdifflib
1
We're about to move code from the template header into pxa2xx_lcd.c.
1
Suppress the deprecation warning when we're running under qtest,
2
Before doing that, make coding style fixes so checkpatch doesn't
2
to avoid "make check" including warning messages in its output.
3
complain about the patch which moves the code. This commit fixes
4
missing braces in the SKIP_PIXEL() macro definition and in if()
5
statements.
6
3
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Message-id: 20210211141515.8755-8-peter.maydell@linaro.org
6
Message-id: 20240206154151.155620-1-peter.maydell@linaro.org
10
---
7
---
11
hw/display/pxa2xx_template.h | 47 +++++++++++++++++++++---------------
8
hw/block/tc58128.c | 4 +++-
12
1 file changed, 28 insertions(+), 19 deletions(-)
9
1 file changed, 3 insertions(+), 1 deletion(-)
13
10
14
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
11
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/display/pxa2xx_template.h
13
--- a/hw/block/tc58128.c
17
+++ b/hw/display/pxa2xx_template.h
14
+++ b/hw/block/tc58128.c
18
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static sh7750_io_device tc58128 = {
19
* Framebuffer format conversion routines.
16
20
*/
17
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2)
21
18
{
22
-# define SKIP_PIXEL(to)        to += deststep
19
- warn_report_once("The TC58128 flash device is deprecated");
23
+# define SKIP_PIXEL(to) do { to += deststep; } while (0)
20
+ if (!qtest_enabled()) {
24
# define COPY_PIXEL(to, from) \
21
+ warn_report_once("The TC58128 flash device is deprecated");
25
do { \
22
+ }
26
*(uint32_t *) to = from; \
23
init_dev(&tc58128_devs[0], zone1);
27
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
24
init_dev(&tc58128_devs[1], zone2);
28
data >>= 5;
25
return sh7750_register_io_device(s, &tc58128);
29
r = (data & 0x1f) << 3;
30
data >>= 5;
31
- if (data & 1)
32
+ if (data & 1) {
33
SKIP_PIXEL(dest);
34
- else
35
+ } else {
36
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
37
+ }
38
data >>= 1;
39
b = (data & 0x1f) << 3;
40
data >>= 5;
41
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line16t(void *opaque,
42
data >>= 5;
43
r = (data & 0x1f) << 3;
44
data >>= 5;
45
- if (data & 1)
46
+ if (data & 1) {
47
SKIP_PIXEL(dest);
48
- else
49
+ } else {
50
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
51
+ }
52
width -= 2;
53
src += 4;
54
}
55
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19(void *opaque,
56
data >>= 6;
57
r = (data & 0x3f) << 2;
58
data >>= 6;
59
- if (data & 1)
60
+ if (data & 1) {
61
SKIP_PIXEL(dest);
62
- else
63
+ } else {
64
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
65
+ }
66
width -= 1;
67
src += 4;
68
}
69
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
70
data[0] >>= 6;
71
r = (data[0] & 0x3f) << 2;
72
data[0] >>= 6;
73
- if (data[0] & 1)
74
+ if (data[0] & 1) {
75
SKIP_PIXEL(dest);
76
- else
77
+ } else {
78
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
79
+ }
80
data[0] >>= 6;
81
b = (data[0] & 0x3f) << 2;
82
data[0] >>= 6;
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
84
data[1] >>= 4;
85
r = (data[1] & 0x3f) << 2;
86
data[1] >>= 6;
87
- if (data[1] & 1)
88
+ if (data[1] & 1) {
89
SKIP_PIXEL(dest);
90
- else
91
+ } else {
92
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
93
+ }
94
data[1] >>= 6;
95
b = (data[1] & 0x3f) << 2;
96
data[1] >>= 6;
97
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
98
data[1] >>= 6;
99
r = ((data[2] & 0x3) << 6) | (data[1] << 2);
100
data[2] >>= 2;
101
- if (data[2] & 1)
102
+ if (data[2] & 1) {
103
SKIP_PIXEL(dest);
104
- else
105
+ } else {
106
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
107
+ }
108
data[2] >>= 6;
109
b = (data[2] & 0x3f) << 2;
110
data[2] >>= 6;
111
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line19p(void *opaque,
112
data[2] >>= 6;
113
r = data[2] << 2;
114
data[2] >>= 6;
115
- if (data[2] & 1)
116
+ if (data[2] & 1) {
117
SKIP_PIXEL(dest);
118
- else
119
+ } else {
120
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
121
+ }
122
width -= 4;
123
}
124
}
125
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line24t(void *opaque,
126
data >>= 8;
127
r = data & 0xff;
128
data >>= 8;
129
- if (data & 1)
130
+ if (data & 1) {
131
SKIP_PIXEL(dest);
132
- else
133
+ } else {
134
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
135
+ }
136
width -= 1;
137
src += 4;
138
}
139
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_draw_line25(void *opaque,
140
data >>= 8;
141
r = data & 0xff;
142
data >>= 8;
143
- if (data & 1)
144
+ if (data & 1) {
145
SKIP_PIXEL(dest);
146
- else
147
+ } else {
148
COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
149
+ }
150
width -= 1;
151
src += 4;
152
}
153
--
26
--
154
2.20.1
27
2.34.1
155
28
156
29
diff view generated by jsdifflib
1
Now that BITS is always 32, expand out all its uses in the template
1
We deliberately don't include qtests_npcm7xx in qtests_aarch64,
2
header, including removing now-useless uses of the glue() macro.
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.
3
4
5
In commit 327b680877b79c4b we added it to qtests_aarch64; revert
6
that change.
7
8
Fixes: 327b680877b79c4b ("tests/qtest: Creating qtest for GMAC Module")
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20210211141515.8755-7-peter.maydell@linaro.org
11
Message-id: 20240206163043.315535-1-peter.maydell@linaro.org
7
---
12
---
8
hw/display/pxa2xx_template.h | 110 ++++++++++++++---------------------
13
tests/qtest/meson.build | 1 -
9
1 file changed, 45 insertions(+), 65 deletions(-)
14
1 file changed, 1 deletion(-)
10
15
11
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
16
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
12
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/pxa2xx_template.h
18
--- a/tests/qtest/meson.build
14
+++ b/hw/display/pxa2xx_template.h
19
+++ b/tests/qtest/meson.build
15
@@ -XXX,XX +XXX,XX @@
20
@@ -XXX,XX +XXX,XX @@ qtests_aarch64 = \
16
*/
21
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
17
22
(config_all_accel.has_key('CONFIG_TCG') and \
18
# define SKIP_PIXEL(to)        to += deststep
23
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
19
-#if BITS == 8
24
- (config_all_devices.has_key('CONFIG_NPCM7XX') ? qtests_npcm7xx : []) + \
20
-# define COPY_PIXEL(to, from) do { *to = from; SKIP_PIXEL(to); } while (0)
25
['arm-cpu-features',
21
-#elif BITS == 15 || BITS == 16
26
'numa-test',
22
-# define COPY_PIXEL(to, from) \
27
'boot-serial-test',
23
- do { \
24
- *(uint16_t *) to = from; \
25
- SKIP_PIXEL(to); \
26
- } while (0)
27
-#elif BITS == 24
28
-# define COPY_PIXEL(to, from) \
29
- do { \
30
- *(uint16_t *) to = from; \
31
- *(to + 2) = (from) >> 16; \
32
- SKIP_PIXEL(to); \
33
- } while (0)
34
-#elif BITS == 32
35
# define COPY_PIXEL(to, from) \
36
do { \
37
*(uint32_t *) to = from; \
38
SKIP_PIXEL(to); \
39
} while (0)
40
-#else
41
-# error unknown bit depth
42
-#endif
43
44
#ifdef HOST_WORDS_BIGENDIAN
45
# define SWAP_WORDS    1
46
@@ -XXX,XX +XXX,XX @@
47
#define FN_2(x)        FN(x + 1) FN(x)
48
#define FN_4(x)        FN_2(x + 2) FN_2(x)
49
50
-static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
51
+static void pxa2xx_draw_line2(void *opaque,
52
uint8_t *dest, const uint8_t *src, int width, int deststep)
53
{
54
uint32_t *palette = opaque;
55
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line2_, BITS)(void *opaque,
56
}
57
}
58
59
-static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
60
+static void pxa2xx_draw_line4(void *opaque,
61
uint8_t *dest, const uint8_t *src, int width, int deststep)
62
{
63
uint32_t *palette = opaque;
64
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line4_, BITS)(void *opaque,
65
}
66
}
67
68
-static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
69
+static void pxa2xx_draw_line8(void *opaque,
70
uint8_t *dest, const uint8_t *src, int width, int deststep)
71
{
72
uint32_t *palette = opaque;
73
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line8_, BITS)(void *opaque,
74
}
75
}
76
77
-static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
78
+static void pxa2xx_draw_line16(void *opaque,
79
uint8_t *dest, const uint8_t *src, int width, int deststep)
80
{
81
uint32_t data;
82
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16_, BITS)(void *opaque,
83
data >>= 6;
84
r = (data & 0x1f) << 3;
85
data >>= 5;
86
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
87
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
88
b = (data & 0x1f) << 3;
89
data >>= 5;
90
g = (data & 0x3f) << 2;
91
data >>= 6;
92
r = (data & 0x1f) << 3;
93
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
94
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
95
width -= 2;
96
src += 4;
97
}
98
}
99
100
-static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
101
+static void pxa2xx_draw_line16t(void *opaque,
102
uint8_t *dest, const uint8_t *src, int width, int deststep)
103
{
104
uint32_t data;
105
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
106
if (data & 1)
107
SKIP_PIXEL(dest);
108
else
109
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
110
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
111
data >>= 1;
112
b = (data & 0x1f) << 3;
113
data >>= 5;
114
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line16t_, BITS)(void *opaque,
115
if (data & 1)
116
SKIP_PIXEL(dest);
117
else
118
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
119
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
120
width -= 2;
121
src += 4;
122
}
123
}
124
125
-static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
126
+static void pxa2xx_draw_line18(void *opaque,
127
uint8_t *dest, const uint8_t *src, int width, int deststep)
128
{
129
uint32_t data;
130
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line18_, BITS)(void *opaque,
131
g = (data & 0x3f) << 2;
132
data >>= 6;
133
r = (data & 0x3f) << 2;
134
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
135
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
136
width -= 1;
137
src += 4;
138
}
139
}
140
141
/* The wicked packed format */
142
-static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
143
+static void pxa2xx_draw_line18p(void *opaque,
144
uint8_t *dest, const uint8_t *src, int width, int deststep)
145
{
146
uint32_t data[3];
147
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line18p_, BITS)(void *opaque,
148
data[0] >>= 6;
149
r = (data[0] & 0x3f) << 2;
150
data[0] >>= 12;
151
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
152
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
153
b = (data[0] & 0x3f) << 2;
154
data[0] >>= 6;
155
g = ((data[1] & 0xf) << 4) | (data[0] << 2);
156
data[1] >>= 4;
157
r = (data[1] & 0x3f) << 2;
158
data[1] >>= 12;
159
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
160
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
161
b = (data[1] & 0x3f) << 2;
162
data[1] >>= 6;
163
g = (data[1] & 0x3f) << 2;
164
data[1] >>= 6;
165
r = ((data[2] & 0x3) << 6) | (data[1] << 2);
166
data[2] >>= 8;
167
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
168
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
169
b = (data[2] & 0x3f) << 2;
170
data[2] >>= 6;
171
g = (data[2] & 0x3f) << 2;
172
data[2] >>= 6;
173
r = data[2] << 2;
174
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
175
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
176
width -= 4;
177
}
178
}
179
180
-static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
181
+static void pxa2xx_draw_line19(void *opaque,
182
uint8_t *dest, const uint8_t *src, int width, int deststep)
183
{
184
uint32_t data;
185
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19_, BITS)(void *opaque,
186
if (data & 1)
187
SKIP_PIXEL(dest);
188
else
189
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
190
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
191
width -= 1;
192
src += 4;
193
}
194
}
195
196
/* The wicked packed format */
197
-static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
198
+static void pxa2xx_draw_line19p(void *opaque,
199
uint8_t *dest, const uint8_t *src, int width, int deststep)
200
{
201
uint32_t data[3];
202
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
203
if (data[0] & 1)
204
SKIP_PIXEL(dest);
205
else
206
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
207
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
208
data[0] >>= 6;
209
b = (data[0] & 0x3f) << 2;
210
data[0] >>= 6;
211
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
212
if (data[1] & 1)
213
SKIP_PIXEL(dest);
214
else
215
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
216
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
217
data[1] >>= 6;
218
b = (data[1] & 0x3f) << 2;
219
data[1] >>= 6;
220
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
221
if (data[2] & 1)
222
SKIP_PIXEL(dest);
223
else
224
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
225
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
226
data[2] >>= 6;
227
b = (data[2] & 0x3f) << 2;
228
data[2] >>= 6;
229
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line19p_, BITS)(void *opaque,
230
if (data[2] & 1)
231
SKIP_PIXEL(dest);
232
else
233
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
234
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
235
width -= 4;
236
}
237
}
238
239
-static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
240
+static void pxa2xx_draw_line24(void *opaque,
241
uint8_t *dest, const uint8_t *src, int width, int deststep)
242
{
243
uint32_t data;
244
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line24_, BITS)(void *opaque,
245
g = data & 0xff;
246
data >>= 8;
247
r = data & 0xff;
248
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
249
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
250
width -= 1;
251
src += 4;
252
}
253
}
254
255
-static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
256
+static void pxa2xx_draw_line24t(void *opaque,
257
uint8_t *dest, const uint8_t *src, int width, int deststep)
258
{
259
uint32_t data;
260
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line24t_, BITS)(void *opaque,
261
if (data & 1)
262
SKIP_PIXEL(dest);
263
else
264
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
265
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
266
width -= 1;
267
src += 4;
268
}
269
}
270
271
-static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
272
+static void pxa2xx_draw_line25(void *opaque,
273
uint8_t *dest, const uint8_t *src, int width, int deststep)
274
{
275
uint32_t data;
276
@@ -XXX,XX +XXX,XX @@ static void glue(pxa2xx_draw_line25_, BITS)(void *opaque,
277
if (data & 1)
278
SKIP_PIXEL(dest);
279
else
280
- COPY_PIXEL(dest, glue(rgb_to_pixel, BITS)(r, g, b));
281
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
282
width -= 1;
283
src += 4;
284
}
285
}
286
287
/* Overlay planes disabled, no transparency */
288
-static drawfn glue(pxa2xx_draw_fn_, BITS)[16] =
289
+static drawfn pxa2xx_draw_fn_32[16] =
290
{
291
[0 ... 0xf] = NULL,
292
- [pxa_lcdc_2bpp] = glue(pxa2xx_draw_line2_, BITS),
293
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
294
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
295
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16_, BITS),
296
- [pxa_lcdc_18bpp] = glue(pxa2xx_draw_line18_, BITS),
297
- [pxa_lcdc_18pbpp] = glue(pxa2xx_draw_line18p_, BITS),
298
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24_, BITS),
299
+ [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
300
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
301
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
302
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
303
+ [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
304
+ [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
305
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
306
};
307
308
/* Overlay planes enabled, transparency used */
309
-static drawfn glue(glue(pxa2xx_draw_fn_, BITS), t)[16] =
310
+static drawfn pxa2xx_draw_fn_32t[16] =
311
{
312
[0 ... 0xf] = NULL,
313
- [pxa_lcdc_4bpp] = glue(pxa2xx_draw_line4_, BITS),
314
- [pxa_lcdc_8bpp] = glue(pxa2xx_draw_line8_, BITS),
315
- [pxa_lcdc_16bpp] = glue(pxa2xx_draw_line16t_, BITS),
316
- [pxa_lcdc_19bpp] = glue(pxa2xx_draw_line19_, BITS),
317
- [pxa_lcdc_19pbpp] = glue(pxa2xx_draw_line19p_, BITS),
318
- [pxa_lcdc_24bpp] = glue(pxa2xx_draw_line24t_, BITS),
319
- [pxa_lcdc_25bpp] = glue(pxa2xx_draw_line25_, BITS),
320
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
321
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
322
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
323
+ [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
324
+ [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
325
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
326
+ [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
327
};
328
329
-#undef BITS
330
#undef COPY_PIXEL
331
#undef SKIP_PIXEL
332
333
--
28
--
334
2.20.1
29
2.34.1
335
30
336
31
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Allow changes to the virt GTDT -- we are going to add the IRQ
2
entry for a new timer to it.
2
3
3
With -Werror=maybe-uninitialized configuration we get
4
../hw/i386/intel_iommu.c: In function ‘vtd_context_device_invalidate’:
5
../hw/i386/intel_iommu.c:1888:10: error: ‘mask’ may be used
6
uninitialized in this function [-Werror=maybe-uninitialized]
7
1888 | mask = ~mask;
8
| ~~~~~^~~~~~~
9
10
Add a g_assert_not_reached() to avoid the error.
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Xu <peterx@redhat.com>
14
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
15
Message-id: 20210309102742.30442-2-eric.auger@redhat.com
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Message-id: 20240122143537.233498-2-peter.maydell@linaro.org
17
---
7
---
18
hw/i386/intel_iommu.c | 2 ++
8
tests/qtest/bios-tables-test-allowed-diff.h | 2 ++
19
1 file changed, 2 insertions(+)
9
1 file changed, 2 insertions(+)
20
10
21
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
11
diff --git a/tests/qtest/bios-tables-test-allowed-diff.h b/tests/qtest/bios-tables-test-allowed-diff.h
22
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/i386/intel_iommu.c
13
--- a/tests/qtest/bios-tables-test-allowed-diff.h
24
+++ b/hw/i386/intel_iommu.c
14
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
25
@@ -XXX,XX +XXX,XX @@ static void vtd_context_device_invalidate(IntelIOMMUState *s,
15
@@ -1 +1,3 @@
26
case 3:
16
/* List of comma-separated changed AML files to ignore */
27
mask = 7; /* Mask bit 2:0 in the SID field */
17
+"tests/data/acpi/virt/FACP",
28
break;
18
+"tests/data/acpi/virt/GTDT",
29
+ default:
30
+ g_assert_not_reached();
31
}
32
mask = ~mask;
33
34
--
19
--
35
2.20.1
20
2.34.1
36
37
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
Armv8.1+ CPUs have the Virtual Host Extension (VHE) which adds a
2
2
non-secure EL2 virtual timer. We implemented the timer itself in the
3
The virt machine already checks KVM_CAP_ARM_VM_IPA_SIZE to get the
3
CPU model, but never wired up its IRQ line to the GIC.
4
upper bound of the IPA size. If that bound is lower than the highest
4
5
possible GPA for the machine, then QEMU will error out. However, the
5
Wire up the IRQ line (this is always safe whether the CPU has the
6
IPA is set to 40 when the highest GPA is less than or equal to 40,
6
interrupt or not, since it always creates the outbound IRQ line).
7
even when KVM may support an IPA limit as low as 32. This means KVM
7
Report it to the guest via dtb and ACPI if the CPU has the feature.
8
may fail the VM creation unnecessarily. Additionally, 40 is selected
8
9
with the value 0, which means use the default, and that gets around
9
The DTB binding is documented in the kernel's
10
a check in some versions of KVM, causing a difficult to debug fail.
10
Documentation/devicetree/bindings/timer/arm\,arch_timer.yaml
11
Always use the IPA size that corresponds to the highest possible GPA,
11
and the ACPI table entries are documented in the ACPI specification
12
unless it's lower than 32, in which case use 32. Also, we must still
12
version 6.3 or later.
13
use 0 when KVM only supports the legacy fixed 40 bit IPA.
13
14
14
Because the IRQ line ACPI binding is new in 6.3, we need to bump the
15
Suggested-by: Marc Zyngier <maz@kernel.org>
15
FADT table rev to show that we might be using 6.3 features.
16
Signed-off-by: Andrew Jones <drjones@redhat.com>
16
17
Reviewed-by: Eric Auger <eric.auger@redhat.com>
17
Note that exposing this IRQ in the DTB will trigger a bug in EDK2
18
Reviewed-by: Marc Zyngier <maz@kernel.org>
18
versions prior to edk2-stable202311, for users who use the virt board
19
Message-id: 20210310135218.255205-3-drjones@redhat.com
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.)
31
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
34
Message-id: 20240122143537.233498-3-peter.maydell@linaro.org
21
---
35
---
22
target/arm/kvm_arm.h | 6 ++++--
36
include/hw/arm/virt.h | 2 ++
23
hw/arm/virt.c | 23 ++++++++++++++++-------
37
hw/arm/virt-acpi-build.c | 20 ++++++++++----
24
target/arm/kvm.c | 4 +++-
38
hw/arm/virt.c | 60 ++++++++++++++++++++++++++++++++++------
25
3 files changed, 23 insertions(+), 10 deletions(-)
39
3 files changed, 67 insertions(+), 15 deletions(-)
26
40
27
diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
41
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
28
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/kvm_arm.h
43
--- a/include/hw/arm/virt.h
30
+++ b/target/arm/kvm_arm.h
44
+++ b/include/hw/arm/virt.h
31
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_sve_supported(void);
45
@@ -XXX,XX +XXX,XX @@ struct VirtMachineClass {
32
/**
46
/* Machines < 6.2 have no support for describing cpu topology to guest */
33
* kvm_arm_get_max_vm_ipa_size:
47
bool no_cpu_topology;
34
* @ms: Machine state handle
48
bool no_tcg_lpa2;
35
+ * @fixed_ipa: True when the IPA limit is fixed at 40. This is the case
49
+ bool no_ns_el2_virt_timer_irq;
36
+ * for legacy KVM.
50
};
37
*
51
38
* Returns the number of bits in the IPA address space supported by KVM
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)
39
*/
73
*/
40
-int kvm_arm_get_max_vm_ipa_size(MachineState *ms);
74
static void
41
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa);
75
build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
42
76
@@ -XXX,XX +XXX,XX @@ build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
43
/**
77
uint32_t irqflags = vmc->claim_edge_triggered_timers ?
44
* kvm_arm_sync_mpstate_to_kvm:
78
1 : /* Interrupt is Edge triggered */
45
@@ -XXX,XX +XXX,XX @@ static inline void kvm_arm_add_vcpu_properties(Object *obj)
79
0; /* Interrupt is Level triggered */
46
g_assert_not_reached();
80
- AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
47
}
81
+ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id,
48
82
.oem_table_id = vms->oem_table_id };
49
-static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
83
50
+static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
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)
51
{
105
{
52
g_assert_not_reached();
106
- /* ACPI v6.0 */
53
}
107
+ /* ACPI v6.3 */
108
AcpiFadtData fadt = {
109
.rev = 6,
110
- .minor_ver = 0,
111
+ .minor_ver = 3,
112
.flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
113
.xdsdt_tbl_offset = &dsdt_tbl_offset,
114
};
54
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
115
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
55
index XXXXXXX..XXXXXXX 100644
116
index XXXXXXX..XXXXXXX 100644
56
--- a/hw/arm/virt.c
117
--- a/hw/arm/virt.c
57
+++ b/hw/arm/virt.c
118
+++ b/hw/arm/virt.c
58
@@ -XXX,XX +XXX,XX @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
119
@@ -XXX,XX +XXX,XX @@ static void create_randomness(MachineState *ms, const char *node)
59
static int virt_kvm_type(MachineState *ms, const char *type_str)
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)
60
{
138
{
61
VirtMachineState *vms = VIRT_MACHINE(ms);
139
MachineState *ms = MACHINE(vms);
62
- int max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms);
140
@@ -XXX,XX +XXX,XX @@ static void fdt_add_timer_nodes(const VirtMachineState *vms)
63
- int requested_pa_size;
141
"arm,armv7-timer");
64
+ int max_vm_pa_size, requested_pa_size;
142
}
65
+ bool fixed_ipa;
143
qemu_fdt_setprop(ms->fdt, "/timer", "always-on", NULL, 0);
66
+
144
- qemu_fdt_setprop_cells(ms->fdt, "/timer", "interrupts",
67
+ max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa);
145
- GIC_FDT_IRQ_TYPE_PPI,
68
146
- INTID_TO_PPI(ARCH_TIMER_S_EL1_IRQ), irqflags,
69
/* we freeze the memory map to compute the highest gpa */
147
- GIC_FDT_IRQ_TYPE_PPI,
70
virt_set_memmap(vms);
148
- INTID_TO_PPI(ARCH_TIMER_NS_EL1_IRQ), irqflags,
71
149
- GIC_FDT_IRQ_TYPE_PPI,
72
requested_pa_size = 64 - clz64(vms->highest_gpa);
150
- INTID_TO_PPI(ARCH_TIMER_VIRT_IRQ), irqflags,
73
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);
190
}
191
+
192
+ /* Now we've created the CPUs we can see if they have the hypvirt timer */
193
+ vms->ns_el2_virt_timer_irq = ns_el2_virt_timer_present() &&
194
+ !vmc->no_ns_el2_virt_timer_irq;
195
+
196
fdt_add_timer_nodes(vms);
197
fdt_add_cpu_nodes(vms);
198
199
@@ -XXX,XX +XXX,XX @@ DEFINE_VIRT_MACHINE_AS_LATEST(9, 0)
200
201
static void virt_machine_8_2_options(MachineClass *mc)
202
{
203
+ VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc));
204
+
205
virt_machine_9_0_options(mc);
206
compat_props_add(mc->compat_props, hw_compat_8_2, hw_compat_8_2_len);
74
+ /*
207
+ /*
75
+ * KVM requires the IPA size to be at least 32 bits.
208
+ * Don't expose NS_EL2_VIRT timer IRQ in DTB on ACPI on 8.2 and
209
+ * earlier machines. (Exposing it tickles a bug in older EDK2
210
+ * guest BIOS binaries.)
76
+ */
211
+ */
77
+ if (requested_pa_size < 32) {
212
+ vmc->no_ns_el2_virt_timer_irq = true;
78
+ requested_pa_size = 32;
213
}
79
+ }
214
DEFINE_VIRT_MACHINE(8, 2)
80
+
81
if (requested_pa_size > max_vm_pa_size) {
82
error_report("-m and ,maxmem option values "
83
"require an IPA range (%d bits) larger than "
84
"the one supported by the host (%d bits)",
85
requested_pa_size, max_vm_pa_size);
86
- exit(1);
87
+ exit(1);
88
}
89
/*
90
- * By default we return 0 which corresponds to an implicit legacy
91
- * 40b IPA setting. Otherwise we return the actual requested PA
92
- * logsize
93
+ * We return the requested PA log size, unless KVM only supports
94
+ * the implicit legacy 40b IPA setting, in which case the kvm_type
95
+ * must be 0.
96
*/
97
- return requested_pa_size > 40 ? requested_pa_size : 0;
98
+ return fixed_ipa ? 0 : requested_pa_size;
99
}
100
101
static void virt_machine_class_init(ObjectClass *oc, void *data)
102
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
103
index XXXXXXX..XXXXXXX 100644
104
--- a/target/arm/kvm.c
105
+++ b/target/arm/kvm.c
106
@@ -XXX,XX +XXX,XX @@ bool kvm_arm_pmu_supported(void)
107
return kvm_check_extension(kvm_state, KVM_CAP_ARM_PMU_V3);
108
}
109
110
-int kvm_arm_get_max_vm_ipa_size(MachineState *ms)
111
+int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa)
112
{
113
KVMState *s = KVM_STATE(ms->accelerator);
114
int ret;
115
116
ret = kvm_check_extension(s, KVM_CAP_ARM_VM_IPA_SIZE);
117
+ *fixed_ipa = ret <= 0;
118
+
119
return ret > 0 ? ret : 40;
120
}
121
215
122
--
216
--
123
2.20.1
217
2.34.1
124
125
diff view generated by jsdifflib
1
Since the dest_width is now always 4 because the output surface is
1
Update the virt golden reference files to say that the FACP is ACPI
2
32bpp, we can replace the dest_width state field with a constant.
2
v6.3, and the GTDT table is a revision 3 table with space for the
3
virtual EL2 timer.
4
5
Diffs from iasl:
6
7
@@ -XXX,XX +XXX,XX @@
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 // ........
3
183
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
184
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
185
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
6
Message-id: 20210211141515.8755-6-peter.maydell@linaro.org
186
Message-id: 20240122143537.233498-4-peter.maydell@linaro.org
7
---
187
---
8
hw/display/pxa2xx_lcd.c | 20 +++++++++++---------
188
tests/qtest/bios-tables-test-allowed-diff.h | 2 --
9
1 file changed, 11 insertions(+), 9 deletions(-)
189
tests/data/acpi/virt/FACP | Bin 276 -> 276 bytes
10
190
tests/data/acpi/virt/GTDT | Bin 96 -> 104 bytes
11
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.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
12
index XXXXXXX..XXXXXXX 100644
194
index XXXXXXX..XXXXXXX 100644
13
--- a/hw/display/pxa2xx_lcd.c
195
--- a/tests/qtest/bios-tables-test-allowed-diff.h
14
+++ b/hw/display/pxa2xx_lcd.c
196
+++ b/tests/qtest/bios-tables-test-allowed-diff.h
15
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
197
@@ -1,3 +1 @@
16
#define LDCMD_SOFINT    (1 << 22)
198
/* List of comma-separated changed AML files to ignore */
17
#define LDCMD_PAL    (1 << 26)
199
-"tests/data/acpi/virt/FACP",
18
200
-"tests/data/acpi/virt/GTDT",
19
+/* Size of a pixel in the QEMU UI output surface, in bytes */
201
diff --git a/tests/data/acpi/virt/FACP b/tests/data/acpi/virt/FACP
20
+#define DEST_PIXEL_WIDTH 4
202
index XXXXXXX..XXXXXXX 100644
21
+
203
GIT binary patch
22
#define BITS 32
204
delta 25
23
#include "pxa2xx_template.h"
205
gcmbQjG=+)F&CxkPgpq-PO=u!l<;2F$$vli407<0<)c^nh
24
206
25
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
207
delta 28
26
else if (s->bpp > pxa_lcdc_8bpp)
208
kcmbQjG=+)F&CxkPgpq-PO>`nx<-|!<6Akz$^DuG%0AAS!ssI20
27
src_width *= 2;
209
28
210
diff --git a/tests/data/acpi/virt/GTDT b/tests/data/acpi/virt/GTDT
29
- dest_width = s->xres * s->dest_width;
211
index XXXXXXX..XXXXXXX 100644
30
+ dest_width = s->xres * DEST_PIXEL_WIDTH;
212
GIT binary patch
31
*miny = 0;
213
delta 25
32
if (s->invalidated) {
214
bcmYeu;BpUf3CUn!U|^m+kt>V?$N&QXMtB4L
33
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
215
34
addr, s->yres, src_width);
216
delta 16
35
}
217
Xcmc~u;BpUf2}xjJU|^avkt+-UB60)u
36
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
218
37
- src_width, dest_width, s->dest_width,
38
+ src_width, dest_width, DEST_PIXEL_WIDTH,
39
s->invalidated,
40
fn, s->dma_ch[0].palette, miny, maxy);
41
}
42
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
43
else if (s->bpp > pxa_lcdc_8bpp)
44
src_width *= 2;
45
46
- dest_width = s->yres * s->dest_width;
47
+ dest_width = s->yres * DEST_PIXEL_WIDTH;
48
*miny = 0;
49
if (s->invalidated) {
50
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
51
addr, s->yres, src_width);
52
}
53
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
54
- src_width, s->dest_width, -dest_width,
55
+ src_width, DEST_PIXEL_WIDTH, -dest_width,
56
s->invalidated,
57
fn, s->dma_ch[0].palette,
58
miny, maxy);
59
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
60
src_width *= 2;
61
}
62
63
- dest_width = s->xres * s->dest_width;
64
+ dest_width = s->xres * DEST_PIXEL_WIDTH;
65
*miny = 0;
66
if (s->invalidated) {
67
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
68
addr, s->yres, src_width);
69
}
70
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
71
- src_width, -dest_width, -s->dest_width,
72
+ src_width, -dest_width, -DEST_PIXEL_WIDTH,
73
s->invalidated,
74
fn, s->dma_ch[0].palette, miny, maxy);
75
}
76
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
77
src_width *= 2;
78
}
79
80
- dest_width = s->yres * s->dest_width;
81
+ dest_width = s->yres * DEST_PIXEL_WIDTH;
82
*miny = 0;
83
if (s->invalidated) {
84
framebuffer_update_memory_section(&s->fbsection, s->sysmem,
85
addr, s->yres, src_width);
86
}
87
framebuffer_update_display(surface, &s->fbsection, s->xres, s->yres,
88
- src_width, -s->dest_width, dest_width,
89
+ src_width, -DEST_PIXEL_WIDTH, dest_width,
90
s->invalidated,
91
fn, s->dma_ch[0].palette,
92
miny, maxy);
93
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
94
memory_region_add_subregion(sysmem, base, &s->iomem);
95
96
s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
97
- s->dest_width = 4;
98
99
vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
100
101
--
219
--
102
2.20.1
220
2.34.1
103
104
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
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
This patch adds the recently implemented MFT device to the NPCM7XX
7
Add the missing call.
4
SoC file.
5
8
6
Reviewed-by: Doug Evans <dje@google.com>
9
Fixes: 21e5326a7c ("hw/arm: Add GMAC devices to NPCM7XX SoC")
7
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
8
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
Message-id: 20210311180855.149764-4-wuhaotsh@google.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
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
12
---
13
---
13
docs/system/arm/nuvoton.rst | 2 +-
14
hw/arm/npcm7xx.c | 1 +
14
include/hw/arm/npcm7xx.h | 2 ++
15
1 file changed, 1 insertion(+)
15
hw/arm/npcm7xx.c | 45 ++++++++++++++++++++++++++++++-------
16
3 files changed, 40 insertions(+), 9 deletions(-)
17
16
18
diff --git a/docs/system/arm/nuvoton.rst b/docs/system/arm/nuvoton.rst
19
index XXXXXXX..XXXXXXX 100644
20
--- a/docs/system/arm/nuvoton.rst
21
+++ b/docs/system/arm/nuvoton.rst
22
@@ -XXX,XX +XXX,XX @@ Supported devices
23
* Pulse Width Modulation (PWM)
24
* SMBus controller (SMBF)
25
* Ethernet controller (EMC)
26
+ * Tachometer
27
28
Missing devices
29
---------------
30
@@ -XXX,XX +XXX,XX @@ Missing devices
31
* Peripheral SPI controller (PSPI)
32
* SD/MMC host
33
* PECI interface
34
- * Tachometer
35
* PCI and PCIe root complex and bridges
36
* VDM and MCTP support
37
* Serial I/O expansion
38
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/arm/npcm7xx.h
41
+++ b/include/hw/arm/npcm7xx.h
42
@@ -XXX,XX +XXX,XX @@
43
#include "hw/mem/npcm7xx_mc.h"
44
#include "hw/misc/npcm7xx_clk.h"
45
#include "hw/misc/npcm7xx_gcr.h"
46
+#include "hw/misc/npcm7xx_mft.h"
47
#include "hw/misc/npcm7xx_pwm.h"
48
#include "hw/misc/npcm7xx_rng.h"
49
#include "hw/net/npcm7xx_emc.h"
50
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
51
NPCM7xxTimerCtrlState tim[3];
52
NPCM7xxADCState adc;
53
NPCM7xxPWMState pwm[2];
54
+ NPCM7xxMFTState mft[8];
55
NPCM7xxOTPState key_storage;
56
NPCM7xxOTPState fuse_array;
57
NPCM7xxMCState mc;
58
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
17
diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c
59
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
60
--- a/hw/arm/npcm7xx.c
19
--- a/hw/arm/npcm7xx.c
61
+++ b/hw/arm/npcm7xx.c
20
+++ b/hw/arm/npcm7xx.c
62
@@ -XXX,XX +XXX,XX @@ enum NPCM7xxInterrupt {
63
NPCM7XX_SMBUS15_IRQ,
64
NPCM7XX_PWM0_IRQ = 93, /* PWM module 0 */
65
NPCM7XX_PWM1_IRQ, /* PWM module 1 */
66
+ NPCM7XX_MFT0_IRQ = 96, /* MFT module 0 */
67
+ NPCM7XX_MFT1_IRQ, /* MFT module 1 */
68
+ NPCM7XX_MFT2_IRQ, /* MFT module 2 */
69
+ NPCM7XX_MFT3_IRQ, /* MFT module 3 */
70
+ NPCM7XX_MFT4_IRQ, /* MFT module 4 */
71
+ NPCM7XX_MFT5_IRQ, /* MFT module 5 */
72
+ NPCM7XX_MFT6_IRQ, /* MFT module 6 */
73
+ NPCM7XX_MFT7_IRQ, /* MFT module 7 */
74
NPCM7XX_EMC2RX_IRQ = 114,
75
NPCM7XX_EMC2TX_IRQ,
76
NPCM7XX_GPIO0_IRQ = 116,
77
@@ -XXX,XX +XXX,XX @@ static const hwaddr npcm7xx_pwm_addr[] = {
78
0xf0104000,
79
};
80
81
+/* Register base address for each MFT Module */
82
+static const hwaddr npcm7xx_mft_addr[] = {
83
+ 0xf0180000,
84
+ 0xf0181000,
85
+ 0xf0182000,
86
+ 0xf0183000,
87
+ 0xf0184000,
88
+ 0xf0185000,
89
+ 0xf0186000,
90
+ 0xf0187000,
91
+};
92
+
93
/* Direct memory-mapped access to each SMBus Module. */
94
static const hwaddr npcm7xx_smbus_addr[] = {
95
0xf0080000,
96
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_init(Object *obj)
97
object_initialize_child(obj, "pwm[*]", &s->pwm[i], TYPE_NPCM7XX_PWM);
98
}
99
100
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
101
+ object_initialize_child(obj, "mft[*]", &s->mft[i], TYPE_NPCM7XX_MFT);
102
+ }
103
+
104
for (i = 0; i < ARRAY_SIZE(s->emc); i++) {
105
object_initialize_child(obj, "emc[*]", &s->emc[i], TYPE_NPCM7XX_EMC);
106
}
107
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
21
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
108
sysbus_connect_irq(sbd, i, npcm7xx_irq(s, NPCM7XX_PWM0_IRQ + i));
22
for (i = 0; i < ARRAY_SIZE(s->gmac); i++) {
109
}
23
SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]);
110
24
111
+ /* MFT Modules. Cannot fail. */
25
+ qemu_configure_nic_device(DEVICE(sbd), false, NULL);
112
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm7xx_mft_addr) != ARRAY_SIZE(s->mft));
26
/*
113
+ for (i = 0; i < ARRAY_SIZE(s->mft); i++) {
27
* The device exists regardless of whether it's connected to a QEMU
114
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->mft[i]);
28
* netdev backend. So always instantiate it even if there is no
115
+
116
+ qdev_connect_clock_in(DEVICE(&s->mft[i]), "clock-in",
117
+ qdev_get_clock_out(DEVICE(&s->clk),
118
+ "apb4-clock"));
119
+ sysbus_realize(sbd, &error_abort);
120
+ sysbus_mmio_map(sbd, 0, npcm7xx_mft_addr[i]);
121
+ sysbus_connect_irq(sbd, 0, npcm7xx_irq(s, NPCM7XX_MFT0_IRQ + i));
122
+ }
123
+
124
/*
125
* EMC Modules. Cannot fail.
126
* The mapping of the device to its netdev backend works as follows:
127
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_realize(DeviceState *dev, Error **errp)
128
create_unimplemented_device("npcm7xx.peci", 0xf0100000, 4 * KiB);
129
create_unimplemented_device("npcm7xx.siox[1]", 0xf0101000, 4 * KiB);
130
create_unimplemented_device("npcm7xx.siox[2]", 0xf0102000, 4 * KiB);
131
- create_unimplemented_device("npcm7xx.mft[0]", 0xf0180000, 4 * KiB);
132
- create_unimplemented_device("npcm7xx.mft[1]", 0xf0181000, 4 * KiB);
133
- create_unimplemented_device("npcm7xx.mft[2]", 0xf0182000, 4 * KiB);
134
- create_unimplemented_device("npcm7xx.mft[3]", 0xf0183000, 4 * KiB);
135
- create_unimplemented_device("npcm7xx.mft[4]", 0xf0184000, 4 * KiB);
136
- create_unimplemented_device("npcm7xx.mft[5]", 0xf0185000, 4 * KiB);
137
- create_unimplemented_device("npcm7xx.mft[6]", 0xf0186000, 4 * KiB);
138
- create_unimplemented_device("npcm7xx.mft[7]", 0xf0187000, 4 * KiB);
139
create_unimplemented_device("npcm7xx.pspi1", 0xf0200000, 4 * KiB);
140
create_unimplemented_device("npcm7xx.pspi2", 0xf0201000, 4 * KiB);
141
create_unimplemented_device("npcm7xx.ahbpci", 0xf0400000, 1 * MiB);
142
--
29
--
143
2.20.1
30
2.34.1
144
145
diff view generated by jsdifflib
1
BITS is always 32, so remove all uses of it from the template header,
1
Currently QEMU will warn if there is a NIC on the board that
2
by dropping the trailing '32' from the draw function names and
2
is not connected to a backend. By default the '-nic user' will
3
not constructing the name of rgb_to_pixel32() via the glue() macro.
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:
6
7
qemu-system-arm: warning: nic npcm7xx-emc.1 has no peer
8
qemu-system-arm: warning: nic npcm-gmac.0 has no peer
9
qemu-system-arm: warning: nic npcm-gmac.1 has no peer
10
11
So suppress those warnings by manually connecting every NIC
12
on the board to some backend.
4
13
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
15
Reviewed-by: David Woodhouse <dwmw@amazon.co.uk>
7
Message-id: 20210211141515.8755-4-peter.maydell@linaro.org
16
Reviewed-by: Thomas Huth <thuth@redhat.com>
17
Message-id: 20240206171231.396392-3-peter.maydell@linaro.org
8
---
18
---
9
hw/display/pl110_template.h | 20 +++----
19
tests/qtest/npcm7xx_emc-test.c | 5 ++++-
10
hw/display/pl110.c | 113 ++++++++++++++++++------------------
20
1 file changed, 4 insertions(+), 1 deletion(-)
11
2 files changed, 65 insertions(+), 68 deletions(-)
12
21
13
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
22
diff --git a/tests/qtest/npcm7xx_emc-test.c b/tests/qtest/npcm7xx_emc-test.c
14
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/pl110_template.h
24
--- a/tests/qtest/npcm7xx_emc-test.c
16
+++ b/hw/display/pl110_template.h
25
+++ b/tests/qtest/npcm7xx_emc-test.c
17
@@ -XXX,XX +XXX,XX @@
26
@@ -XXX,XX +XXX,XX @@ static int *packet_test_init(int module_num, GString *cmd_line)
18
#endif
27
* KISS and use -nic. The driver accepts 'emc0' and 'emc1' as aliases
19
28
* in the 'model' field to specify the device to match.
20
#if ORDER == 0
29
*/
21
-#define NAME glue(glue(lblp_, BORDER), BITS)
30
- g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d ",
22
+#define NAME glue(lblp_, BORDER)
31
+ g_string_append_printf(cmd_line, " -nic socket,fd=%d,model=emc%d "
23
#ifdef HOST_WORDS_BIGENDIAN
32
+ "-nic user,model=npcm7xx-emc "
24
#define SWAP_WORDS 1
33
+ "-nic user,model=npcm-gmac "
25
#endif
34
+ "-nic user,model=npcm-gmac",
26
#elif ORDER == 1
35
test_sockets[1], module_num);
27
-#define NAME glue(glue(bbbp_, BORDER), BITS)
36
28
+#define NAME glue(bbbp_, BORDER)
37
g_test_queue_destroy(packet_test_clear, test_sockets);
29
#ifndef HOST_WORDS_BIGENDIAN
30
#define SWAP_WORDS 1
31
#endif
32
#else
33
#define SWAP_PIXELS 1
34
-#define NAME glue(glue(lbbp_, BORDER), BITS)
35
+#define NAME glue(lbbp_, BORDER)
36
#ifdef HOST_WORDS_BIGENDIAN
37
#define SWAP_WORDS 1
38
#endif
39
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line16_,NAME)(void *opaque, uint8_t *d, const uint8_
40
MSB = (data & 0x1f) << 3;
41
data >>= 5;
42
#endif
43
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
44
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
45
LSB = (data & 0x1f) << 3;
46
data >>= 5;
47
g = (data & 0x3f) << 2;
48
data >>= 6;
49
MSB = (data & 0x1f) << 3;
50
data >>= 5;
51
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
52
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
53
#undef MSB
54
#undef LSB
55
width -= 2;
56
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line32_,NAME)(void *opaque, uint8_t *d, const uint8_
57
g = (data >> 16) & 0xff;
58
MSB = (data >> 8) & 0xff;
59
#endif
60
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
61
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
62
#undef MSB
63
#undef LSB
64
width--;
65
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line16_555_,NAME)(void *opaque, uint8_t *d, const ui
66
data >>= 5;
67
MSB = (data & 0x1f) << 3;
68
data >>= 5;
69
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
70
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
71
LSB = (data & 0x1f) << 3;
72
data >>= 5;
73
g = (data & 0x1f) << 3;
74
data >>= 5;
75
MSB = (data & 0x1f) << 3;
76
data >>= 6;
77
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
78
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
79
#undef MSB
80
#undef LSB
81
width -= 2;
82
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_
83
data >>= 4;
84
MSB = (data & 0xf) << 4;
85
data >>= 8;
86
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
87
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
88
LSB = (data & 0xf) << 4;
89
data >>= 4;
90
g = (data & 0xf) << 4;
91
data >>= 4;
92
MSB = (data & 0xf) << 4;
93
data >>= 8;
94
- COPY_PIXEL(d, glue(rgb_to_pixel,BITS)(r, g, b));
95
+ COPY_PIXEL(d, rgb_to_pixel32(r, g, b));
96
#undef MSB
97
#undef LSB
98
width -= 2;
99
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
100
index XXXXXXX..XXXXXXX 100644
101
--- a/hw/display/pl110.c
102
+++ b/hw/display/pl110.c
103
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
104
pl111_id
105
};
106
107
-#define BITS 32
108
#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
109
110
#undef RGB
111
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
112
#include "pl110_template.h"
113
#undef BORDER
114
115
-static drawfn pl110_draw_fn_32[48] = {
116
- pl110_draw_line1_lblp_bgr32,
117
- pl110_draw_line2_lblp_bgr32,
118
- pl110_draw_line4_lblp_bgr32,
119
- pl110_draw_line8_lblp_bgr32,
120
- pl110_draw_line16_555_lblp_bgr32,
121
- pl110_draw_line32_lblp_bgr32,
122
- pl110_draw_line16_lblp_bgr32,
123
- pl110_draw_line12_lblp_bgr32,
124
-
125
- pl110_draw_line1_bbbp_bgr32,
126
- pl110_draw_line2_bbbp_bgr32,
127
- pl110_draw_line4_bbbp_bgr32,
128
- pl110_draw_line8_bbbp_bgr32,
129
- pl110_draw_line16_555_bbbp_bgr32,
130
- pl110_draw_line32_bbbp_bgr32,
131
- pl110_draw_line16_bbbp_bgr32,
132
- pl110_draw_line12_bbbp_bgr32,
133
-
134
- pl110_draw_line1_lbbp_bgr32,
135
- pl110_draw_line2_lbbp_bgr32,
136
- pl110_draw_line4_lbbp_bgr32,
137
- pl110_draw_line8_lbbp_bgr32,
138
- pl110_draw_line16_555_lbbp_bgr32,
139
- pl110_draw_line32_lbbp_bgr32,
140
- pl110_draw_line16_lbbp_bgr32,
141
- pl110_draw_line12_lbbp_bgr32,
142
-
143
- pl110_draw_line1_lblp_rgb32,
144
- pl110_draw_line2_lblp_rgb32,
145
- pl110_draw_line4_lblp_rgb32,
146
- pl110_draw_line8_lblp_rgb32,
147
- pl110_draw_line16_555_lblp_rgb32,
148
- pl110_draw_line32_lblp_rgb32,
149
- pl110_draw_line16_lblp_rgb32,
150
- pl110_draw_line12_lblp_rgb32,
151
-
152
- pl110_draw_line1_bbbp_rgb32,
153
- pl110_draw_line2_bbbp_rgb32,
154
- pl110_draw_line4_bbbp_rgb32,
155
- pl110_draw_line8_bbbp_rgb32,
156
- pl110_draw_line16_555_bbbp_rgb32,
157
- pl110_draw_line32_bbbp_rgb32,
158
- pl110_draw_line16_bbbp_rgb32,
159
- pl110_draw_line12_bbbp_rgb32,
160
-
161
- pl110_draw_line1_lbbp_rgb32,
162
- pl110_draw_line2_lbbp_rgb32,
163
- pl110_draw_line4_lbbp_rgb32,
164
- pl110_draw_line8_lbbp_rgb32,
165
- pl110_draw_line16_555_lbbp_rgb32,
166
- pl110_draw_line32_lbbp_rgb32,
167
- pl110_draw_line16_lbbp_rgb32,
168
- pl110_draw_line12_lbbp_rgb32,
169
-};
170
-
171
-#undef BITS
172
#undef COPY_PIXEL
173
174
+static drawfn pl110_draw_fn_32[48] = {
175
+ pl110_draw_line1_lblp_bgr,
176
+ pl110_draw_line2_lblp_bgr,
177
+ pl110_draw_line4_lblp_bgr,
178
+ pl110_draw_line8_lblp_bgr,
179
+ pl110_draw_line16_555_lblp_bgr,
180
+ pl110_draw_line32_lblp_bgr,
181
+ pl110_draw_line16_lblp_bgr,
182
+ pl110_draw_line12_lblp_bgr,
183
+
184
+ pl110_draw_line1_bbbp_bgr,
185
+ pl110_draw_line2_bbbp_bgr,
186
+ pl110_draw_line4_bbbp_bgr,
187
+ pl110_draw_line8_bbbp_bgr,
188
+ pl110_draw_line16_555_bbbp_bgr,
189
+ pl110_draw_line32_bbbp_bgr,
190
+ pl110_draw_line16_bbbp_bgr,
191
+ pl110_draw_line12_bbbp_bgr,
192
+
193
+ pl110_draw_line1_lbbp_bgr,
194
+ pl110_draw_line2_lbbp_bgr,
195
+ pl110_draw_line4_lbbp_bgr,
196
+ pl110_draw_line8_lbbp_bgr,
197
+ pl110_draw_line16_555_lbbp_bgr,
198
+ pl110_draw_line32_lbbp_bgr,
199
+ pl110_draw_line16_lbbp_bgr,
200
+ pl110_draw_line12_lbbp_bgr,
201
+
202
+ pl110_draw_line1_lblp_rgb,
203
+ pl110_draw_line2_lblp_rgb,
204
+ pl110_draw_line4_lblp_rgb,
205
+ pl110_draw_line8_lblp_rgb,
206
+ pl110_draw_line16_555_lblp_rgb,
207
+ pl110_draw_line32_lblp_rgb,
208
+ pl110_draw_line16_lblp_rgb,
209
+ pl110_draw_line12_lblp_rgb,
210
+
211
+ pl110_draw_line1_bbbp_rgb,
212
+ pl110_draw_line2_bbbp_rgb,
213
+ pl110_draw_line4_bbbp_rgb,
214
+ pl110_draw_line8_bbbp_rgb,
215
+ pl110_draw_line16_555_bbbp_rgb,
216
+ pl110_draw_line32_bbbp_rgb,
217
+ pl110_draw_line16_bbbp_rgb,
218
+ pl110_draw_line12_bbbp_rgb,
219
+
220
+ pl110_draw_line1_lbbp_rgb,
221
+ pl110_draw_line2_lbbp_rgb,
222
+ pl110_draw_line4_lbbp_rgb,
223
+ pl110_draw_line8_lbbp_rgb,
224
+ pl110_draw_line16_555_lbbp_rgb,
225
+ pl110_draw_line32_lbbp_rgb,
226
+ pl110_draw_line16_lbbp_rgb,
227
+ pl110_draw_line12_lbbp_rgb,
228
+};
229
230
static int pl110_enabled(PL110State *s)
231
{
232
--
38
--
233
2.20.1
39
2.34.1
234
235
diff view generated by jsdifflib
1
From: Andrew Jones <drjones@redhat.com>
1
It doesn't make sense to read the value of MDCR_EL2 on a non-A-profile
2
CPU, and in fact if you try to do it we will assert:
2
3
3
Prior to commit f2ce39b4f067 a MachineClass kvm_type method
4
#6 0x00007ffff4b95e96 in __GI___assert_fail
4
only needed to be registered to ensure it would be executed.
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
5
With commit f2ce39b4f067 a kvm-type machine property must also
6
#7 0x0000555555ebf412 in arm_security_space_below_el3 (env=0x555557bc8190) at ../../target/arm/helper.c:12600
6
be specified. hw/arm/virt relies on the kvm_type method to pass
7
#8 0x0000555555ea6f89 in arm_is_el2_enabled (env=0x555557bc8190) at ../../target/arm/cpu.h:2595
7
its selected IPA limit to KVM, but this is not exposed as a
8
#9 0x0000555555ea942f in arm_mdcr_el2_eff (env=0x555557bc8190) at ../../target/arm/internals.h:1512
8
machine property. Restore the previous functionality of invoking
9
kvm_type when it's present.
10
9
11
Fixes: f2ce39b4f067 ("vl: make qemu_get_machine_opts static")
10
We might call pmu_counter_enabled() on an M-profile CPU (for example
12
Signed-off-by: Andrew Jones <drjones@redhat.com>
11
from the migration pre/post hooks in machine.c); this should always
13
Reviewed-by: Eric Auger <eric.auger@redhat.com>
12
return false because these CPUs don't set ARM_FEATURE_PMU.
14
Message-id: 20210310135218.255205-2-drjones@redhat.com
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
15
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>
24
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
25
Message-id: 20240208153346.970021-1-peter.maydell@linaro.org
16
---
26
---
17
include/hw/boards.h | 1 +
27
target/arm/helper.c | 12 ++++++++++--
18
accel/kvm/kvm-all.c | 2 ++
28
1 file changed, 10 insertions(+), 2 deletions(-)
19
2 files changed, 3 insertions(+)
20
29
21
diff --git a/include/hw/boards.h b/include/hw/boards.h
30
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/boards.h
32
--- a/target/arm/helper.c
24
+++ b/include/hw/boards.h
33
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct {
34
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
26
* @kvm_type:
35
bool enabled, prohibited = false, filtered;
27
* Return the type of KVM corresponding to the kvm-type string option or
36
bool secure = arm_is_secure(env);
28
* computed based on other criteria such as the host kernel capabilities.
37
int el = arm_current_el(env);
29
+ * kvm-type may be NULL if it is not needed.
38
- uint64_t mdcr_el2 = arm_mdcr_el2_eff(env);
30
* @numa_mem_supported:
39
- uint8_t hpmn = mdcr_el2 & MDCR_HPMN;
31
* true if '--numa node.mem' option is supported and false otherwise
40
+ uint64_t mdcr_el2;
32
* @smp_parse:
41
+ uint8_t hpmn;
33
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
42
34
index XXXXXXX..XXXXXXX 100644
43
+ /*
35
--- a/accel/kvm/kvm-all.c
44
+ * We might be called for M-profile cores where MDCR_EL2 doesn't
36
+++ b/accel/kvm/kvm-all.c
45
+ * exist and arm_mdcr_el2_eff() will assert, so this early-exit check
37
@@ -XXX,XX +XXX,XX @@ static int kvm_init(MachineState *ms)
46
+ * must be before we read that value.
38
"kvm-type",
47
+ */
39
&error_abort);
48
if (!arm_feature(env, ARM_FEATURE_PMU)) {
40
type = mc->kvm_type(ms, kvm_type);
49
return false;
41
+ } else if (mc->kvm_type) {
42
+ type = mc->kvm_type(ms, NULL);
43
}
50
}
44
51
45
do {
52
+ mdcr_el2 = arm_mdcr_el2_eff(env);
53
+ hpmn = mdcr_el2 & MDCR_HPMN;
54
+
55
if (!arm_feature(env, ARM_FEATURE_EL2) ||
56
(counter < hpmn || counter == 31)) {
57
e = env->cp15.c9_pmcr & PMCRE;
46
--
58
--
47
2.20.1
59
2.34.1
48
60
49
61
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Nabih Estefan <nabihestefan@google.com>
2
2
3
This patch adds testing of PWM fan RPMs in the existing npcm7xx pwm
3
Fix the nocm_gmac-test.c file to run on a nuvoton 7xx machine instead
4
test. It tests whether the MFT module can measure correct fan values
4
of 8xx. Also fix comments referencing this and values expecting 8xx.
5
for a PWM fan in NPCM7XX boards.
6
5
7
Reviewed-by: Doug Evans <dje@google.com>
6
Change-Id: Iabd0fba14910c3f1e883c4a9521350f3db9ffab8
7
Signed-Off-By: Nabih Estefan <nabihestefan@google.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
8
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
9
Signed-off-by: Hao Wu <wuhaotsh@google.com>
9
Message-id: 20240208194759.2858582-2-nabihestefan@google.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20210311180855.149764-6-wuhaotsh@google.com
11
[PMM: commit message tweaks]
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
tests/qtest/npcm7xx_pwm-test.c | 205 ++++++++++++++++++++++++++++++++-
14
tests/qtest/npcm_gmac-test.c | 84 +-----------------------------------
15
1 file changed, 199 insertions(+), 6 deletions(-)
15
tests/qtest/meson.build | 3 +-
16
2 files changed, 4 insertions(+), 83 deletions(-)
16
17
17
diff --git a/tests/qtest/npcm7xx_pwm-test.c b/tests/qtest/npcm7xx_pwm-test.c
18
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
18
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/qtest/npcm7xx_pwm-test.c
20
--- a/tests/qtest/npcm_gmac-test.c
20
+++ b/tests/qtest/npcm7xx_pwm-test.c
21
+++ b/tests/qtest/npcm_gmac-test.c
21
@@ -XXX,XX +XXX,XX @@
22
@@ -XXX,XX +XXX,XX @@ typedef struct TestData {
22
#define PLL_FBDV(rv) extract32((rv), 16, 12)
23
const GMACModule *module;
23
#define PLL_OTDV1(rv) extract32((rv), 8, 3)
24
} TestData;
24
#define PLL_OTDV2(rv) extract32((rv), 13, 3)
25
25
+#define APB4CKDIV(rv) extract32((rv), 30, 2)
26
-/* Values extracted from hw/arm/npcm8xx.c */
26
#define APB3CKDIV(rv) extract32((rv), 28, 2)
27
+/* Values extracted from hw/arm/npcm7xx.c */
27
#define CLK2CKDIV(rv) extract32((rv), 0, 1)
28
static const GMACModule gmac_module_list[] = {
28
#define CLK4CKDIV(rv) extract32((rv), 26, 2)
29
{
29
@@ -XXX,XX +XXX,XX @@
30
.irq = 14,
30
31
@@ -XXX,XX +XXX,XX @@ static const GMACModule gmac_module_list[] = {
31
#define MAX_DUTY 1000000
32
.irq = 15,
32
33
.base_addr = 0xf0804000
33
+/* MFT (PWM fan) related */
34
},
34
+#define MFT_BA(n) (0xf0180000 + ((n) * 0x1000))
35
- {
35
+#define MFT_IRQ(n) (96 + (n))
36
- .irq = 16,
36
+#define MFT_CNT1 0x00
37
- .base_addr = 0xf0806000
37
+#define MFT_CRA 0x02
38
- },
38
+#define MFT_CRB 0x04
39
- {
39
+#define MFT_CNT2 0x06
40
- .irq = 17,
40
+#define MFT_PRSC 0x08
41
- .base_addr = 0xf0808000
41
+#define MFT_CKC 0x0a
42
- }
42
+#define MFT_MCTRL 0x0c
43
};
43
+#define MFT_ICTRL 0x0e
44
44
+#define MFT_ICLR 0x10
45
/* Returns the index of the GMAC module. */
45
+#define MFT_IEN 0x12
46
@@ -XXX,XX +XXX,XX @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
46
+#define MFT_CPA 0x14
47
return qtest_readl(qts, mod->base_addr + regno);
47
+#define MFT_CPB 0x16
48
+#define MFT_CPCFG 0x18
49
+#define MFT_INASEL 0x1a
50
+#define MFT_INBSEL 0x1c
51
+
52
+#define MFT_MCTRL_ALL 0x64
53
+#define MFT_ICLR_ALL 0x3f
54
+#define MFT_IEN_ALL 0x3f
55
+#define MFT_CPCFG_EQ_MODE 0x44
56
+
57
+#define MFT_CKC_C2CSEL BIT(3)
58
+#define MFT_CKC_C1CSEL BIT(0)
59
+
60
+#define MFT_ICTRL_TFPND BIT(5)
61
+#define MFT_ICTRL_TEPND BIT(4)
62
+#define MFT_ICTRL_TDPND BIT(3)
63
+#define MFT_ICTRL_TCPND BIT(2)
64
+#define MFT_ICTRL_TBPND BIT(1)
65
+#define MFT_ICTRL_TAPND BIT(0)
66
+
67
+#define MFT_MAX_CNT 0xffff
68
+#define MFT_TIMEOUT 0x5000
69
+
70
+#define DEFAULT_RPM 19800
71
+#define DEFAULT_PRSC 255
72
+#define MFT_PULSE_PER_REVOLUTION 2
73
+
74
+#define MAX_ERROR 1
75
+
76
typedef struct PWMModule {
77
int irq;
78
uint64_t base_addr;
79
@@ -XXX,XX +XXX,XX @@ static uint64_t pwm_get_duty(QTestState *qts, int module_index, int pwm_index)
80
return pwm_qom_get(qts, path, name);
81
}
48
}
82
49
83
+static void mft_qom_set(QTestState *qts, int index, const char *name,
50
-static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
84
+ uint32_t value)
51
- NPCMRegister regno)
85
+{
52
-{
86
+ QDict *response;
53
- uint32_t write_value = (regno & 0x3ffe00) >> 9;
87
+ char *path = g_strdup_printf("/machine/soc/mft[%d]", index);
54
- qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
88
+
55
- uint32_t read_offset = regno & 0x1ff;
89
+ g_test_message("Setting properties %s of mft[%d] with value %u",
56
- return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
90
+ name, index, value);
57
-}
91
+ response = qtest_qmp(qts, "{ 'execute': 'qom-set',"
58
-
92
+ " 'arguments': { 'path': %s, "
59
/* Check that GMAC registers are reset to default value */
93
+ " 'property': %s, 'value': %u}}",
94
+ path, name, value);
95
+ /* The qom set message returns successfully. */
96
+ g_assert_true(qdict_haskey(response, "return"));
97
+}
98
+
99
static uint32_t get_pll(uint32_t con)
100
{
101
return REF_HZ * PLL_FBDV(con) / (PLL_INDV(con) * PLL_OTDV1(con)
102
* PLL_OTDV2(con));
103
}
104
105
-static uint64_t read_pclk(QTestState *qts)
106
+static uint64_t read_pclk(QTestState *qts, bool mft)
107
{
108
uint64_t freq = REF_HZ;
109
uint32_t clksel = qtest_readl(qts, CLK_BA + CLKSEL);
110
uint32_t pllcon;
111
uint32_t clkdiv1 = qtest_readl(qts, CLK_BA + CLKDIV1);
112
uint32_t clkdiv2 = qtest_readl(qts, CLK_BA + CLKDIV2);
113
+ uint32_t apbdiv = mft ? APB4CKDIV(clkdiv2) : APB3CKDIV(clkdiv2);
114
115
switch (CPUCKSEL(clksel)) {
116
case 0:
117
@@ -XXX,XX +XXX,XX @@ static uint64_t read_pclk(QTestState *qts)
118
g_assert_not_reached();
119
}
120
121
- freq >>= (CLK2CKDIV(clkdiv1) + CLK4CKDIV(clkdiv1) + APB3CKDIV(clkdiv2));
122
+ freq >>= (CLK2CKDIV(clkdiv1) + CLK4CKDIV(clkdiv1) + apbdiv);
123
124
return freq;
125
}
126
@@ -XXX,XX +XXX,XX @@ static uint32_t pwm_selector(uint32_t csr)
127
static uint64_t pwm_compute_freq(QTestState *qts, uint32_t ppr, uint32_t csr,
128
uint32_t cnr)
129
{
130
- return read_pclk(qts) / ((ppr + 1) * pwm_selector(csr) * (cnr + 1));
131
+ return read_pclk(qts, false) / ((ppr + 1) * pwm_selector(csr) * (cnr + 1));
132
}
133
134
static uint64_t pwm_compute_duty(uint32_t cnr, uint32_t cmr, bool inverted)
135
@@ -XXX,XX +XXX,XX @@ static void pwm_write(QTestState *qts, const TestData *td, unsigned offset,
136
qtest_writel(qts, td->module->base_addr + offset, value);
137
}
138
139
+static uint8_t mft_readb(QTestState *qts, int index, unsigned offset)
140
+{
141
+ return qtest_readb(qts, MFT_BA(index) + offset);
142
+}
143
+
144
+static uint16_t mft_readw(QTestState *qts, int index, unsigned offset)
145
+{
146
+ return qtest_readw(qts, MFT_BA(index) + offset);
147
+}
148
+
149
+static void mft_writeb(QTestState *qts, int index, unsigned offset,
150
+ uint8_t value)
151
+{
152
+ qtest_writeb(qts, MFT_BA(index) + offset, value);
153
+}
154
+
155
+static void mft_writew(QTestState *qts, int index, unsigned offset,
156
+ uint16_t value)
157
+{
158
+ return qtest_writew(qts, MFT_BA(index) + offset, value);
159
+}
160
+
161
static uint32_t pwm_read_ppr(QTestState *qts, const TestData *td)
162
{
163
return extract32(pwm_read(qts, td, PPR), ppr_base[pwm_index(td->pwm)], 8);
164
@@ -XXX,XX +XXX,XX @@ static void pwm_write_cmr(QTestState *qts, const TestData *td, uint32_t value)
165
pwm_write(qts, td, td->pwm->cmr_offset, value);
166
}
167
168
+static int mft_compute_index(const TestData *td)
169
+{
170
+ int index = pwm_module_index(td->module) * ARRAY_SIZE(pwm_list) +
171
+ pwm_index(td->pwm);
172
+
173
+ g_assert_cmpint(index, <,
174
+ ARRAY_SIZE(pwm_module_list) * ARRAY_SIZE(pwm_list));
175
+
176
+ return index;
177
+}
178
+
179
+static void mft_reset_counters(QTestState *qts, int index)
180
+{
181
+ mft_writew(qts, index, MFT_CNT1, MFT_MAX_CNT);
182
+ mft_writew(qts, index, MFT_CNT2, MFT_MAX_CNT);
183
+ mft_writew(qts, index, MFT_CRA, MFT_MAX_CNT);
184
+ mft_writew(qts, index, MFT_CRB, MFT_MAX_CNT);
185
+ mft_writew(qts, index, MFT_CPA, MFT_MAX_CNT - MFT_TIMEOUT);
186
+ mft_writew(qts, index, MFT_CPB, MFT_MAX_CNT - MFT_TIMEOUT);
187
+}
188
+
189
+static void mft_init(QTestState *qts, const TestData *td)
190
+{
191
+ int index = mft_compute_index(td);
192
+
193
+ /* Enable everything */
194
+ mft_writeb(qts, index, MFT_CKC, 0);
195
+ mft_writeb(qts, index, MFT_ICLR, MFT_ICLR_ALL);
196
+ mft_writeb(qts, index, MFT_MCTRL, MFT_MCTRL_ALL);
197
+ mft_writeb(qts, index, MFT_IEN, MFT_IEN_ALL);
198
+ mft_writeb(qts, index, MFT_INASEL, 0);
199
+ mft_writeb(qts, index, MFT_INBSEL, 0);
200
+
201
+ /* Set cpcfg to use EQ mode, same as kernel driver */
202
+ mft_writeb(qts, index, MFT_CPCFG, MFT_CPCFG_EQ_MODE);
203
+
204
+ /* Write default counters, timeout and prescaler */
205
+ mft_reset_counters(qts, index);
206
+ mft_writeb(qts, index, MFT_PRSC, DEFAULT_PRSC);
207
+
208
+ /* Write default max rpm via QMP */
209
+ mft_qom_set(qts, index, "max_rpm[0]", DEFAULT_RPM);
210
+ mft_qom_set(qts, index, "max_rpm[1]", DEFAULT_RPM);
211
+}
212
+
213
+static int32_t mft_compute_cnt(uint32_t rpm, uint64_t clk)
214
+{
215
+ uint64_t cnt;
216
+
217
+ if (rpm == 0) {
218
+ return -1;
219
+ }
220
+
221
+ cnt = clk * 60 / ((DEFAULT_PRSC + 1) * rpm * MFT_PULSE_PER_REVOLUTION);
222
+ if (cnt >= MFT_TIMEOUT) {
223
+ return -1;
224
+ }
225
+ return MFT_MAX_CNT - cnt;
226
+}
227
+
228
+static void mft_verify_rpm(QTestState *qts, const TestData *td, uint64_t duty)
229
+{
230
+ int index = mft_compute_index(td);
231
+ uint16_t cnt, cr;
232
+ uint32_t rpm = DEFAULT_RPM * duty / MAX_DUTY;
233
+ uint64_t clk = read_pclk(qts, true);
234
+ int32_t expected_cnt = mft_compute_cnt(rpm, clk);
235
+
236
+ qtest_irq_intercept_in(qts, "/machine/soc/a9mpcore/gic");
237
+ g_test_message(
238
+ "verifying rpm for mft[%d]: clk: %lu, duty: %lu, rpm: %u, cnt: %d",
239
+ index, clk, duty, rpm, expected_cnt);
240
+
241
+ /* Verify rpm for fan A */
242
+ /* Stop capture */
243
+ mft_writeb(qts, index, MFT_CKC, 0);
244
+ mft_writeb(qts, index, MFT_ICLR, MFT_ICLR_ALL);
245
+ mft_reset_counters(qts, index);
246
+ g_assert_cmphex(mft_readw(qts, index, MFT_CNT1), ==, MFT_MAX_CNT);
247
+ g_assert_cmphex(mft_readw(qts, index, MFT_CRA), ==, MFT_MAX_CNT);
248
+ g_assert_cmphex(mft_readw(qts, index, MFT_CPA), ==,
249
+ MFT_MAX_CNT - MFT_TIMEOUT);
250
+ /* Start capture */
251
+ mft_writeb(qts, index, MFT_CKC, MFT_CKC_C1CSEL);
252
+ g_assert_true(qtest_get_irq(qts, MFT_IRQ(index)));
253
+ if (expected_cnt == -1) {
254
+ g_assert_cmphex(mft_readb(qts, index, MFT_ICTRL), ==, MFT_ICTRL_TEPND);
255
+ } else {
256
+ g_assert_cmphex(mft_readb(qts, index, MFT_ICTRL), ==, MFT_ICTRL_TAPND);
257
+ cnt = mft_readw(qts, index, MFT_CNT1);
258
+ /*
259
+ * Due to error in clock measurement and rounding, we might have a small
260
+ * error in measuring RPM.
261
+ */
262
+ g_assert_cmphex(cnt + MAX_ERROR, >=, expected_cnt);
263
+ g_assert_cmphex(cnt, <=, expected_cnt + MAX_ERROR);
264
+ cr = mft_readw(qts, index, MFT_CRA);
265
+ g_assert_cmphex(cnt, ==, cr);
266
+ }
267
+
268
+ /* Verify rpm for fan B */
269
+
270
+ qtest_irq_intercept_out(qts, "/machine/soc/a9mpcore/gic");
271
+}
272
+
273
/* Check pwm registers can be reset to default value */
274
static void test_init(gconstpointer test_data)
60
static void test_init(gconstpointer test_data)
275
{
61
{
276
const TestData *td = test_data;
62
const TestData *td = test_data;
277
- QTestState *qts = qtest_init("-machine quanta-gsj");
63
const GMACModule *mod = td->module;
64
- QTestState *qts = qtest_init("-machine npcm845-evb");
278
+ QTestState *qts = qtest_init("-machine npcm750-evb");
65
+ QTestState *qts = qtest_init("-machine npcm750-evb");
279
int module = pwm_module_index(td->module);
66
280
int pwm = pwm_index(td->pwm);
67
#define CHECK_REG32(regno, value) \
281
68
do { \
69
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
70
} while (0)
71
72
-#define CHECK_REG_PCS(regno, value) \
73
- do { \
74
- g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
75
- } while (0)
76
-
77
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
78
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
79
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
282
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
80
@@ -XXX,XX +XXX,XX @@ static void test_init(gconstpointer test_data)
283
static void test_oneshot(gconstpointer test_data)
81
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
284
{
82
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
285
const TestData *td = test_data;
83
286
- QTestState *qts = qtest_init("-machine quanta-gsj");
84
- /* TODO Add registers PCS */
287
+ QTestState *qts = qtest_init("-machine npcm750-evb");
85
- if (mod->base_addr == 0xf0802000) {
288
int module = pwm_module_index(td->module);
86
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
289
int pwm = pwm_index(td->pwm);
87
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
290
uint32_t ppr, csr, pcr;
88
- CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
291
@@ -XXX,XX +XXX,XX @@ static void test_oneshot(gconstpointer test_data)
89
-
292
static void test_toggle(gconstpointer test_data)
90
- CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
293
{
91
- CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
294
const TestData *td = test_data;
92
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
295
- QTestState *qts = qtest_init("-machine quanta-gsj");
93
- CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
296
+ QTestState *qts = qtest_init("-machine npcm750-evb");
94
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
297
int module = pwm_module_index(td->module);
95
- CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
298
int pwm = pwm_index(td->pwm);
96
- CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
299
uint32_t ppr, csr, pcr, cnr, cmr;
97
- CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
300
int i, j, k, l;
98
-
301
uint64_t expected_freq, expected_duty;
99
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
302
100
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
303
+ mft_init(qts, td);
101
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
304
+
102
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
305
pcr = CH_EN | CH_MOD;
103
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
306
for (i = 0; i < ARRAY_SIZE(ppr_list); ++i) {
104
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
307
ppr = ppr_list[i];
105
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
308
@@ -XXX,XX +XXX,XX @@ static void test_toggle(gconstpointer test_data)
106
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
309
==, expected_freq);
107
- CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
310
}
108
-
311
109
- CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
312
+ /* Test MFT's RPM is correct. */
110
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
313
+ mft_verify_rpm(qts, td, expected_duty);
111
- CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
314
+
112
- CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
315
/* Test inverted mode */
113
- CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
316
expected_duty = pwm_compute_duty(cnr, cmr, true);
114
- CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
317
pwm_write_pcr(qts, td, pcr | CH_INV);
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);
143
}
144
145
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
146
index XXXXXXX..XXXXXXX 100644
147
--- a/tests/qtest/meson.build
148
+++ b/tests/qtest/meson.build
149
@@ -XXX,XX +XXX,XX @@ qtests_npcm7xx = \
150
'npcm7xx_sdhci-test',
151
'npcm7xx_smbus-test',
152
'npcm7xx_timer-test',
153
- 'npcm7xx_watchdog_timer-test'] + \
154
+ 'npcm7xx_watchdog_timer-test',
155
+ 'npcm_gmac-test'] + \
156
(slirp.found() ? ['npcm7xx_emc-test'] : [])
157
qtests_aspeed = \
158
['aspeed_hace-test',
318
--
159
--
319
2.20.1
160
2.34.1
320
321
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
As of today, the driver can invalidate a number of pages that is
3
An access fault is raised when the Access Flag is not set in the
4
not a power of 2. However IOTLB unmap notifications and internal
4
looked-up PTE and the AFFD field is not set in the corresponding context
5
IOTLB invalidations work with masks leading to erroneous
5
descriptor. This was already implemented for stage 2. Implement it for
6
invalidations.
6
stage 1 as well.
7
7
8
In case the range is not a power of 2, split invalidations into
8
Signed-off-by: Luc Michel <luc.michel@amd.com>
9
power of 2 invalidations.
9
Reviewed-by: Mostafa Saleh <smostafa@google.com>
10
10
Reviewed-by: Eric Auger <eric.auger@redhat.com>
11
When looking for a single page entry in the vSMMU internal IOTLB,
11
Tested-by: Mostafa Saleh <smostafa@google.com>
12
let's make sure that if the entry is not found using a
12
Message-id: 20240213082211.3330400-1-luc.michel@amd.com
13
g_hash_table_remove() we iterate over all the entries to find a
13
[PMM: tweaked comment text]
14
potential range that overlaps it.
15
16
Signed-off-by: Eric Auger <eric.auger@redhat.com>
17
Message-id: 20210309102742.30442-6-eric.auger@redhat.com
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
15
---
21
hw/arm/smmu-common.c | 30 ++++++++++++++++++------------
16
hw/arm/smmuv3-internal.h | 1 +
22
hw/arm/smmuv3.c | 24 ++++++++++++++++++++----
17
include/hw/arm/smmu-common.h | 1 +
23
2 files changed, 38 insertions(+), 16 deletions(-)
18
hw/arm/smmu-common.c | 11 +++++++++++
19
hw/arm/smmuv3.c | 1 +
20
4 files changed, 14 insertions(+)
24
21
22
diff --git a/hw/arm/smmuv3-internal.h b/hw/arm/smmuv3-internal.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/hw/arm/smmuv3-internal.h
25
+++ b/hw/arm/smmuv3-internal.h
26
@@ -XXX,XX +XXX,XX @@ static inline int pa_range(STE *ste)
27
#define CD_EPD(x, sel) extract32((x)->word[0], (16 * (sel)) + 14, 1)
28
#define CD_ENDI(x) extract32((x)->word[0], 15, 1)
29
#define CD_IPS(x) extract32((x)->word[1], 0 , 3)
30
+#define CD_AFFD(x) extract32((x)->word[1], 3 , 1)
31
#define CD_TBI(x) extract32((x)->word[1], 6 , 2)
32
#define CD_HD(x) extract32((x)->word[1], 10 , 1)
33
#define CD_HA(x) extract32((x)->word[1], 11 , 1)
34
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
35
index XXXXXXX..XXXXXXX 100644
36
--- a/include/hw/arm/smmu-common.h
37
+++ b/include/hw/arm/smmu-common.h
38
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUTransCfg {
39
bool disabled; /* smmu is disabled */
40
bool bypassed; /* translation is bypassed */
41
bool aborted; /* translation is aborted */
42
+ bool affd; /* AF fault disable */
43
uint32_t iotlb_hits; /* counts IOTLB hits */
44
uint32_t iotlb_misses; /* counts IOTLB misses*/
45
/* Used by stage-1 only. */
25
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
46
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
26
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
27
--- a/hw/arm/smmu-common.c
48
--- a/hw/arm/smmu-common.c
28
+++ b/hw/arm/smmu-common.c
49
+++ b/hw/arm/smmu-common.c
29
@@ -XXX,XX +XXX,XX @@ inline void
50
@@ -XXX,XX +XXX,XX @@ static int smmu_ptw_64_s1(SMMUTransCfg *cfg,
30
smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
51
pte_addr, pte, iova, gpa,
31
uint8_t tg, uint64_t num_pages, uint8_t ttl)
52
block_size >> 20);
32
{
53
}
33
+ /* if tg is not set we use 4KB range invalidation */
34
+ uint8_t granule = tg ? tg * 2 + 10 : 12;
35
+
54
+
36
if (ttl && (num_pages == 1) && (asid >= 0)) {
55
+ /*
37
SMMUIOTLBKey key = smmu_get_iotlb_key(asid, iova, tg, ttl);
56
+ * QEMU does not currently implement HTTU, so if AFFD and PTE.AF
38
57
+ * are 0 we take an Access flag fault. (5.4. Context Descriptor)
39
- g_hash_table_remove(s->iotlb, &key);
58
+ * An Access flag fault takes priority over a Permission fault.
40
- } else {
59
+ */
41
- /* if tg is not set we use 4KB range invalidation */
60
+ if (!PTE_AF(pte) && !cfg->affd) {
42
- uint8_t granule = tg ? tg * 2 + 10 : 12;
61
+ info->type = SMMU_PTW_ERR_ACCESS;
43
-
62
+ goto error;
44
- SMMUIOTLBPageInvInfo info = {
45
- .asid = asid, .iova = iova,
46
- .mask = (num_pages * 1 << granule) - 1};
47
-
48
- g_hash_table_foreach_remove(s->iotlb,
49
- smmu_hash_remove_by_asid_iova,
50
- &info);
51
+ if (g_hash_table_remove(s->iotlb, &key)) {
52
+ return;
53
+ }
63
+ }
54
+ /*
55
+ * if the entry is not found, let's see if it does not
56
+ * belong to a larger IOTLB entry
57
+ */
58
}
59
+
64
+
60
+ SMMUIOTLBPageInvInfo info = {
65
ap = PTE_AP(pte);
61
+ .asid = asid, .iova = iova,
66
if (is_permission_fault(ap, perm)) {
62
+ .mask = (num_pages * 1 << granule) - 1};
67
info->type = SMMU_PTW_ERR_PERMISSION;
63
+
64
+ g_hash_table_foreach_remove(s->iotlb,
65
+ smmu_hash_remove_by_asid_iova,
66
+ &info);
67
}
68
69
inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
70
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
68
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
71
index XXXXXXX..XXXXXXX 100644
69
index XXXXXXX..XXXXXXX 100644
72
--- a/hw/arm/smmuv3.c
70
--- a/hw/arm/smmuv3.c
73
+++ b/hw/arm/smmuv3.c
71
+++ b/hw/arm/smmuv3.c
74
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
72
@@ -XXX,XX +XXX,XX @@ static int decode_cd(SMMUTransCfg *cfg, CD *cd, SMMUEventInfo *event)
75
uint16_t vmid = CMD_VMID(cmd);
73
cfg->oas = MIN(oas2bits(SMMU_IDR5_OAS), cfg->oas);
76
bool leaf = CMD_LEAF(cmd);
74
cfg->tbi = CD_TBI(cd);
77
uint8_t tg = CMD_TG(cmd);
75
cfg->asid = CD_ASID(cd);
78
- hwaddr num_pages = 1;
76
+ cfg->affd = CD_AFFD(cd);
79
+ uint64_t first_page = 0, last_page;
77
80
+ uint64_t num_pages = 1;
78
trace_smmuv3_decode_cd(cfg->oas);
81
int asid = -1;
79
82
83
if (tg) {
84
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
85
if (type == SMMU_CMD_TLBI_NH_VA) {
86
asid = CMD_ASID(cmd);
87
}
88
- trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, num_pages, ttl, leaf);
89
- smmuv3_inv_notifiers_iova(s, asid, addr, tg, num_pages);
90
- smmu_iotlb_inv_iova(s, asid, addr, tg, num_pages, ttl);
91
+
92
+ /* Split invalidations into ^2 range invalidations */
93
+ last_page = num_pages - 1;
94
+ while (num_pages) {
95
+ uint8_t granule = tg * 2 + 10;
96
+ uint64_t mask, count;
97
+
98
+ mask = dma_aligned_pow2_mask(first_page, last_page, 64 - granule);
99
+ count = mask + 1;
100
+
101
+ trace_smmuv3_s1_range_inval(vmid, asid, addr, tg, count, ttl, leaf);
102
+ smmuv3_inv_notifiers_iova(s, asid, addr, tg, count);
103
+ smmu_iotlb_inv_iova(s, asid, addr, tg, count, ttl);
104
+
105
+ num_pages -= count;
106
+ first_page += count;
107
+ addr += count * BIT_ULL(granule);
108
+ }
109
}
110
111
static int smmuv3_cmdq_consume(SMMUv3State *s)
112
--
80
--
113
2.20.1
81
2.34.1
114
115
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This patch adds GPIOs in NPCM7xx PWM module for its duty values.
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
The purpose of this is to connect it to the MFT module to provide
5
an input for measuring a PWM fan's RPM. Each PWM module has
6
NPCM7XX_PWM_PER_MODULE of GPIOs, each one corresponds to
7
one PWM instance and can connect to multiple fan instances in MFT.
8
9
Reviewed-by: Doug Evans <dje@google.com>
10
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
11
Signed-off-by: Hao Wu <wuhaotsh@google.com>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
Message-id: 20210311180855.149764-2-wuhaotsh@google.com
5
Message-id: 20240213155214.13619-2-philmd@linaro.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
7
---
16
include/hw/misc/npcm7xx_pwm.h | 4 +++-
8
hw/arm/stellaris.c | 6 ++++--
17
hw/misc/npcm7xx_pwm.c | 4 ++++
9
1 file changed, 4 insertions(+), 2 deletions(-)
18
2 files changed, 7 insertions(+), 1 deletion(-)
19
10
20
diff --git a/include/hw/misc/npcm7xx_pwm.h b/include/hw/misc/npcm7xx_pwm.h
11
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
21
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
22
--- a/include/hw/misc/npcm7xx_pwm.h
13
--- a/hw/arm/stellaris.c
23
+++ b/include/hw/misc/npcm7xx_pwm.h
14
+++ b/hw/arm/stellaris.c
24
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxPWM {
15
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_trigger(void *opaque, int irq, int level)
25
* @iomem: Memory region through which registers are accessed.
26
* @clock: The PWM clock.
27
* @pwm: The PWM channels owned by this module.
28
+ * @duty_gpio_out: The duty cycle of each PWM channels as a output GPIO.
29
* @ppr: The prescaler register.
30
* @csr: The clock selector register.
31
* @pcr: The control register.
32
@@ -XXX,XX +XXX,XX @@ struct NPCM7xxPWMState {
33
MemoryRegion iomem;
34
35
Clock *clock;
36
- NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE];
37
+ NPCM7xxPWM pwm[NPCM7XX_PWM_PER_MODULE];
38
+ qemu_irq duty_gpio_out[NPCM7XX_PWM_PER_MODULE];
39
40
uint32_t ppr;
41
uint32_t csr;
42
diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c
43
index XXXXXXX..XXXXXXX 100644
44
--- a/hw/misc/npcm7xx_pwm.c
45
+++ b/hw/misc/npcm7xx_pwm.c
46
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_update_duty(NPCM7xxPWM *p)
47
trace_npcm7xx_pwm_update_duty(DEVICE(p->module)->canonical_path,
48
p->index, p->duty, duty);
49
p->duty = duty;
50
+ qemu_set_irq(p->module->duty_gpio_out[p->index], p->duty);
51
}
16
}
52
}
17
}
53
18
54
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_init(Object *obj)
19
-static void stellaris_adc_reset(StellarisADCState *s)
55
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
20
+static void stellaris_adc_reset_hold(Object *obj)
56
int i;
21
{
57
22
+ StellarisADCState *s = STELLARIS_ADC(obj);
58
+ QEMU_BUILD_BUG_ON(ARRAY_SIZE(s->pwm) != NPCM7XX_PWM_PER_MODULE);
23
int n;
59
for (i = 0; i < NPCM7XX_PWM_PER_MODULE; i++) {
24
60
NPCM7xxPWM *p = &s->pwm[i];
25
for (n = 0; n < 4; n++) {
61
p->module = s;
26
@@ -XXX,XX +XXX,XX @@ static void stellaris_adc_init(Object *obj)
62
@@ -XXX,XX +XXX,XX @@ static void npcm7xx_pwm_init(Object *obj)
27
memory_region_init_io(&s->iomem, obj, &stellaris_adc_ops, s,
63
object_property_add_uint32_ptr(obj, "duty[*]",
28
"adc", 0x1000);
64
&s->pwm[i].duty, OBJ_PROP_FLAG_READ);
29
sysbus_init_mmio(sbd, &s->iomem);
65
}
30
- stellaris_adc_reset(s);
66
+ qdev_init_gpio_out_named(DEVICE(s), s->duty_gpio_out,
31
qdev_init_gpio_in(dev, stellaris_adc_trigger, 1);
67
+ "duty-gpio-out", NPCM7XX_PWM_PER_MODULE);
68
}
32
}
69
33
70
static const VMStateDescription vmstate_npcm7xx_pwm = {
34
@@ -XXX,XX +XXX,XX @@ static const TypeInfo stellaris_i2c_info = {
35
static void stellaris_adc_class_init(ObjectClass *klass, void *data)
36
{
37
DeviceClass *dc = DEVICE_CLASS(klass);
38
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
39
40
+ rc->phases.hold = stellaris_adc_reset_hold;
41
dc->vmsd = &vmstate_stellaris_adc;
42
}
43
71
--
44
--
72
2.20.1
45
2.34.1
73
46
74
47
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Currently the emulated EMAC for sun8i always traverses the transmit queue
3
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
4
from the head when transferring packets. It searches for a list of consecutive
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
descriptors whichs are flagged as ready for processing and transmits their payloads
5
Message-id: 20240213155214.13619-3-philmd@linaro.org
6
accordingly. The controller stops processing once it finds a descriptor that is not
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
marked ready.
8
9
While the above behaviour works in most situations, it is not the same as the actual
10
EMAC in hardware. Actual hardware uses the TX_CUR_DESC register value to keep track
11
of the last position in the transmit queue and continues processing from that position
12
when software triggers the start of DMA processing. The currently emulated behaviour can
13
lead to packet loss on transmit when software fills the transmit queue with ready
14
descriptors that overlap the tail of the circular list.
15
16
This commit modifies the emulated EMAC for sun8i such that it processes
17
the transmit queue using the TX_CUR_DESC register in the same way as hardware.
18
19
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
20
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
21
Message-id: 20210310195820.21950-2-nieklinnenbank@gmail.com
22
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
---
8
---
24
hw/net/allwinner-sun8i-emac.c | 62 +++++++++++++++++++----------------
9
hw/arm/stellaris.c | 26 ++++++++++++++++++++++----
25
1 file changed, 34 insertions(+), 28 deletions(-)
10
1 file changed, 22 insertions(+), 4 deletions(-)
26
11
27
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
12
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
28
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/net/allwinner-sun8i-emac.c
14
--- a/hw/arm/stellaris.c
30
+++ b/hw/net/allwinner-sun8i-emac.c
15
+++ b/hw/arm/stellaris.c
31
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_update_irq(AwSun8iEmacState *s)
16
@@ -XXX,XX +XXX,XX @@ static void stellaris_sys_instance_init(Object *obj)
32
qemu_set_irq(s->irq, (s->int_sta & s->int_en) != 0);
17
s->sysclk = qdev_init_clock_out(DEVICE(s), "SYSCLK");
33
}
18
}
34
19
35
-static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
20
-/* I2C controller. */
36
- FrameDescriptor *desc,
21
+/*
37
- size_t min_size)
22
+ * I2C controller.
38
+static bool allwinner_sun8i_emac_desc_owned(FrameDescriptor *desc,
23
+ * ??? For now we only implement the master interface.
39
+ size_t min_buf_size)
24
+ */
25
26
#define TYPE_STELLARIS_I2C "stellaris-i2c"
27
OBJECT_DECLARE_SIMPLE_TYPE(stellaris_i2c_state, STELLARIS_I2C)
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_write(void *opaque, hwaddr offset,
29
stellaris_i2c_update(s);
30
}
31
32
-static void stellaris_i2c_reset(stellaris_i2c_state *s)
33
+static void stellaris_i2c_reset_enter(Object *obj, ResetType type)
40
{
34
{
41
- uint32_t paddr = desc->next;
35
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
42
-
36
+
43
- dma_memory_read(&s->dma_as, paddr, desc, sizeof(*desc));
37
if (s->mcs & STELLARIS_I2C_MCS_BUSBSY)
44
-
38
i2c_end_transfer(s->bus);
45
- if ((desc->status & DESC_STATUS_CTL) &&
46
- (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
47
- return paddr;
48
- } else {
49
- return 0;
50
- }
51
+ return (desc->status & DESC_STATUS_CTL) && (min_buf_size == 0 ||
52
+ (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_buf_size);
53
}
54
55
-static uint32_t allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
56
- FrameDescriptor *desc,
57
- uint32_t start_addr,
58
- size_t min_size)
59
+static void allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s,
60
+ FrameDescriptor *desc,
61
+ uint32_t phys_addr)
62
+{
63
+ dma_memory_read(&s->dma_as, phys_addr, desc, sizeof(*desc));
64
+}
39
+}
65
+
40
+
66
+static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s,
41
+static void stellaris_i2c_reset_hold(Object *obj)
67
+ FrameDescriptor *desc)
68
+{
42
+{
69
+ const uint32_t nxt = desc->next;
43
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
70
+ allwinner_sun8i_emac_get_desc(s, desc, nxt);
44
71
+ return nxt;
45
s->msa = 0;
46
s->mcs = 0;
47
@@ -XXX,XX +XXX,XX @@ static void stellaris_i2c_reset(stellaris_i2c_state *s)
48
s->mimr = 0;
49
s->mris = 0;
50
s->mcr = 0;
72
+}
51
+}
73
+
52
+
74
+static uint32_t allwinner_sun8i_emac_find_desc(AwSun8iEmacState *s,
53
+static void stellaris_i2c_reset_exit(Object *obj)
75
+ FrameDescriptor *desc,
54
+{
76
+ uint32_t start_addr,
55
+ stellaris_i2c_state *s = STELLARIS_I2C(obj);
77
+ size_t min_size)
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)
78
{
71
{
79
uint32_t desc_addr = start_addr;
72
DeviceClass *dc = DEVICE_CLASS(klass);
80
73
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
81
/* Note that the list is a cycle. Last entry points back to the head. */
74
82
while (desc_addr != 0) {
75
+ rc->phases.enter = stellaris_i2c_reset_enter;
83
- dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc));
76
+ rc->phases.hold = stellaris_i2c_reset_hold;
84
+ allwinner_sun8i_emac_get_desc(s, desc, desc_addr);
77
+ rc->phases.exit = stellaris_i2c_reset_exit;
85
78
dc->vmsd = &vmstate_stellaris_i2c;
86
- if ((desc->status & DESC_STATUS_CTL) &&
87
- (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) {
88
+ if (allwinner_sun8i_emac_desc_owned(desc, min_size)) {
89
return desc_addr;
90
} else if (desc->next == start_addr) {
91
break;
92
@@ -XXX,XX +XXX,XX @@ static uint32_t allwinner_sun8i_emac_rx_desc(AwSun8iEmacState *s,
93
FrameDescriptor *desc,
94
size_t min_size)
95
{
96
- return allwinner_sun8i_emac_get_desc(s, desc, s->rx_desc_curr, min_size);
97
+ return allwinner_sun8i_emac_find_desc(s, desc, s->rx_desc_curr, min_size);
98
}
79
}
99
80
100
static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s,
101
- FrameDescriptor *desc,
102
- size_t min_size)
103
+ FrameDescriptor *desc)
104
{
105
- return allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_head, min_size);
106
+ allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_curr);
107
+ return s->tx_desc_curr;
108
}
109
110
static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s,
111
@@ -XXX,XX +XXX,XX @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc,
112
bytes_left -= desc_bytes;
113
114
/* Move to the next descriptor */
115
- s->rx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 64);
116
+ s->rx_desc_curr = allwinner_sun8i_emac_find_desc(s, &desc, desc.next,
117
+ AW_SUN8I_EMAC_MIN_PKT_SZ);
118
if (!s->rx_desc_curr) {
119
/* Not enough buffer space available */
120
s->int_sta |= INT_STA_RX_BUF_UA;
121
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
122
size_t transmitted = 0;
123
static uint8_t packet_buf[2048];
124
125
- s->tx_desc_curr = allwinner_sun8i_emac_tx_desc(s, &desc, 0);
126
+ s->tx_desc_curr = allwinner_sun8i_emac_tx_desc(s, &desc);
127
128
/* Read all transmit descriptors */
129
- while (s->tx_desc_curr != 0) {
130
+ while (allwinner_sun8i_emac_desc_owned(&desc, 0)) {
131
132
/* Read from physical memory into packet buffer */
133
bytes = desc.status2 & DESC_STATUS2_BUF_SIZE_MASK;
134
@@ -XXX,XX +XXX,XX @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s)
135
packet_bytes = 0;
136
transmitted++;
137
}
138
- s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 0);
139
+ s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc);
140
}
141
142
/* Raise transmit completed interrupt */
143
--
81
--
144
2.20.1
82
2.34.1
145
83
146
84
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Previously the ARMBIAN_ARTIFACTS_CACHED pre-condition was added to allow running
3
QDev objects created with qdev_new() need to manually add
4
tests that have already existing armbian.com artifacts stored in the local avocado cache,
4
their parent relationship with object_property_add_child().
5
but do not have working URLs to download a fresh copy.
6
5
7
At this time of writing the URLs for artifacts on the armbian.com server are updated and working.
6
This commit plug the devices which aren't part of the SoC;
8
Any future broken URLs will result in a skipped acceptance test, for example:
7
they will be plugged into a SoC container in the next one.
9
8
10
(1/5) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
11
CANCEL: Missing asset https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb (0.53 s)
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
11
Message-id: 20240213155214.13619-4-philmd@linaro.org
13
This commits removes the ARMBIAN_ARTIFACTS_CACHED pre-condition such that
14
the acceptance tests for the orangepi-pc and cubieboard machines can run.
15
16
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
17
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
18
Message-id: 20210310195820.21950-6-nieklinnenbank@gmail.com
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
---
13
---
21
tests/acceptance/boot_linux_console.py | 12 ------------
14
hw/arm/stellaris.c | 4 ++++
22
tests/acceptance/replay_kernel.py | 2 --
15
1 file changed, 4 insertions(+)
23
2 files changed, 14 deletions(-)
24
16
25
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
17
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
26
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
27
--- a/tests/acceptance/boot_linux_console.py
19
--- a/hw/arm/stellaris.c
28
+++ b/tests/acceptance/boot_linux_console.py
20
+++ b/hw/arm/stellaris.c
29
@@ -XXX,XX +XXX,XX @@ def test_arm_exynos4210_initrd(self):
21
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
30
self.wait_for_console_pattern('Boot successful.')
22
&error_fatal);
31
# TODO user command, for now the uart is stuck
23
32
24
ssddev = qdev_new("ssd0323");
33
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
25
+ object_property_add_child(OBJECT(ms), "oled", OBJECT(ssddev));
34
- 'Test artifacts fetched from unreliable apt.armbian.com')
26
qdev_prop_set_uint8(ssddev, "cs", 1);
35
def test_arm_cubieboard_initrd(self):
27
qdev_realize_and_unref(ssddev, bus, &error_fatal);
36
"""
28
37
:avocado: tags=arch:arm
29
gpio_d_splitter = qdev_new(TYPE_SPLIT_IRQ);
38
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
30
+ object_property_add_child(OBJECT(ms), "splitter",
39
'system-control@1c00000')
31
+ OBJECT(gpio_d_splitter));
40
# cubieboard's reboot is not functioning; omit reboot test.
32
qdev_prop_set_uint32(gpio_d_splitter, "num-lines", 2);
41
33
qdev_realize_and_unref(gpio_d_splitter, NULL, &error_fatal);
42
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
34
qdev_connect_gpio_out(
43
- 'Test artifacts fetched from unreliable apt.armbian.com')
35
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
44
def test_arm_cubieboard_sata(self):
36
DeviceState *gpad;
45
"""
37
46
:avocado: tags=arch:arm
38
gpad = qdev_new(TYPE_STELLARIS_GAMEPAD);
47
@@ -XXX,XX +XXX,XX @@ def test_arm_quanta_gsj_initrd(self):
39
+ object_property_add_child(OBJECT(ms), "gamepad", OBJECT(gpad));
48
self.wait_for_console_pattern(
40
for (i = 0; i < ARRAY_SIZE(gpad_keycode); i++) {
49
'Give root password for system maintenance')
41
qlist_append_int(gpad_keycode_list, gpad_keycode[i]);
50
42
}
51
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
52
- 'Test artifacts fetched from unreliable apt.armbian.com')
53
def test_arm_orangepi(self):
54
"""
55
:avocado: tags=arch:arm
56
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
57
console_pattern = 'Kernel command line: %s' % kernel_command_line
58
self.wait_for_console_pattern(console_pattern)
59
60
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
61
- 'Test artifacts fetched from unreliable apt.armbian.com')
62
def test_arm_orangepi_initrd(self):
63
"""
64
:avocado: tags=arch:arm
65
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
66
# Wait for VM to shut down gracefully
67
self.vm.wait()
68
69
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
70
- 'Test artifacts fetched from unreliable apt.armbian.com')
71
def test_arm_orangepi_sd(self):
72
"""
73
:avocado: tags=arch:arm
74
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
75
# Wait for VM to shut down gracefully
76
self.vm.wait()
77
78
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
79
- 'Test artifacts fetched from unreliable apt.armbian.com')
80
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
81
def test_arm_orangepi_bionic_20_08(self):
82
"""
83
diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py
84
index XXXXXXX..XXXXXXX 100644
85
--- a/tests/acceptance/replay_kernel.py
86
+++ b/tests/acceptance/replay_kernel.py
87
@@ -XXX,XX +XXX,XX @@ def test_arm_virt(self):
88
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=1)
89
90
@skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
91
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
92
- 'Test artifacts fetched from unreliable apt.armbian.com')
93
def test_arm_cubieboard_initrd(self):
94
"""
95
:avocado: tags=arch:arm
96
--
43
--
97
2.20.1
44
2.34.1
98
45
99
46
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
The linux kernel 4.20.7 binary for sunxi has been removed from apt.armbian.com:
3
QDev objects created with qdev_new() need to manually add
4
their parent relationship with object_property_add_child().
4
5
5
$ ARMBIAN_ARTIFACTS_CACHED=yes AVOCADO_ALLOW_LARGE_STORAGE=yes avocado --show=app,console run -t machine:orangepi-pc tests/acceptance/boot_linux_console.py
6
Since we don't model the SoC, just use a QOM container.
6
Fetching asset from tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi
7
...
8
(1/6) tests/acceptance/boot_linux_console.py:BootLinuxConsole.test_arm_orangepi:
9
CANCEL: Missing asset https://apt.armbian.com/pool/main/l/linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb (0.55 s)
10
7
11
This commit updates the sunxi kernel to 5.10.16 for the acceptance
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
tests of the orangepi-pc and cubieboard machines.
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
13
10
Message-id: 20240213155214.13619-5-philmd@linaro.org
14
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
15
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
16
Message-id: 20210310195820.21950-5-nieklinnenbank@gmail.com
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
---
12
---
19
tests/acceptance/boot_linux_console.py | 40 +++++++++++++-------------
13
hw/arm/stellaris.c | 11 ++++++++++-
20
tests/acceptance/replay_kernel.py | 8 +++---
14
1 file changed, 10 insertions(+), 1 deletion(-)
21
2 files changed, 24 insertions(+), 24 deletions(-)
22
15
23
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
16
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
24
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
25
--- a/tests/acceptance/boot_linux_console.py
18
--- a/hw/arm/stellaris.c
26
+++ b/tests/acceptance/boot_linux_console.py
19
+++ b/hw/arm/stellaris.c
27
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
20
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
28
:avocado: tags=machine:cubieboard
21
* 400fe000 system control
29
"""
22
*/
30
deb_url = ('https://apt.armbian.com/pool/main/l/'
23
31
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
24
+ Object *soc_container;
32
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
25
DeviceState *gpio_dev[7], *nvic;
33
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
26
qemu_irq gpio_in[7][8];
34
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
27
qemu_irq gpio_out[7][8];
35
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
28
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
36
kernel_path = self.extract_from_deb(deb_path,
29
flash_size = (((board->dc0 & 0xffff) + 1) << 1) * 1024;
37
- '/boot/vmlinuz-4.20.7-sunxi')
30
sram_size = ((board->dc0 >> 18) + 1) * 1024;
38
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
31
39
+ '/boot/vmlinuz-5.10.16-sunxi')
32
+ soc_container = object_new("container");
40
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
33
+ object_property_add_child(OBJECT(ms), "soc", soc_container);
41
dtb_path = self.extract_from_deb(deb_path, dtb_path)
34
+
42
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
35
/* Flash programming is done via the SCU, so pretend it is ROM. */
43
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
36
memory_region_init_rom(flash, NULL, "stellaris.flash", flash_size,
44
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_sata(self):
37
&error_fatal);
45
:avocado: tags=machine:cubieboard
38
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
46
"""
39
* need its sysclk output.
47
deb_url = ('https://apt.armbian.com/pool/main/l/'
40
*/
48
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
41
ssys_dev = qdev_new(TYPE_STELLARIS_SYS);
49
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
42
+ object_property_add_child(soc_container, "sys", OBJECT(ssys_dev));
50
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
43
51
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
44
/*
52
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
45
* Most devices come preprogrammed with a MAC address in the user data.
53
kernel_path = self.extract_from_deb(deb_path,
46
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
54
- '/boot/vmlinuz-4.20.7-sunxi')
47
sysbus_realize_and_unref(SYS_BUS_DEVICE(ssys_dev), &error_fatal);
55
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
48
56
+ '/boot/vmlinuz-5.10.16-sunxi')
49
nvic = qdev_new(TYPE_ARMV7M);
57
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
50
+ object_property_add_child(soc_container, "v7m", OBJECT(nvic));
58
dtb_path = self.extract_from_deb(deb_path, dtb_path)
51
qdev_prop_set_uint32(nvic, "num-irq", NUM_IRQ_LINES);
59
rootfs_url = ('https://github.com/groeck/linux-build-test/raw/'
52
qdev_prop_set_uint8(nvic, "num-prio-bits", NUM_PRIO_BITS);
60
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
53
qdev_prop_set_string(nvic, "cpu-type", ms->cpu_type);
61
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi(self):
54
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
62
:avocado: tags=machine:orangepi-pc
55
63
"""
56
dev = qdev_new(TYPE_STELLARIS_GPTM);
64
deb_url = ('https://apt.armbian.com/pool/main/l/'
57
sbd = SYS_BUS_DEVICE(dev);
65
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
58
+ object_property_add_child(soc_container, "gptm[*]", OBJECT(dev));
66
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
59
qdev_connect_clock_in(dev, "clk",
67
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
60
qdev_get_clock_out(ssys_dev, "SYSCLK"));
68
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
61
sysbus_realize_and_unref(sbd, &error_fatal);
69
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
62
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
70
kernel_path = self.extract_from_deb(deb_path,
63
71
- '/boot/vmlinuz-4.20.7-sunxi')
64
if (board->dc1 & (1 << 3)) { /* watchdog present */
72
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
65
dev = qdev_new(TYPE_LUMINARY_WATCHDOG);
73
+ '/boot/vmlinuz-5.10.16-sunxi')
66
-
74
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
67
+ object_property_add_child(soc_container, "wdg", OBJECT(dev));
75
dtb_path = self.extract_from_deb(deb_path, dtb_path)
68
qdev_connect_clock_in(dev, "WDOGCLK",
76
69
qdev_get_clock_out(ssys_dev, "SYSCLK"));
77
self.vm.set_console()
70
78
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_initrd(self):
71
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
79
:avocado: tags=machine:orangepi-pc
72
SysBusDevice *sbd;
80
"""
73
81
deb_url = ('https://apt.armbian.com/pool/main/l/'
74
dev = qdev_new("pl011_luminary");
82
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
75
+ object_property_add_child(soc_container, "uart[*]", OBJECT(dev));
83
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
76
sbd = SYS_BUS_DEVICE(dev);
84
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
77
qdev_prop_set_chr(dev, "chardev", serial_hd(i));
85
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
78
sysbus_realize_and_unref(sbd, &error_fatal);
86
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
79
@@ -XXX,XX +XXX,XX @@ static void stellaris_init(MachineState *ms, stellaris_board_info *board)
87
kernel_path = self.extract_from_deb(deb_path,
80
DeviceState *enet;
88
- '/boot/vmlinuz-4.20.7-sunxi')
81
89
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
82
enet = qdev_new("stellaris_enet");
90
+ '/boot/vmlinuz-5.10.16-sunxi')
83
+ object_property_add_child(soc_container, "enet", OBJECT(enet));
91
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
84
if (nd) {
92
dtb_path = self.extract_from_deb(deb_path, dtb_path)
85
qdev_set_nic_properties(enet, nd);
93
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
86
} else {
94
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
95
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
96
:avocado: tags=device:sd
97
"""
98
deb_url = ('https://apt.armbian.com/pool/main/l/'
99
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
100
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
101
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
102
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
103
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
104
kernel_path = self.extract_from_deb(deb_path,
105
- '/boot/vmlinuz-4.20.7-sunxi')
106
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun8i-h3-orangepi-pc.dtb'
107
+ '/boot/vmlinuz-5.10.16-sunxi')
108
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun8i-h3-orangepi-pc.dtb'
109
dtb_path = self.extract_from_deb(deb_path, dtb_path)
110
rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
111
'kci-2019.02/armel/base/rootfs.ext2.xz')
112
diff --git a/tests/acceptance/replay_kernel.py b/tests/acceptance/replay_kernel.py
113
index XXXXXXX..XXXXXXX 100644
114
--- a/tests/acceptance/replay_kernel.py
115
+++ b/tests/acceptance/replay_kernel.py
116
@@ -XXX,XX +XXX,XX @@ def test_arm_cubieboard_initrd(self):
117
:avocado: tags=machine:cubieboard
118
"""
119
deb_url = ('https://apt.armbian.com/pool/main/l/'
120
- 'linux-4.20.7-sunxi/linux-image-dev-sunxi_5.75_armhf.deb')
121
- deb_hash = '1334c29c44d984ffa05ed10de8c3361f33d78315'
122
+ 'linux-5.10.16-sunxi/linux-image-current-sunxi_21.02.2_armhf.deb')
123
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
124
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
125
kernel_path = self.extract_from_deb(deb_path,
126
- '/boot/vmlinuz-4.20.7-sunxi')
127
- dtb_path = '/usr/lib/linux-image-dev-sunxi/sun4i-a10-cubieboard.dtb'
128
+ '/boot/vmlinuz-5.10.16-sunxi')
129
+ dtb_path = '/usr/lib/linux-image-current-sunxi/sun4i-a10-cubieboard.dtb'
130
dtb_path = self.extract_from_deb(deb_path, dtb_path)
131
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
132
'2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
133
--
87
--
134
2.20.1
88
2.34.1
135
89
136
90
diff view generated by jsdifflib
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
1
We support two different encodings for the AArch32 IMPDEF
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.
2
5
3
Update the download URL of the Armbian 20.08 Bionic image for
6
When we implemented this we picked which encoding to
4
test_arm_orangepi_bionic_20_08 of the orangepi-pc machine.
7
use based on whether the CPU set ARM_FEATURE_AARCH64.
8
However this isn't right for three cases:
9
* the qemu-system-arm 'max' CPU, which is supposed to be
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
5
19
6
The archive.armbian.com URL contains more images and should keep stable
20
Make the decision of the encoding be based on whether
7
for a longer period of time than dl.armbian.com.
21
the CPU implements the ARM_FEATURE_V8 flag instead.
8
22
9
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
23
This changes the behaviour only for the qemu-system-arm
10
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
24
'-cpu max'. We don't expect anybody to be relying on the
11
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
25
old behaviour because:
12
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
26
* it's not what the real hardware Cortex-A57 does
13
Message-id: 20210310195820.21950-4-nieklinnenbank@gmail.com
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
31
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
34
Message-id: 20240206132931.38376-2-peter.maydell@linaro.org
15
---
35
---
16
tests/acceptance/boot_linux_console.py | 2 +-
36
target/arm/helper.c | 2 +-
17
1 file changed, 1 insertion(+), 1 deletion(-)
37
1 file changed, 1 insertion(+), 1 deletion(-)
18
38
19
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
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/tests/acceptance/boot_linux_console.py
41
--- a/target/arm/helper.c
22
+++ b/tests/acceptance/boot_linux_console.py
42
+++ b/target/arm/helper.c
23
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_bionic_20_08(self):
43
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
24
# to 1036 MiB, but the underlying filesystem is 1552 MiB...
44
* AArch64 cores we might need to add a specific feature flag
25
# As we expand it to 2 GiB we are safe.
45
* to indicate cores with "flavour 2" CBAR.
26
46
*/
27
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
47
- if (arm_feature(env, ARM_FEATURE_AARCH64)) {
28
+ image_url = ('https://archive.armbian.com/orangepipc/archive/'
48
+ if (arm_feature(env, ARM_FEATURE_V8)) {
29
'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
49
/* 32 bit view is [31:18] 0...0 [43:32]. */
30
image_hash = ('b4d6775f5673486329e45a0586bf06b6'
50
uint32_t cbar32 = (extract64(cpu->reset_cbar, 18, 14) << 18)
31
'dbe792199fd182ac6b9c7bb6c7d3e6dd')
51
| extract64(cpu->reset_cbar, 32, 12);
32
--
52
--
33
2.20.1
53
2.34.1
34
35
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <f4bug@amsat.org>
1
The Cortex-R52 implements the Configuration Base Address Register
2
(CBAR), as a read-only register. Add ARM_FEATURE_CBAR_RO to this CPU
3
type, so that our implementation provides the register and the
4
associated qdev property.
2
5
3
If the SSECounter link is absent, we set an error message
4
in sse_timer_realize() but forgot to propagate this error.
5
Add the missing 'return'.
6
7
Fixes: CID 1450755 (Null pointer dereferences)
8
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
9
Message-id: 20210312001845.1562670-1-f4bug@amsat.org
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
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>
8
Message-id: 20240206132931.38376-3-peter.maydell@linaro.org
12
---
9
---
13
hw/timer/sse-timer.c | 1 +
10
target/arm/tcg/cpu32.c | 1 +
14
1 file changed, 1 insertion(+)
11
1 file changed, 1 insertion(+)
15
12
16
diff --git a/hw/timer/sse-timer.c b/hw/timer/sse-timer.c
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/timer/sse-timer.c
15
--- a/target/arm/tcg/cpu32.c
19
+++ b/hw/timer/sse-timer.c
16
+++ b/target/arm/tcg/cpu32.c
20
@@ -XXX,XX +XXX,XX @@ static void sse_timer_realize(DeviceState *dev, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
21
18
set_feature(&cpu->env, ARM_FEATURE_PMSA);
22
if (!s->counter) {
19
set_feature(&cpu->env, ARM_FEATURE_NEON);
23
error_setg(errp, "counter property was not set");
20
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
24
+ return;
21
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
25
}
22
cpu->midr = 0x411fd133; /* r1p3 */
26
23
cpu->revidr = 0x00000000;
27
s->counter_notifier.notify = sse_timer_counter_callback;
24
cpu->reset_fpsid = 0x41034023;
28
--
25
--
29
2.20.1
26
2.34.1
30
31
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Add the Cortex-R52 IMPDEF sysregs, by defining them here and
2
also by enabling the AUXCR feature which defines the ACTLR
3
and HACTLR registers. As is our usual practice, we make these
4
simple reads-as-zero stubs for now.
2
5
3
Unmap notifiers work with an address mask assuming an
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
invalidation range of a power of 2. Nothing mandates this
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
in the VIRTIO-IOMMU spec.
8
Message-id: 20240206132931.38376-4-peter.maydell@linaro.org
9
---
10
target/arm/tcg/cpu32.c | 108 +++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 108 insertions(+)
6
12
7
So in case the range is not a power of 2, split it into
13
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
8
several invalidations.
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reviewed-by: Peter Xu <peterx@redhat.com>
12
Message-id: 20210309102742.30442-4-eric.auger@redhat.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/virtio/virtio-iommu.c | 19 ++++++++++++++++---
16
1 file changed, 16 insertions(+), 3 deletions(-)
17
18
diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/virtio/virtio-iommu.c
15
--- a/target/arm/tcg/cpu32.c
21
+++ b/hw/virtio/virtio-iommu.c
16
+++ b/target/arm/tcg/cpu32.c
22
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
23
hwaddr virt_end)
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
24
{
19
}
25
IOMMUTLBEvent event;
20
26
+ uint64_t delta = virt_end - virt_start;
21
+static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
27
22
+ { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
28
if (!(mr->iommu_notify_flags & IOMMU_NOTIFIER_UNMAP)) {
23
+ .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
29
return;
24
+ { .name = "IMP_ATCMREGIONR",
30
@@ -XXX,XX +XXX,XX @@ static void virtio_iommu_notify_unmap(IOMMUMemoryRegion *mr, hwaddr virt_start,
25
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
31
26
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
32
event.type = IOMMU_NOTIFIER_UNMAP;
27
+ { .name = "IMP_BTCMREGIONR",
33
event.entry.target_as = &address_space_memory;
28
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
34
- event.entry.addr_mask = virt_end - virt_start;
29
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
35
- event.entry.iova = virt_start;
30
+ { .name = "IMP_CTCMREGIONR",
36
event.entry.perm = IOMMU_NONE;
31
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
37
event.entry.translated_addr = 0;
32
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
38
+ event.entry.addr_mask = delta;
33
+ { .name = "IMP_CSCTLR",
39
+ event.entry.iova = virt_start;
34
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
40
35
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
41
- memory_region_notify_iommu(mr, 0, event);
36
+ { .name = "IMP_BPCTLR",
42
+ if (delta == UINT64_MAX) {
37
+ .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
43
+ memory_region_notify_iommu(mr, 0, event);
38
+ .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
44
+ }
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
+};
45
+
124
+
46
+
125
+
47
+ while (virt_start != virt_end + 1) {
126
static void cortex_r52_initfn(Object *obj)
48
+ uint64_t mask = dma_aligned_pow2_mask(virt_start, virt_end, 64);
127
{
128
ARMCPU *cpu = ARM_CPU(obj);
129
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
130
set_feature(&cpu->env, ARM_FEATURE_NEON);
131
set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
132
set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
133
+ set_feature(&cpu->env, ARM_FEATURE_AUXCR);
134
cpu->midr = 0x411fd133; /* r1p3 */
135
cpu->revidr = 0x00000000;
136
cpu->reset_fpsid = 0x41034023;
137
@@ -XXX,XX +XXX,XX @@ static void cortex_r52_initfn(Object *obj)
138
139
cpu->pmsav7_dregion = 16;
140
cpu->pmsav8r_hdregion = 16;
49
+
141
+
50
+ event.entry.addr_mask = mask;
142
+ define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
51
+ event.entry.iova = virt_start;
52
+ memory_region_notify_iommu(mr, 0, event);
53
+ virt_start += mask + 1;
54
+ }
55
}
143
}
56
144
57
static gboolean virtio_iommu_notify_unmap_cb(gpointer key, gpointer value,
145
static void cortex_r5f_initfn(Object *obj)
58
--
146
--
59
2.20.1
147
2.34.1
60
61
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
Architecturally, the AArch32 MSR/MRS to/from banked register
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.
2
6
3
This patch implements Multi Function Timer (MFT) module for NPCM7XX.
7
However, for the case of accessing SPSR_hyp from hyp mode, it turns
4
This module is mainly used to configure PWM fans. It has just enough
8
out that real hardware permits this, with the same effect as if the
5
functionality to make the PWM fan kernel module work.
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.
6
17
7
The module takes two input, the max_rpm of a fan (modifiable via QMP)
18
For convenience of being able to run guest code, permit
8
and duty cycle (a GPIO from the PWM module.) The actual measured RPM
19
this UNPREDICTABLE access instead of UNDEFing it.
9
is equal to max_rpm * duty_cycle / NPCM7XX_PWM_MAX_DUTY. The RPM is
10
measured as a counter compared to a prescaled input clock. The kernel
11
driver reads this counter and report to user space.
12
20
13
Refs:
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
https://github.com/torvalds/linux/blob/master/drivers/hwmon/npcm750-pwm-fan.c
22
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
23
Message-id: 20240206132931.38376-5-peter.maydell@linaro.org
24
---
25
target/arm/tcg/op_helper.c | 43 ++++++++++++++++++++++++++------------
26
target/arm/tcg/translate.c | 19 +++++++++++------
27
2 files changed, 43 insertions(+), 19 deletions(-)
15
28
16
Reviewed-by: Doug Evans <dje@google.com>
29
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
17
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
30
index XXXXXXX..XXXXXXX 100644
18
Signed-off-by: Hao Wu <wuhaotsh@google.com>
31
--- a/target/arm/tcg/op_helper.c
19
Message-id: 20210311180855.149764-3-wuhaotsh@google.com
32
+++ b/target/arm/tcg/op_helper.c
20
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
33
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
21
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
34
*/
22
---
35
int curmode = env->uncached_cpsr & CPSR_M;
23
include/hw/misc/npcm7xx_mft.h | 70 +++++
36
24
hw/misc/npcm7xx_mft.c | 540 ++++++++++++++++++++++++++++++++++
37
- if (regno == 17) {
25
hw/misc/meson.build | 1 +
38
- /* ELR_Hyp: a special case because access from tgtmode is OK */
26
hw/misc/trace-events | 8 +
39
- if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
27
4 files changed, 619 insertions(+)
40
- goto undef;
28
create mode 100644 include/hw/misc/npcm7xx_mft.h
41
+ if (tgtmode == ARM_CPU_MODE_HYP) {
29
create mode 100644 hw/misc/npcm7xx_mft.c
30
31
diff --git a/include/hw/misc/npcm7xx_mft.h b/include/hw/misc/npcm7xx_mft.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/misc/npcm7xx_mft.h
36
@@ -XXX,XX +XXX,XX @@
37
+/*
38
+ * Nuvoton NPCM7xx MFT Module
39
+ *
40
+ * Copyright 2021 Google LLC
41
+ *
42
+ * This program is free software; you can redistribute it and/or modify it
43
+ * under the terms of the GNU General Public License as published by the
44
+ * Free Software Foundation; either version 2 of the License, or
45
+ * (at your option) any later version.
46
+ *
47
+ * This program is distributed in the hope that it will be useful, but WITHOUT
48
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
49
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
50
+ * for more details.
51
+ */
52
+#ifndef NPCM7XX_MFT_H
53
+#define NPCM7XX_MFT_H
54
+
55
+#include "exec/memory.h"
56
+#include "hw/clock.h"
57
+#include "hw/irq.h"
58
+#include "hw/sysbus.h"
59
+#include "qom/object.h"
60
+
61
+/* Max Fan input number. */
62
+#define NPCM7XX_MFT_MAX_FAN_INPUT 19
63
+
64
+/*
65
+ * Number of registers in one MFT module. Don't change this without increasing
66
+ * the version_id in vmstate.
67
+ */
68
+#define NPCM7XX_MFT_NR_REGS (0x20 / sizeof(uint16_t))
69
+
70
+/*
71
+ * The MFT can take up to 4 inputs: A0, B0, A1, B1. It can measure one A and one
72
+ * B simultaneously. NPCM7XX_MFT_INASEL and NPCM7XX_MFT_INBSEL are used to
73
+ * select which A or B input are used.
74
+ */
75
+#define NPCM7XX_MFT_FANIN_COUNT 4
76
+
77
+/**
78
+ * struct NPCM7xxMFTState - Multi Functional Tachometer device state.
79
+ * @parent: System bus device.
80
+ * @iomem: Memory region through which registers are accessed.
81
+ * @clock_in: The input clock for MFT from CLK module.
82
+ * @clock_{1,2}: The counter clocks for NPCM7XX_MFT_CNT{1,2}
83
+ * @irq: The IRQ for this MFT state.
84
+ * @regs: The MMIO registers.
85
+ * @max_rpm: The maximum rpm for fans. Order: A0, B0, A1, B1.
86
+ * @duty: The duty cycles for fans, relative to NPCM7XX_PWM_MAX_DUTY.
87
+ */
88
+typedef struct NPCM7xxMFTState {
89
+ SysBusDevice parent;
90
+
91
+ MemoryRegion iomem;
92
+
93
+ Clock *clock_in;
94
+ Clock *clock_1, *clock_2;
95
+ qemu_irq irq;
96
+ uint16_t regs[NPCM7XX_MFT_NR_REGS];
97
+
98
+ uint32_t max_rpm[NPCM7XX_MFT_FANIN_COUNT];
99
+ uint32_t duty[NPCM7XX_MFT_FANIN_COUNT];
100
+} NPCM7xxMFTState;
101
+
102
+#define TYPE_NPCM7XX_MFT "npcm7xx-mft"
103
+#define NPCM7XX_MFT(obj) \
104
+ OBJECT_CHECK(NPCM7xxMFTState, (obj), TYPE_NPCM7XX_MFT)
105
+
106
+#endif /* NPCM7XX_MFT_H */
107
diff --git a/hw/misc/npcm7xx_mft.c b/hw/misc/npcm7xx_mft.c
108
new file mode 100644
109
index XXXXXXX..XXXXXXX
110
--- /dev/null
111
+++ b/hw/misc/npcm7xx_mft.c
112
@@ -XXX,XX +XXX,XX @@
113
+/*
114
+ * Nuvoton NPCM7xx MFT Module
115
+ *
116
+ * Copyright 2021 Google LLC
117
+ *
118
+ * This program is free software; you can redistribute it and/or modify it
119
+ * under the terms of the GNU General Public License as published by the
120
+ * Free Software Foundation; either version 2 of the License, or
121
+ * (at your option) any later version.
122
+ *
123
+ * This program is distributed in the hope that it will be useful, but WITHOUT
124
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
125
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
126
+ * for more details.
127
+ */
128
+
129
+#include "qemu/osdep.h"
130
+#include "hw/irq.h"
131
+#include "hw/qdev-clock.h"
132
+#include "hw/qdev-properties.h"
133
+#include "hw/misc/npcm7xx_mft.h"
134
+#include "hw/misc/npcm7xx_pwm.h"
135
+#include "hw/registerfields.h"
136
+#include "migration/vmstate.h"
137
+#include "qapi/error.h"
138
+#include "qapi/visitor.h"
139
+#include "qemu/bitops.h"
140
+#include "qemu/error-report.h"
141
+#include "qemu/log.h"
142
+#include "qemu/module.h"
143
+#include "qemu/timer.h"
144
+#include "qemu/units.h"
145
+#include "trace.h"
146
+
147
+/*
148
+ * Some of the registers can only accessed via 16-bit ops and some can only
149
+ * be accessed via 8-bit ops. However we mark all of them using REG16 to
150
+ * simplify implementation. npcm7xx_mft_check_mem_op checks the access length
151
+ * of memory operations.
152
+ */
153
+REG16(NPCM7XX_MFT_CNT1, 0x00);
154
+REG16(NPCM7XX_MFT_CRA, 0x02);
155
+REG16(NPCM7XX_MFT_CRB, 0x04);
156
+REG16(NPCM7XX_MFT_CNT2, 0x06);
157
+REG16(NPCM7XX_MFT_PRSC, 0x08);
158
+REG16(NPCM7XX_MFT_CKC, 0x0a);
159
+REG16(NPCM7XX_MFT_MCTRL, 0x0c);
160
+REG16(NPCM7XX_MFT_ICTRL, 0x0e);
161
+REG16(NPCM7XX_MFT_ICLR, 0x10);
162
+REG16(NPCM7XX_MFT_IEN, 0x12);
163
+REG16(NPCM7XX_MFT_CPA, 0x14);
164
+REG16(NPCM7XX_MFT_CPB, 0x16);
165
+REG16(NPCM7XX_MFT_CPCFG, 0x18);
166
+REG16(NPCM7XX_MFT_INASEL, 0x1a);
167
+REG16(NPCM7XX_MFT_INBSEL, 0x1c);
168
+
169
+/* Register Fields */
170
+#define NPCM7XX_MFT_CKC_C2CSEL BIT(3)
171
+#define NPCM7XX_MFT_CKC_C1CSEL BIT(0)
172
+
173
+#define NPCM7XX_MFT_MCTRL_TBEN BIT(6)
174
+#define NPCM7XX_MFT_MCTRL_TAEN BIT(5)
175
+#define NPCM7XX_MFT_MCTRL_TBEDG BIT(4)
176
+#define NPCM7XX_MFT_MCTRL_TAEDG BIT(3)
177
+#define NPCM7XX_MFT_MCTRL_MODE5 BIT(2)
178
+
179
+#define NPCM7XX_MFT_ICTRL_TFPND BIT(5)
180
+#define NPCM7XX_MFT_ICTRL_TEPND BIT(4)
181
+#define NPCM7XX_MFT_ICTRL_TDPND BIT(3)
182
+#define NPCM7XX_MFT_ICTRL_TCPND BIT(2)
183
+#define NPCM7XX_MFT_ICTRL_TBPND BIT(1)
184
+#define NPCM7XX_MFT_ICTRL_TAPND BIT(0)
185
+
186
+#define NPCM7XX_MFT_ICLR_TFCLR BIT(5)
187
+#define NPCM7XX_MFT_ICLR_TECLR BIT(4)
188
+#define NPCM7XX_MFT_ICLR_TDCLR BIT(3)
189
+#define NPCM7XX_MFT_ICLR_TCCLR BIT(2)
190
+#define NPCM7XX_MFT_ICLR_TBCLR BIT(1)
191
+#define NPCM7XX_MFT_ICLR_TACLR BIT(0)
192
+
193
+#define NPCM7XX_MFT_IEN_TFIEN BIT(5)
194
+#define NPCM7XX_MFT_IEN_TEIEN BIT(4)
195
+#define NPCM7XX_MFT_IEN_TDIEN BIT(3)
196
+#define NPCM7XX_MFT_IEN_TCIEN BIT(2)
197
+#define NPCM7XX_MFT_IEN_TBIEN BIT(1)
198
+#define NPCM7XX_MFT_IEN_TAIEN BIT(0)
199
+
200
+#define NPCM7XX_MFT_CPCFG_GET_B(rv) extract8((rv), 4, 4)
201
+#define NPCM7XX_MFT_CPCFG_GET_A(rv) extract8((rv), 0, 4)
202
+#define NPCM7XX_MFT_CPCFG_HIEN BIT(3)
203
+#define NPCM7XX_MFT_CPCFG_EQEN BIT(2)
204
+#define NPCM7XX_MFT_CPCFG_LOEN BIT(1)
205
+#define NPCM7XX_MFT_CPCFG_CPSEL BIT(0)
206
+
207
+#define NPCM7XX_MFT_INASEL_SELA BIT(0)
208
+#define NPCM7XX_MFT_INBSEL_SELB BIT(0)
209
+
210
+/* Max CNT values of the module. The CNT value is a countdown from it. */
211
+#define NPCM7XX_MFT_MAX_CNT 0xFFFF
212
+
213
+/* Each fan revolution should generated 2 pulses */
214
+#define NPCM7XX_MFT_PULSE_PER_REVOLUTION 2
215
+
216
+typedef enum NPCM7xxMFTCaptureState {
217
+ /* capture succeeded with a valid CNT value. */
218
+ NPCM7XX_CAPTURE_SUCCEED,
219
+ /* capture stopped prematurely due to reaching CPCFG condition. */
220
+ NPCM7XX_CAPTURE_COMPARE_HIT,
221
+ /* capture fails since it reaches underflow condition for CNT. */
222
+ NPCM7XX_CAPTURE_UNDERFLOW,
223
+} NPCM7xxMFTCaptureState;
224
+
225
+static void npcm7xx_mft_reset(NPCM7xxMFTState *s)
226
+{
227
+ int i;
228
+
229
+ /* Only registers PRSC ~ INBSEL need to be reset. */
230
+ for (i = R_NPCM7XX_MFT_PRSC; i <= R_NPCM7XX_MFT_INBSEL; ++i) {
231
+ s->regs[i] = 0;
232
+ }
233
+}
234
+
235
+static void npcm7xx_mft_clear_interrupt(NPCM7xxMFTState *s, uint8_t iclr)
236
+{
237
+ /*
238
+ * Clear bits in ICTRL where corresponding bits in iclr is 1.
239
+ * Both iclr and ictrl are 8-bit regs. (See npcm7xx_mft_check_mem_op)
240
+ */
241
+ s->regs[R_NPCM7XX_MFT_ICTRL] &= ~iclr;
242
+}
243
+
244
+/*
245
+ * If the CPCFG's condition should be triggered during count down from
246
+ * NPCM7XX_MFT_MAX_CNT to src if compared to tgt, return the count when
247
+ * the condition is triggered.
248
+ * Otherwise return -1.
249
+ * Since tgt is uint16_t it must always <= NPCM7XX_MFT_MAX_CNT.
250
+ */
251
+static int npcm7xx_mft_compare(int32_t src, uint16_t tgt, uint8_t cpcfg)
252
+{
253
+ if (cpcfg & NPCM7XX_MFT_CPCFG_HIEN) {
254
+ return NPCM7XX_MFT_MAX_CNT;
255
+ }
256
+ if ((cpcfg & NPCM7XX_MFT_CPCFG_EQEN) && (src <= tgt)) {
257
+ return tgt;
258
+ }
259
+ if ((cpcfg & NPCM7XX_MFT_CPCFG_LOEN) && (tgt > 0) && (src < tgt)) {
260
+ return tgt - 1;
261
+ }
262
+
263
+ return -1;
264
+}
265
+
266
+/* Compute CNT according to corresponding fan's RPM. */
267
+static NPCM7xxMFTCaptureState npcm7xx_mft_compute_cnt(
268
+ Clock *clock, uint32_t max_rpm, uint32_t duty, uint16_t tgt,
269
+ uint8_t cpcfg, uint16_t *cnt)
270
+{
271
+ uint32_t rpm = (uint64_t)max_rpm * (uint64_t)duty / NPCM7XX_PWM_MAX_DUTY;
272
+ int32_t count;
273
+ int stopped;
274
+ NPCM7xxMFTCaptureState state;
275
+
276
+ if (rpm == 0) {
277
+ /*
42
+ /*
278
+ * If RPM = 0, capture won't happen. CNT will continue count down.
43
+ * Handle Hyp target regs first because some are special cases
279
+ * So it's effective equivalent to have a cnt > NPCM7XX_MFT_MAX_CNT
44
+ * which don't want the usual "not accessible from tgtmode" check.
280
+ */
45
+ */
281
+ count = NPCM7XX_MFT_MAX_CNT + 1;
46
+ switch (regno) {
282
+ } else {
47
+ case 16 ... 17: /* ELR_Hyp, SPSR_Hyp */
283
+ /*
48
+ if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
284
+ * RPM = revolution/min. The time for one revlution (in ns) is
49
+ goto undef;
285
+ * MINUTE_TO_NANOSECOND / RPM.
286
+ */
287
+ count = clock_ns_to_ticks(clock, (60 * NANOSECONDS_PER_SECOND) /
288
+ (rpm * NPCM7XX_MFT_PULSE_PER_REVOLUTION));
289
+ }
290
+
291
+ if (count > NPCM7XX_MFT_MAX_CNT) {
292
+ count = -1;
293
+ } else {
294
+ /* The CNT is a countdown value from NPCM7XX_MFT_MAX_CNT. */
295
+ count = NPCM7XX_MFT_MAX_CNT - count;
296
+ }
297
+ stopped = npcm7xx_mft_compare(count, tgt, cpcfg);
298
+ if (stopped == -1) {
299
+ if (count == -1) {
300
+ /* Underflow */
301
+ state = NPCM7XX_CAPTURE_UNDERFLOW;
302
+ } else {
303
+ state = NPCM7XX_CAPTURE_SUCCEED;
304
+ }
305
+ } else {
306
+ count = stopped;
307
+ state = NPCM7XX_CAPTURE_COMPARE_HIT;
308
+ }
309
+
310
+ if (count != -1) {
311
+ *cnt = count;
312
+ }
313
+ trace_npcm7xx_mft_rpm(clock->canonical_path, clock_get_hz(clock),
314
+ state, count, rpm, duty);
315
+ return state;
316
+}
317
+
318
+/*
319
+ * Capture Fan RPM and update CNT and CR registers accordingly.
320
+ * Raise IRQ if certain contidions are met in IEN.
321
+ */
322
+static void npcm7xx_mft_capture(NPCM7xxMFTState *s)
323
+{
324
+ int irq_level = 0;
325
+ NPCM7xxMFTCaptureState state;
326
+ int sel;
327
+ uint8_t cpcfg;
328
+
329
+ /*
330
+ * If not mode 5, the behavior is undefined. We just do nothing in this
331
+ * case.
332
+ */
333
+ if (!(s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_MODE5)) {
334
+ return;
335
+ }
336
+
337
+ /* Capture input A. */
338
+ if (s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_TAEN &&
339
+ s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C1CSEL) {
340
+ sel = s->regs[R_NPCM7XX_MFT_INASEL] & NPCM7XX_MFT_INASEL_SELA;
341
+ cpcfg = NPCM7XX_MFT_CPCFG_GET_A(s->regs[R_NPCM7XX_MFT_CPCFG]);
342
+ state = npcm7xx_mft_compute_cnt(s->clock_1,
343
+ sel ? s->max_rpm[2] : s->max_rpm[0],
344
+ sel ? s->duty[2] : s->duty[0],
345
+ s->regs[R_NPCM7XX_MFT_CPA],
346
+ cpcfg,
347
+ &s->regs[R_NPCM7XX_MFT_CNT1]);
348
+ switch (state) {
349
+ case NPCM7XX_CAPTURE_SUCCEED:
350
+ /* Interrupt on input capture on TAn transition - TAPND */
351
+ s->regs[R_NPCM7XX_MFT_CRA] = s->regs[R_NPCM7XX_MFT_CNT1];
352
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TAPND;
353
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TAIEN) {
354
+ irq_level = 1;
355
+ }
50
+ }
356
+ break;
51
+ break;
357
+
52
+ case 13:
358
+ case NPCM7XX_CAPTURE_COMPARE_HIT:
53
+ if (curmode != ARM_CPU_MODE_MON) {
359
+ /* Compare Hit - TEPND */
54
+ goto undef;
360
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TEPND;
361
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TEIEN) {
362
+ irq_level = 1;
363
+ }
55
+ }
364
+ break;
56
+ break;
365
+
366
+ case NPCM7XX_CAPTURE_UNDERFLOW:
367
+ /* Underflow - TCPND */
368
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TCPND;
369
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TCIEN) {
370
+ irq_level = 1;
371
+ }
372
+ break;
373
+
374
+ default:
57
+ default:
375
+ g_assert_not_reached();
58
+ g_assert_not_reached();
59
}
60
return;
61
}
62
@@ -XXX,XX +XXX,XX @@ static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
63
}
64
}
65
66
- if (tgtmode == ARM_CPU_MODE_HYP) {
67
- /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
68
- if (curmode != ARM_CPU_MODE_MON) {
69
- goto undef;
70
- }
71
- }
72
-
73
return;
74
75
undef:
76
@@ -XXX,XX +XXX,XX @@ void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
77
78
switch (regno) {
79
case 16: /* SPSRs */
80
- env->banked_spsr[bank_number(tgtmode)] = value;
81
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
82
+ /* Only happens for SPSR_Hyp access in Hyp mode */
83
+ env->spsr = value;
84
+ } else {
85
+ env->banked_spsr[bank_number(tgtmode)] = value;
376
+ }
86
+ }
377
+ }
87
break;
378
+
88
case 17: /* ELR_Hyp */
379
+ /* Capture input B. */
89
env->elr_el[2] = value;
380
+ if (s->regs[R_NPCM7XX_MFT_MCTRL] & NPCM7XX_MFT_MCTRL_TBEN &&
90
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
381
+ s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C2CSEL) {
91
382
+ sel = s->regs[R_NPCM7XX_MFT_INBSEL] & NPCM7XX_MFT_INBSEL_SELB;
92
switch (regno) {
383
+ cpcfg = NPCM7XX_MFT_CPCFG_GET_B(s->regs[R_NPCM7XX_MFT_CPCFG]);
93
case 16: /* SPSRs */
384
+ state = npcm7xx_mft_compute_cnt(s->clock_2,
94
- return env->banked_spsr[bank_number(tgtmode)];
385
+ sel ? s->max_rpm[3] : s->max_rpm[1],
95
+ if (tgtmode == (env->uncached_cpsr & CPSR_M)) {
386
+ sel ? s->duty[3] : s->duty[1],
96
+ /* Only happens for SPSR_Hyp access in Hyp mode */
387
+ s->regs[R_NPCM7XX_MFT_CPB],
97
+ return env->spsr;
388
+ cpcfg,
98
+ } else {
389
+ &s->regs[R_NPCM7XX_MFT_CNT2]);
99
+ return env->banked_spsr[bank_number(tgtmode)];
390
+ switch (state) {
391
+ case NPCM7XX_CAPTURE_SUCCEED:
392
+ /* Interrupt on input capture on TBn transition - TBPND */
393
+ s->regs[R_NPCM7XX_MFT_CRB] = s->regs[R_NPCM7XX_MFT_CNT2];
394
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TBPND;
395
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TBIEN) {
396
+ irq_level = 1;
397
+ }
398
+ break;
399
+
400
+ case NPCM7XX_CAPTURE_COMPARE_HIT:
401
+ /* Compare Hit - TFPND */
402
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TFPND;
403
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TFIEN) {
404
+ irq_level = 1;
405
+ }
406
+ break;
407
+
408
+ case NPCM7XX_CAPTURE_UNDERFLOW:
409
+ /* Underflow - TDPND */
410
+ s->regs[R_NPCM7XX_MFT_ICTRL] |= NPCM7XX_MFT_ICTRL_TDPND;
411
+ if (s->regs[R_NPCM7XX_MFT_IEN] & NPCM7XX_MFT_IEN_TDIEN) {
412
+ irq_level = 1;
413
+ }
414
+ break;
415
+
416
+ default:
417
+ g_assert_not_reached();
418
+ }
100
+ }
419
+ }
101
case 17: /* ELR_Hyp */
420
+
102
return env->elr_el[2];
421
+ trace_npcm7xx_mft_capture(DEVICE(s)->canonical_path, irq_level);
103
case 13:
422
+ qemu_set_irq(s->irq, irq_level);
104
diff --git a/target/arm/tcg/translate.c b/target/arm/tcg/translate.c
423
+}
424
+
425
+/* Update clock for counters. */
426
+static void npcm7xx_mft_update_clock(void *opaque, ClockEvent event)
427
+{
428
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
429
+ uint64_t prescaled_clock_period;
430
+
431
+ prescaled_clock_period = clock_get(s->clock_in) *
432
+ (s->regs[R_NPCM7XX_MFT_PRSC] + 1ULL);
433
+ trace_npcm7xx_mft_update_clock(s->clock_in->canonical_path,
434
+ s->regs[R_NPCM7XX_MFT_CKC],
435
+ clock_get(s->clock_in),
436
+ prescaled_clock_period);
437
+ /* Update clock 1 */
438
+ if (s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C1CSEL) {
439
+ /* Clock is prescaled. */
440
+ clock_update(s->clock_1, prescaled_clock_period);
441
+ } else {
442
+ /* Clock stopped. */
443
+ clock_update(s->clock_1, 0);
444
+ }
445
+ /* Update clock 2 */
446
+ if (s->regs[R_NPCM7XX_MFT_CKC] & NPCM7XX_MFT_CKC_C2CSEL) {
447
+ /* Clock is prescaled. */
448
+ clock_update(s->clock_2, prescaled_clock_period);
449
+ } else {
450
+ /* Clock stopped. */
451
+ clock_update(s->clock_2, 0);
452
+ }
453
+
454
+ npcm7xx_mft_capture(s);
455
+}
456
+
457
+static uint64_t npcm7xx_mft_read(void *opaque, hwaddr offset, unsigned size)
458
+{
459
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
460
+ uint16_t value = 0;
461
+
462
+ switch (offset) {
463
+ case A_NPCM7XX_MFT_ICLR:
464
+ qemu_log_mask(LOG_GUEST_ERROR,
465
+ "%s: register @ 0x%04" HWADDR_PRIx " is write-only\n",
466
+ __func__, offset);
467
+ break;
468
+
469
+ default:
470
+ value = s->regs[offset / 2];
471
+ }
472
+
473
+ trace_npcm7xx_mft_read(DEVICE(s)->canonical_path, offset, value);
474
+ return value;
475
+}
476
+
477
+static void npcm7xx_mft_write(void *opaque, hwaddr offset,
478
+ uint64_t v, unsigned size)
479
+{
480
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
481
+
482
+ trace_npcm7xx_mft_write(DEVICE(s)->canonical_path, offset, v);
483
+ switch (offset) {
484
+ case A_NPCM7XX_MFT_ICLR:
485
+ npcm7xx_mft_clear_interrupt(s, v);
486
+ break;
487
+
488
+ case A_NPCM7XX_MFT_CKC:
489
+ case A_NPCM7XX_MFT_PRSC:
490
+ s->regs[offset / 2] = v;
491
+ npcm7xx_mft_update_clock(s, ClockUpdate);
492
+ break;
493
+
494
+ default:
495
+ s->regs[offset / 2] = v;
496
+ npcm7xx_mft_capture(s);
497
+ break;
498
+ }
499
+}
500
+
501
+static bool npcm7xx_mft_check_mem_op(void *opaque, hwaddr offset,
502
+ unsigned size, bool is_write,
503
+ MemTxAttrs attrs)
504
+{
505
+ switch (offset) {
506
+ /* 16-bit registers. Must be accessed with 16-bit read/write.*/
507
+ case A_NPCM7XX_MFT_CNT1:
508
+ case A_NPCM7XX_MFT_CRA:
509
+ case A_NPCM7XX_MFT_CRB:
510
+ case A_NPCM7XX_MFT_CNT2:
511
+ case A_NPCM7XX_MFT_CPA:
512
+ case A_NPCM7XX_MFT_CPB:
513
+ return size == 2;
514
+
515
+ /* 8-bit registers. Must be accessed with 8-bit read/write.*/
516
+ case A_NPCM7XX_MFT_PRSC:
517
+ case A_NPCM7XX_MFT_CKC:
518
+ case A_NPCM7XX_MFT_MCTRL:
519
+ case A_NPCM7XX_MFT_ICTRL:
520
+ case A_NPCM7XX_MFT_ICLR:
521
+ case A_NPCM7XX_MFT_IEN:
522
+ case A_NPCM7XX_MFT_CPCFG:
523
+ case A_NPCM7XX_MFT_INASEL:
524
+ case A_NPCM7XX_MFT_INBSEL:
525
+ return size == 1;
526
+
527
+ default:
528
+ /* Invalid registers. */
529
+ return false;
530
+ }
531
+}
532
+
533
+static void npcm7xx_mft_get_max_rpm(Object *obj, Visitor *v, const char *name,
534
+ void *opaque, Error **errp)
535
+{
536
+ visit_type_uint32(v, name, (uint32_t *)opaque, errp);
537
+}
538
+
539
+static void npcm7xx_mft_set_max_rpm(Object *obj, Visitor *v, const char *name,
540
+ void *opaque, Error **errp)
541
+{
542
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
543
+ uint32_t *max_rpm = opaque;
544
+ uint32_t value;
545
+
546
+ if (!visit_type_uint32(v, name, &value, errp)) {
547
+ return;
548
+ }
549
+
550
+ *max_rpm = value;
551
+ npcm7xx_mft_capture(s);
552
+}
553
+
554
+static void npcm7xx_mft_duty_handler(void *opaque, int n, int value)
555
+{
556
+ NPCM7xxMFTState *s = NPCM7XX_MFT(opaque);
557
+
558
+ trace_npcm7xx_mft_set_duty(DEVICE(s)->canonical_path, n, value);
559
+ s->duty[n] = value;
560
+ npcm7xx_mft_capture(s);
561
+}
562
+
563
+static const struct MemoryRegionOps npcm7xx_mft_ops = {
564
+ .read = npcm7xx_mft_read,
565
+ .write = npcm7xx_mft_write,
566
+ .endianness = DEVICE_LITTLE_ENDIAN,
567
+ .valid = {
568
+ .min_access_size = 1,
569
+ .max_access_size = 2,
570
+ .unaligned = false,
571
+ .accepts = npcm7xx_mft_check_mem_op,
572
+ },
573
+};
574
+
575
+static void npcm7xx_mft_enter_reset(Object *obj, ResetType type)
576
+{
577
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
578
+
579
+ npcm7xx_mft_reset(s);
580
+}
581
+
582
+static void npcm7xx_mft_hold_reset(Object *obj)
583
+{
584
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
585
+
586
+ qemu_irq_lower(s->irq);
587
+}
588
+
589
+static void npcm7xx_mft_init(Object *obj)
590
+{
591
+ NPCM7xxMFTState *s = NPCM7XX_MFT(obj);
592
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
593
+ DeviceState *dev = DEVICE(obj);
594
+
595
+ memory_region_init_io(&s->iomem, obj, &npcm7xx_mft_ops, s,
596
+ TYPE_NPCM7XX_MFT, 4 * KiB);
597
+ sysbus_init_mmio(sbd, &s->iomem);
598
+ sysbus_init_irq(sbd, &s->irq);
599
+ s->clock_in = qdev_init_clock_in(dev, "clock-in", npcm7xx_mft_update_clock,
600
+ s, ClockUpdate);
601
+ s->clock_1 = qdev_init_clock_out(dev, "clock1");
602
+ s->clock_2 = qdev_init_clock_out(dev, "clock2");
603
+
604
+ for (int i = 0; i < NPCM7XX_PWM_PER_MODULE; ++i) {
605
+ object_property_add(obj, "max_rpm[*]", "uint32",
606
+ npcm7xx_mft_get_max_rpm,
607
+ npcm7xx_mft_set_max_rpm,
608
+ NULL, &s->max_rpm[i]);
609
+ }
610
+ qdev_init_gpio_in_named(dev, npcm7xx_mft_duty_handler, "duty",
611
+ NPCM7XX_MFT_FANIN_COUNT);
612
+}
613
+
614
+static const VMStateDescription vmstate_npcm7xx_mft = {
615
+ .name = "npcm7xx-mft-module",
616
+ .version_id = 0,
617
+ .minimum_version_id = 0,
618
+ .fields = (VMStateField[]) {
619
+ VMSTATE_CLOCK(clock_in, NPCM7xxMFTState),
620
+ VMSTATE_CLOCK(clock_1, NPCM7xxMFTState),
621
+ VMSTATE_CLOCK(clock_2, NPCM7xxMFTState),
622
+ VMSTATE_UINT16_ARRAY(regs, NPCM7xxMFTState, NPCM7XX_MFT_NR_REGS),
623
+ VMSTATE_UINT32_ARRAY(max_rpm, NPCM7xxMFTState, NPCM7XX_MFT_FANIN_COUNT),
624
+ VMSTATE_UINT32_ARRAY(duty, NPCM7xxMFTState, NPCM7XX_MFT_FANIN_COUNT),
625
+ VMSTATE_END_OF_LIST(),
626
+ },
627
+};
628
+
629
+static void npcm7xx_mft_class_init(ObjectClass *klass, void *data)
630
+{
631
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
632
+ DeviceClass *dc = DEVICE_CLASS(klass);
633
+
634
+ dc->desc = "NPCM7xx MFT Controller";
635
+ dc->vmsd = &vmstate_npcm7xx_mft;
636
+ rc->phases.enter = npcm7xx_mft_enter_reset;
637
+ rc->phases.hold = npcm7xx_mft_hold_reset;
638
+}
639
+
640
+static const TypeInfo npcm7xx_mft_info = {
641
+ .name = TYPE_NPCM7XX_MFT,
642
+ .parent = TYPE_SYS_BUS_DEVICE,
643
+ .instance_size = sizeof(NPCM7xxMFTState),
644
+ .class_init = npcm7xx_mft_class_init,
645
+ .instance_init = npcm7xx_mft_init,
646
+};
647
+
648
+static void npcm7xx_mft_register_type(void)
649
+{
650
+ type_register_static(&npcm7xx_mft_info);
651
+}
652
+type_init(npcm7xx_mft_register_type);
653
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
654
index XXXXXXX..XXXXXXX 100644
105
index XXXXXXX..XXXXXXX 100644
655
--- a/hw/misc/meson.build
106
--- a/target/arm/tcg/translate.c
656
+++ b/hw/misc/meson.build
107
+++ b/target/arm/tcg/translate.c
657
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_MAINSTONE', if_true: files('mst_fpga.c'))
108
@@ -XXX,XX +XXX,XX @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
658
softmmu_ss.add(when: 'CONFIG_NPCM7XX', if_true: files(
109
break;
659
'npcm7xx_clk.c',
110
case ARM_CPU_MODE_HYP:
660
'npcm7xx_gcr.c',
111
/*
661
+ 'npcm7xx_mft.c',
112
- * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
662
'npcm7xx_pwm.c',
113
- * (and so we can forbid accesses from EL2 or below). elr_hyp
663
'npcm7xx_rng.c',
114
- * can be accessed also from Hyp mode, so forbid accesses from
664
))
115
- * EL0 or EL1.
665
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
116
+ * r13_hyp can only be accessed from Monitor mode, and so we
666
index XXXXXXX..XXXXXXX 100644
117
+ * can forbid accesses from EL2 or below.
667
--- a/hw/misc/trace-events
118
+ * elr_hyp can be accessed also from Hyp mode, so forbid
668
+++ b/hw/misc/trace-events
119
+ * accesses from EL0 or EL1.
669
@@ -XXX,XX +XXX,XX @@ npcm7xx_clk_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " valu
120
+ * SPSR_hyp is supposed to be in the same category as r13_hyp
670
npcm7xx_gcr_read(uint64_t offset, uint32_t value) " offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
121
+ * and UNPREDICTABLE if accessed from anything except Monitor
671
npcm7xx_gcr_write(uint64_t offset, uint32_t value) "offset: 0x%04" PRIx64 " value: 0x%08" PRIx32
122
+ * mode. However there is some real-world code that will do
672
123
+ * it because at least some hardware happens to permit the
673
+# npcm7xx_mft.c
124
+ * access. (Notably a standard Cortex-R52 startup code fragment
674
+npcm7xx_mft_read(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
125
+ * does this.) So we permit SPSR_hyp from Hyp mode also, to allow
675
+npcm7xx_mft_write(const char *name, uint64_t offset, uint16_t value) "%s: offset: 0x%04" PRIx64 " value: 0x%04" PRIx16
126
+ * this (incorrect) guest code to run.
676
+npcm7xx_mft_rpm(const char *clock, uint32_t clock_hz, int state, int32_t cnt, uint32_t rpm, uint32_t duty) " fan clk: %s clock_hz: %" PRIu32 ", state: %d, cnt: %" PRIi32 ", rpm: %" PRIu32 ", duty: %" PRIu32
127
*/
677
+npcm7xx_mft_capture(const char *name, int irq_level) "%s: level: %d"
128
- if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
678
+npcm7xx_mft_update_clock(const char *name, uint16_t sel, uint64_t clock_period, uint64_t prescaled_clock_period) "%s: sel: 0x%02" PRIx16 ", period: %" PRIu64 ", prescaled: %" PRIu64
129
- (s->current_el < 3 && *regno != 17)) {
679
+npcm7xx_mft_set_duty(const char *name, int n, int value) "%s[%d]: %d"
130
+ if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2
680
+
131
+ || (s->current_el < 3 && *regno != 16 && *regno != 17)) {
681
# npcm7xx_rng.c
132
goto undef;
682
npcm7xx_rng_read(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
133
}
683
npcm7xx_rng_write(uint64_t offset, uint64_t value, unsigned size) "offset: 0x%04" PRIx64 " value: 0x%02" PRIx64 " size: %u"
134
break;
684
--
135
--
685
2.20.1
136
2.34.1
686
687
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
We currently guard the CFG3 register read with
2
(scc_partno(s) == 0x524 && scc_partno(s) == 0x547)
3
which is clearly wrong as it is never true.
2
4
3
If the asid is not set, do not attempt to locate the key directly
5
This register is present on all board types except AN524
4
as all inserted keys have a valid asid.
6
and AN527; correct the condition.
5
7
6
Use g_hash_table_foreach_remove instead.
8
Fixes: 6ac80818941829c0 ("hw/misc/mps2-scc: Implement changes for AN547")
7
8
Signed-off-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20210309102742.30442-5-eric.auger@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
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
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20240206132931.38376-6-peter.maydell@linaro.org
12
---
13
---
13
hw/arm/smmu-common.c | 2 +-
14
hw/misc/mps2-scc.c | 2 +-
14
1 file changed, 1 insertion(+), 1 deletion(-)
15
1 file changed, 1 insertion(+), 1 deletion(-)
15
16
16
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
17
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
17
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
18
--- a/hw/arm/smmu-common.c
19
--- a/hw/misc/mps2-scc.c
19
+++ b/hw/arm/smmu-common.c
20
+++ b/hw/misc/mps2-scc.c
20
@@ -XXX,XX +XXX,XX @@ inline void
21
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
21
smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
22
r = s->cfg2;
22
uint8_t tg, uint64_t num_pages, uint8_t ttl)
23
break;
23
{
24
case A_CFG3:
24
- if (ttl && (num_pages == 1)) {
25
- if (scc_partno(s) == 0x524 && scc_partno(s) == 0x547) {
25
+ if (ttl && (num_pages == 1) && (asid >= 0)) {
26
+ if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
26
SMMUIOTLBKey key = smmu_get_iotlb_key(asid, iova, tg, ttl);
27
/* CFG3 reserved on AN524 */
27
28
goto bad_offset;
28
g_hash_table_remove(s->iotlb, &key);
29
}
29
--
30
--
30
2.20.1
31
2.34.1
31
32
32
33
diff view generated by jsdifflib
1
The template header is now included only once; just inline its contents
1
The MPS SCC device has a lot of different flavours for the various
2
in hw/display/pxa2xx_lcd.c.
2
different MPS FPGA images, which look mostly similar but have
3
differences in how particular registers are handled. Currently we
4
deal with this with a lot of open-coded checks on scc_partno(), but
5
as we add more board types this is getting a bit hard to read.
6
7
Factor out the conditions into some functions which we can
8
give more descriptive names to.
3
9
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20210211141515.8755-10-peter.maydell@linaro.org
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20240206132931.38376-7-peter.maydell@linaro.org
7
---
14
---
8
hw/display/pxa2xx_template.h | 434 -----------------------------------
15
hw/misc/mps2-scc.c | 45 +++++++++++++++++++++++++++++++--------------
9
hw/display/pxa2xx_lcd.c | 427 +++++++++++++++++++++++++++++++++-
16
1 file changed, 31 insertions(+), 14 deletions(-)
10
2 files changed, 425 insertions(+), 436 deletions(-)
11
delete mode 100644 hw/display/pxa2xx_template.h
12
17
13
diff --git a/hw/display/pxa2xx_template.h b/hw/display/pxa2xx_template.h
18
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
14
deleted file mode 100644
15
index XXXXXXX..XXXXXXX
16
--- a/hw/display/pxa2xx_template.h
17
+++ /dev/null
18
@@ -XXX,XX +XXX,XX @@
19
-/*
20
- * Intel XScale PXA255/270 LCDC emulation.
21
- *
22
- * Copyright (c) 2006 Openedhand Ltd.
23
- * Written by Andrzej Zaborowski <balrog@zabor.org>
24
- *
25
- * This code is licensed under the GPLv2.
26
- *
27
- * Framebuffer format conversion routines.
28
- */
29
-
30
-# define SKIP_PIXEL(to) do { to += deststep; } while (0)
31
-# define COPY_PIXEL(to, from) \
32
- do { \
33
- *(uint32_t *) to = from; \
34
- SKIP_PIXEL(to); \
35
- } while (0)
36
-
37
-#ifdef HOST_WORDS_BIGENDIAN
38
-# define SWAP_WORDS 1
39
-#endif
40
-
41
-#define FN_2(x) FN(x + 1) FN(x)
42
-#define FN_4(x) FN_2(x + 2) FN_2(x)
43
-
44
-static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
45
- int width, int deststep)
46
-{
47
- uint32_t *palette = opaque;
48
- uint32_t data;
49
- while (width > 0) {
50
- data = *(uint32_t *) src;
51
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
52
-#ifdef SWAP_WORDS
53
- FN_4(12)
54
- FN_4(8)
55
- FN_4(4)
56
- FN_4(0)
57
-#else
58
- FN_4(0)
59
- FN_4(4)
60
- FN_4(8)
61
- FN_4(12)
62
-#endif
63
-#undef FN
64
- width -= 16;
65
- src += 4;
66
- }
67
-}
68
-
69
-static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
70
- int width, int deststep)
71
-{
72
- uint32_t *palette = opaque;
73
- uint32_t data;
74
- while (width > 0) {
75
- data = *(uint32_t *) src;
76
-#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
77
-#ifdef SWAP_WORDS
78
- FN_2(6)
79
- FN_2(4)
80
- FN_2(2)
81
- FN_2(0)
82
-#else
83
- FN_2(0)
84
- FN_2(2)
85
- FN_2(4)
86
- FN_2(6)
87
-#endif
88
-#undef FN
89
- width -= 8;
90
- src += 4;
91
- }
92
-}
93
-
94
-static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
95
- int width, int deststep)
96
-{
97
- uint32_t *palette = opaque;
98
- uint32_t data;
99
- while (width > 0) {
100
- data = *(uint32_t *) src;
101
-#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
102
-#ifdef SWAP_WORDS
103
- FN(24)
104
- FN(16)
105
- FN(8)
106
- FN(0)
107
-#else
108
- FN(0)
109
- FN(8)
110
- FN(16)
111
- FN(24)
112
-#endif
113
-#undef FN
114
- width -= 4;
115
- src += 4;
116
- }
117
-}
118
-
119
-static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
120
- int width, int deststep)
121
-{
122
- uint32_t data;
123
- unsigned int r, g, b;
124
- while (width > 0) {
125
- data = *(uint32_t *) src;
126
-#ifdef SWAP_WORDS
127
- data = bswap32(data);
128
-#endif
129
- b = (data & 0x1f) << 3;
130
- data >>= 5;
131
- g = (data & 0x3f) << 2;
132
- data >>= 6;
133
- r = (data & 0x1f) << 3;
134
- data >>= 5;
135
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
136
- b = (data & 0x1f) << 3;
137
- data >>= 5;
138
- g = (data & 0x3f) << 2;
139
- data >>= 6;
140
- r = (data & 0x1f) << 3;
141
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
142
- width -= 2;
143
- src += 4;
144
- }
145
-}
146
-
147
-static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
148
- int width, int deststep)
149
-{
150
- uint32_t data;
151
- unsigned int r, g, b;
152
- while (width > 0) {
153
- data = *(uint32_t *) src;
154
-#ifdef SWAP_WORDS
155
- data = bswap32(data);
156
-#endif
157
- b = (data & 0x1f) << 3;
158
- data >>= 5;
159
- g = (data & 0x1f) << 3;
160
- data >>= 5;
161
- r = (data & 0x1f) << 3;
162
- data >>= 5;
163
- if (data & 1) {
164
- SKIP_PIXEL(dest);
165
- } else {
166
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
167
- }
168
- data >>= 1;
169
- b = (data & 0x1f) << 3;
170
- data >>= 5;
171
- g = (data & 0x1f) << 3;
172
- data >>= 5;
173
- r = (data & 0x1f) << 3;
174
- data >>= 5;
175
- if (data & 1) {
176
- SKIP_PIXEL(dest);
177
- } else {
178
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
179
- }
180
- width -= 2;
181
- src += 4;
182
- }
183
-}
184
-
185
-static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
186
- int width, int deststep)
187
-{
188
- uint32_t data;
189
- unsigned int r, g, b;
190
- while (width > 0) {
191
- data = *(uint32_t *) src;
192
-#ifdef SWAP_WORDS
193
- data = bswap32(data);
194
-#endif
195
- b = (data & 0x3f) << 2;
196
- data >>= 6;
197
- g = (data & 0x3f) << 2;
198
- data >>= 6;
199
- r = (data & 0x3f) << 2;
200
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
201
- width -= 1;
202
- src += 4;
203
- }
204
-}
205
-
206
-/* The wicked packed format */
207
-static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
208
- int width, int deststep)
209
-{
210
- uint32_t data[3];
211
- unsigned int r, g, b;
212
- while (width > 0) {
213
- data[0] = *(uint32_t *) src;
214
- src += 4;
215
- data[1] = *(uint32_t *) src;
216
- src += 4;
217
- data[2] = *(uint32_t *) src;
218
- src += 4;
219
-#ifdef SWAP_WORDS
220
- data[0] = bswap32(data[0]);
221
- data[1] = bswap32(data[1]);
222
- data[2] = bswap32(data[2]);
223
-#endif
224
- b = (data[0] & 0x3f) << 2;
225
- data[0] >>= 6;
226
- g = (data[0] & 0x3f) << 2;
227
- data[0] >>= 6;
228
- r = (data[0] & 0x3f) << 2;
229
- data[0] >>= 12;
230
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
231
- b = (data[0] & 0x3f) << 2;
232
- data[0] >>= 6;
233
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
234
- data[1] >>= 4;
235
- r = (data[1] & 0x3f) << 2;
236
- data[1] >>= 12;
237
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
238
- b = (data[1] & 0x3f) << 2;
239
- data[1] >>= 6;
240
- g = (data[1] & 0x3f) << 2;
241
- data[1] >>= 6;
242
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
243
- data[2] >>= 8;
244
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
245
- b = (data[2] & 0x3f) << 2;
246
- data[2] >>= 6;
247
- g = (data[2] & 0x3f) << 2;
248
- data[2] >>= 6;
249
- r = data[2] << 2;
250
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
251
- width -= 4;
252
- }
253
-}
254
-
255
-static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
256
- int width, int deststep)
257
-{
258
- uint32_t data;
259
- unsigned int r, g, b;
260
- while (width > 0) {
261
- data = *(uint32_t *) src;
262
-#ifdef SWAP_WORDS
263
- data = bswap32(data);
264
-#endif
265
- b = (data & 0x3f) << 2;
266
- data >>= 6;
267
- g = (data & 0x3f) << 2;
268
- data >>= 6;
269
- r = (data & 0x3f) << 2;
270
- data >>= 6;
271
- if (data & 1) {
272
- SKIP_PIXEL(dest);
273
- } else {
274
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
275
- }
276
- width -= 1;
277
- src += 4;
278
- }
279
-}
280
-
281
-/* The wicked packed format */
282
-static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
283
- int width, int deststep)
284
-{
285
- uint32_t data[3];
286
- unsigned int r, g, b;
287
- while (width > 0) {
288
- data[0] = *(uint32_t *) src;
289
- src += 4;
290
- data[1] = *(uint32_t *) src;
291
- src += 4;
292
- data[2] = *(uint32_t *) src;
293
- src += 4;
294
-# ifdef SWAP_WORDS
295
- data[0] = bswap32(data[0]);
296
- data[1] = bswap32(data[1]);
297
- data[2] = bswap32(data[2]);
298
-# endif
299
- b = (data[0] & 0x3f) << 2;
300
- data[0] >>= 6;
301
- g = (data[0] & 0x3f) << 2;
302
- data[0] >>= 6;
303
- r = (data[0] & 0x3f) << 2;
304
- data[0] >>= 6;
305
- if (data[0] & 1) {
306
- SKIP_PIXEL(dest);
307
- } else {
308
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
309
- }
310
- data[0] >>= 6;
311
- b = (data[0] & 0x3f) << 2;
312
- data[0] >>= 6;
313
- g = ((data[1] & 0xf) << 4) | (data[0] << 2);
314
- data[1] >>= 4;
315
- r = (data[1] & 0x3f) << 2;
316
- data[1] >>= 6;
317
- if (data[1] & 1) {
318
- SKIP_PIXEL(dest);
319
- } else {
320
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
321
- }
322
- data[1] >>= 6;
323
- b = (data[1] & 0x3f) << 2;
324
- data[1] >>= 6;
325
- g = (data[1] & 0x3f) << 2;
326
- data[1] >>= 6;
327
- r = ((data[2] & 0x3) << 6) | (data[1] << 2);
328
- data[2] >>= 2;
329
- if (data[2] & 1) {
330
- SKIP_PIXEL(dest);
331
- } else {
332
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
333
- }
334
- data[2] >>= 6;
335
- b = (data[2] & 0x3f) << 2;
336
- data[2] >>= 6;
337
- g = (data[2] & 0x3f) << 2;
338
- data[2] >>= 6;
339
- r = data[2] << 2;
340
- data[2] >>= 6;
341
- if (data[2] & 1) {
342
- SKIP_PIXEL(dest);
343
- } else {
344
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
345
- }
346
- width -= 4;
347
- }
348
-}
349
-
350
-static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
351
- int width, int deststep)
352
-{
353
- uint32_t data;
354
- unsigned int r, g, b;
355
- while (width > 0) {
356
- data = *(uint32_t *) src;
357
-#ifdef SWAP_WORDS
358
- data = bswap32(data);
359
-#endif
360
- b = data & 0xff;
361
- data >>= 8;
362
- g = data & 0xff;
363
- data >>= 8;
364
- r = data & 0xff;
365
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
366
- width -= 1;
367
- src += 4;
368
- }
369
-}
370
-
371
-static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
372
- int width, int deststep)
373
-{
374
- uint32_t data;
375
- unsigned int r, g, b;
376
- while (width > 0) {
377
- data = *(uint32_t *) src;
378
-#ifdef SWAP_WORDS
379
- data = bswap32(data);
380
-#endif
381
- b = (data & 0x7f) << 1;
382
- data >>= 7;
383
- g = data & 0xff;
384
- data >>= 8;
385
- r = data & 0xff;
386
- data >>= 8;
387
- if (data & 1) {
388
- SKIP_PIXEL(dest);
389
- } else {
390
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
391
- }
392
- width -= 1;
393
- src += 4;
394
- }
395
-}
396
-
397
-static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
398
- int width, int deststep)
399
-{
400
- uint32_t data;
401
- unsigned int r, g, b;
402
- while (width > 0) {
403
- data = *(uint32_t *) src;
404
-#ifdef SWAP_WORDS
405
- data = bswap32(data);
406
-#endif
407
- b = data & 0xff;
408
- data >>= 8;
409
- g = data & 0xff;
410
- data >>= 8;
411
- r = data & 0xff;
412
- data >>= 8;
413
- if (data & 1) {
414
- SKIP_PIXEL(dest);
415
- } else {
416
- COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
417
- }
418
- width -= 1;
419
- src += 4;
420
- }
421
-}
422
-
423
-/* Overlay planes disabled, no transparency */
424
-static drawfn pxa2xx_draw_fn_32[16] = {
425
- [0 ... 0xf] = NULL,
426
- [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
427
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
428
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
429
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
430
- [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
431
- [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
432
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
433
-};
434
-
435
-/* Overlay planes enabled, transparency used */
436
-static drawfn pxa2xx_draw_fn_32t[16] = {
437
- [0 ... 0xf] = NULL,
438
- [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
439
- [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
440
- [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
441
- [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
442
- [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
443
- [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
444
- [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
445
-};
446
-
447
-#undef COPY_PIXEL
448
-#undef SKIP_PIXEL
449
-
450
-#ifdef SWAP_WORDS
451
-# undef SWAP_WORDS
452
-#endif
453
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
454
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
455
--- a/hw/display/pxa2xx_lcd.c
20
--- a/hw/misc/mps2-scc.c
456
+++ b/hw/display/pxa2xx_lcd.c
21
+++ b/hw/misc/mps2-scc.c
457
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
22
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
458
/* Size of a pixel in the QEMU UI output surface, in bytes */
23
return extract32(s->id, 4, 8);
459
#define DEST_PIXEL_WIDTH 4
24
}
460
25
461
-#define BITS 32
26
+/* Is CFG_REG2 present? */
462
-#include "pxa2xx_template.h"
27
+static bool have_cfg2(MPS2SCC *s)
463
+/* Line drawing code to handle the various possible guest pixel formats */
464
+
465
+# define SKIP_PIXEL(to) do { to += deststep; } while (0)
466
+# define COPY_PIXEL(to, from) \
467
+ do { \
468
+ *(uint32_t *) to = from; \
469
+ SKIP_PIXEL(to); \
470
+ } while (0)
471
+
472
+#ifdef HOST_WORDS_BIGENDIAN
473
+# define SWAP_WORDS 1
474
+#endif
475
+
476
+#define FN_2(x) FN(x + 1) FN(x)
477
+#define FN_4(x) FN_2(x + 2) FN_2(x)
478
+
479
+static void pxa2xx_draw_line2(void *opaque, uint8_t *dest, const uint8_t *src,
480
+ int width, int deststep)
481
+{
28
+{
482
+ uint32_t *palette = opaque;
29
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
483
+ uint32_t data;
484
+ while (width > 0) {
485
+ data = *(uint32_t *) src;
486
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 2)) & 3]);
487
+#ifdef SWAP_WORDS
488
+ FN_4(12)
489
+ FN_4(8)
490
+ FN_4(4)
491
+ FN_4(0)
492
+#else
493
+ FN_4(0)
494
+ FN_4(4)
495
+ FN_4(8)
496
+ FN_4(12)
497
+#endif
498
+#undef FN
499
+ width -= 16;
500
+ src += 4;
501
+ }
502
+}
30
+}
503
+
31
+
504
+static void pxa2xx_draw_line4(void *opaque, uint8_t *dest, const uint8_t *src,
32
+/* Is CFG_REG3 present? */
505
+ int width, int deststep)
33
+static bool have_cfg3(MPS2SCC *s)
506
+{
34
+{
507
+ uint32_t *palette = opaque;
35
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
508
+ uint32_t data;
509
+ while (width > 0) {
510
+ data = *(uint32_t *) src;
511
+#define FN(x) COPY_PIXEL(dest, palette[(data >> ((x) * 4)) & 0xf]);
512
+#ifdef SWAP_WORDS
513
+ FN_2(6)
514
+ FN_2(4)
515
+ FN_2(2)
516
+ FN_2(0)
517
+#else
518
+ FN_2(0)
519
+ FN_2(2)
520
+ FN_2(4)
521
+ FN_2(6)
522
+#endif
523
+#undef FN
524
+ width -= 8;
525
+ src += 4;
526
+ }
527
+}
36
+}
528
+
37
+
529
+static void pxa2xx_draw_line8(void *opaque, uint8_t *dest, const uint8_t *src,
38
+/* Is CFG_REG5 present? */
530
+ int width, int deststep)
39
+static bool have_cfg5(MPS2SCC *s)
531
+{
40
+{
532
+ uint32_t *palette = opaque;
41
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
533
+ uint32_t data;
534
+ while (width > 0) {
535
+ data = *(uint32_t *) src;
536
+#define FN(x) COPY_PIXEL(dest, palette[(data >> (x)) & 0xff]);
537
+#ifdef SWAP_WORDS
538
+ FN(24)
539
+ FN(16)
540
+ FN(8)
541
+ FN(0)
542
+#else
543
+ FN(0)
544
+ FN(8)
545
+ FN(16)
546
+ FN(24)
547
+#endif
548
+#undef FN
549
+ width -= 4;
550
+ src += 4;
551
+ }
552
+}
42
+}
553
+
43
+
554
+static void pxa2xx_draw_line16(void *opaque, uint8_t *dest, const uint8_t *src,
44
+/* Is CFG_REG6 present? */
555
+ int width, int deststep)
45
+static bool have_cfg6(MPS2SCC *s)
556
+{
46
+{
557
+ uint32_t data;
47
+ return scc_partno(s) == 0x524;
558
+ unsigned int r, g, b;
559
+ while (width > 0) {
560
+ data = *(uint32_t *) src;
561
+#ifdef SWAP_WORDS
562
+ data = bswap32(data);
563
+#endif
564
+ b = (data & 0x1f) << 3;
565
+ data >>= 5;
566
+ g = (data & 0x3f) << 2;
567
+ data >>= 6;
568
+ r = (data & 0x1f) << 3;
569
+ data >>= 5;
570
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
571
+ b = (data & 0x1f) << 3;
572
+ data >>= 5;
573
+ g = (data & 0x3f) << 2;
574
+ data >>= 6;
575
+ r = (data & 0x1f) << 3;
576
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
577
+ width -= 2;
578
+ src += 4;
579
+ }
580
+}
48
+}
581
+
49
+
582
+static void pxa2xx_draw_line16t(void *opaque, uint8_t *dest, const uint8_t *src,
50
/* Handle a write via the SYS_CFG channel to the specified function/device.
583
+ int width, int deststep)
51
* Return false on error (reported to guest via SYS_CFGCTRL ERROR bit).
584
+{
52
*/
585
+ uint32_t data;
53
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
586
+ unsigned int r, g, b;
54
r = s->cfg1;
587
+ while (width > 0) {
55
break;
588
+ data = *(uint32_t *) src;
56
case A_CFG2:
589
+#ifdef SWAP_WORDS
57
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
590
+ data = bswap32(data);
58
- /* CFG2 reserved on other boards */
591
+#endif
59
+ if (!have_cfg2(s)) {
592
+ b = (data & 0x1f) << 3;
60
goto bad_offset;
593
+ data >>= 5;
61
}
594
+ g = (data & 0x1f) << 3;
62
r = s->cfg2;
595
+ data >>= 5;
63
break;
596
+ r = (data & 0x1f) << 3;
64
case A_CFG3:
597
+ data >>= 5;
65
- if (scc_partno(s) == 0x524 || scc_partno(s) == 0x547) {
598
+ if (data & 1) {
66
- /* CFG3 reserved on AN524 */
599
+ SKIP_PIXEL(dest);
67
+ if (!have_cfg3(s)) {
600
+ } else {
68
goto bad_offset;
601
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
69
}
602
+ }
70
/* These are user-settable DIP switches on the board. We don't
603
+ data >>= 1;
71
@@ -XXX,XX +XXX,XX @@ static uint64_t mps2_scc_read(void *opaque, hwaddr offset, unsigned size)
604
+ b = (data & 0x1f) << 3;
72
r = s->cfg4;
605
+ data >>= 5;
73
break;
606
+ g = (data & 0x1f) << 3;
74
case A_CFG5:
607
+ data >>= 5;
75
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
608
+ r = (data & 0x1f) << 3;
76
- /* CFG5 reserved on other boards */
609
+ data >>= 5;
77
+ if (!have_cfg5(s)) {
610
+ if (data & 1) {
78
goto bad_offset;
611
+ SKIP_PIXEL(dest);
79
}
612
+ } else {
80
r = s->cfg5;
613
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
81
break;
614
+ }
82
case A_CFG6:
615
+ width -= 2;
83
- if (scc_partno(s) != 0x524) {
616
+ src += 4;
84
- /* CFG6 reserved on other boards */
617
+ }
85
+ if (!have_cfg6(s)) {
618
+}
86
goto bad_offset;
619
+
87
}
620
+static void pxa2xx_draw_line18(void *opaque, uint8_t *dest, const uint8_t *src,
88
r = s->cfg6;
621
+ int width, int deststep)
89
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
622
+{
90
}
623
+ uint32_t data;
91
break;
624
+ unsigned int r, g, b;
92
case A_CFG2:
625
+ while (width > 0) {
93
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
626
+ data = *(uint32_t *) src;
94
- /* CFG2 reserved on other boards */
627
+#ifdef SWAP_WORDS
95
+ if (!have_cfg2(s)) {
628
+ data = bswap32(data);
96
goto bad_offset;
629
+#endif
97
}
630
+ b = (data & 0x3f) << 2;
98
/* AN524: QSPI Select signal */
631
+ data >>= 6;
99
s->cfg2 = value;
632
+ g = (data & 0x3f) << 2;
100
break;
633
+ data >>= 6;
101
case A_CFG5:
634
+ r = (data & 0x3f) << 2;
102
- if (scc_partno(s) != 0x524 && scc_partno(s) != 0x547) {
635
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
103
- /* CFG5 reserved on other boards */
636
+ width -= 1;
104
+ if (!have_cfg5(s)) {
637
+ src += 4;
105
goto bad_offset;
638
+ }
106
}
639
+}
107
/* AN524: ACLK frequency in Hz */
640
+
108
s->cfg5 = value;
641
+/* The wicked packed format */
109
break;
642
+static void pxa2xx_draw_line18p(void *opaque, uint8_t *dest, const uint8_t *src,
110
case A_CFG6:
643
+ int width, int deststep)
111
- if (scc_partno(s) != 0x524) {
644
+{
112
- /* CFG6 reserved on other boards */
645
+ uint32_t data[3];
113
+ if (!have_cfg6(s)) {
646
+ unsigned int r, g, b;
114
goto bad_offset;
647
+ while (width > 0) {
115
}
648
+ data[0] = *(uint32_t *) src;
116
/* AN524: Clock divider for BRAM */
649
+ src += 4;
650
+ data[1] = *(uint32_t *) src;
651
+ src += 4;
652
+ data[2] = *(uint32_t *) src;
653
+ src += 4;
654
+#ifdef SWAP_WORDS
655
+ data[0] = bswap32(data[0]);
656
+ data[1] = bswap32(data[1]);
657
+ data[2] = bswap32(data[2]);
658
+#endif
659
+ b = (data[0] & 0x3f) << 2;
660
+ data[0] >>= 6;
661
+ g = (data[0] & 0x3f) << 2;
662
+ data[0] >>= 6;
663
+ r = (data[0] & 0x3f) << 2;
664
+ data[0] >>= 12;
665
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
666
+ b = (data[0] & 0x3f) << 2;
667
+ data[0] >>= 6;
668
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
669
+ data[1] >>= 4;
670
+ r = (data[1] & 0x3f) << 2;
671
+ data[1] >>= 12;
672
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
673
+ b = (data[1] & 0x3f) << 2;
674
+ data[1] >>= 6;
675
+ g = (data[1] & 0x3f) << 2;
676
+ data[1] >>= 6;
677
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
678
+ data[2] >>= 8;
679
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
680
+ b = (data[2] & 0x3f) << 2;
681
+ data[2] >>= 6;
682
+ g = (data[2] & 0x3f) << 2;
683
+ data[2] >>= 6;
684
+ r = data[2] << 2;
685
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
686
+ width -= 4;
687
+ }
688
+}
689
+
690
+static void pxa2xx_draw_line19(void *opaque, uint8_t *dest, const uint8_t *src,
691
+ int width, int deststep)
692
+{
693
+ uint32_t data;
694
+ unsigned int r, g, b;
695
+ while (width > 0) {
696
+ data = *(uint32_t *) src;
697
+#ifdef SWAP_WORDS
698
+ data = bswap32(data);
699
+#endif
700
+ b = (data & 0x3f) << 2;
701
+ data >>= 6;
702
+ g = (data & 0x3f) << 2;
703
+ data >>= 6;
704
+ r = (data & 0x3f) << 2;
705
+ data >>= 6;
706
+ if (data & 1) {
707
+ SKIP_PIXEL(dest);
708
+ } else {
709
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
710
+ }
711
+ width -= 1;
712
+ src += 4;
713
+ }
714
+}
715
+
716
+/* The wicked packed format */
717
+static void pxa2xx_draw_line19p(void *opaque, uint8_t *dest, const uint8_t *src,
718
+ int width, int deststep)
719
+{
720
+ uint32_t data[3];
721
+ unsigned int r, g, b;
722
+ while (width > 0) {
723
+ data[0] = *(uint32_t *) src;
724
+ src += 4;
725
+ data[1] = *(uint32_t *) src;
726
+ src += 4;
727
+ data[2] = *(uint32_t *) src;
728
+ src += 4;
729
+# ifdef SWAP_WORDS
730
+ data[0] = bswap32(data[0]);
731
+ data[1] = bswap32(data[1]);
732
+ data[2] = bswap32(data[2]);
733
+# endif
734
+ b = (data[0] & 0x3f) << 2;
735
+ data[0] >>= 6;
736
+ g = (data[0] & 0x3f) << 2;
737
+ data[0] >>= 6;
738
+ r = (data[0] & 0x3f) << 2;
739
+ data[0] >>= 6;
740
+ if (data[0] & 1) {
741
+ SKIP_PIXEL(dest);
742
+ } else {
743
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
744
+ }
745
+ data[0] >>= 6;
746
+ b = (data[0] & 0x3f) << 2;
747
+ data[0] >>= 6;
748
+ g = ((data[1] & 0xf) << 4) | (data[0] << 2);
749
+ data[1] >>= 4;
750
+ r = (data[1] & 0x3f) << 2;
751
+ data[1] >>= 6;
752
+ if (data[1] & 1) {
753
+ SKIP_PIXEL(dest);
754
+ } else {
755
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
756
+ }
757
+ data[1] >>= 6;
758
+ b = (data[1] & 0x3f) << 2;
759
+ data[1] >>= 6;
760
+ g = (data[1] & 0x3f) << 2;
761
+ data[1] >>= 6;
762
+ r = ((data[2] & 0x3) << 6) | (data[1] << 2);
763
+ data[2] >>= 2;
764
+ if (data[2] & 1) {
765
+ SKIP_PIXEL(dest);
766
+ } else {
767
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
768
+ }
769
+ data[2] >>= 6;
770
+ b = (data[2] & 0x3f) << 2;
771
+ data[2] >>= 6;
772
+ g = (data[2] & 0x3f) << 2;
773
+ data[2] >>= 6;
774
+ r = data[2] << 2;
775
+ data[2] >>= 6;
776
+ if (data[2] & 1) {
777
+ SKIP_PIXEL(dest);
778
+ } else {
779
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
780
+ }
781
+ width -= 4;
782
+ }
783
+}
784
+
785
+static void pxa2xx_draw_line24(void *opaque, uint8_t *dest, const uint8_t *src,
786
+ int width, int deststep)
787
+{
788
+ uint32_t data;
789
+ unsigned int r, g, b;
790
+ while (width > 0) {
791
+ data = *(uint32_t *) src;
792
+#ifdef SWAP_WORDS
793
+ data = bswap32(data);
794
+#endif
795
+ b = data & 0xff;
796
+ data >>= 8;
797
+ g = data & 0xff;
798
+ data >>= 8;
799
+ r = data & 0xff;
800
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
801
+ width -= 1;
802
+ src += 4;
803
+ }
804
+}
805
+
806
+static void pxa2xx_draw_line24t(void *opaque, uint8_t *dest, const uint8_t *src,
807
+ int width, int deststep)
808
+{
809
+ uint32_t data;
810
+ unsigned int r, g, b;
811
+ while (width > 0) {
812
+ data = *(uint32_t *) src;
813
+#ifdef SWAP_WORDS
814
+ data = bswap32(data);
815
+#endif
816
+ b = (data & 0x7f) << 1;
817
+ data >>= 7;
818
+ g = data & 0xff;
819
+ data >>= 8;
820
+ r = data & 0xff;
821
+ data >>= 8;
822
+ if (data & 1) {
823
+ SKIP_PIXEL(dest);
824
+ } else {
825
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
826
+ }
827
+ width -= 1;
828
+ src += 4;
829
+ }
830
+}
831
+
832
+static void pxa2xx_draw_line25(void *opaque, uint8_t *dest, const uint8_t *src,
833
+ int width, int deststep)
834
+{
835
+ uint32_t data;
836
+ unsigned int r, g, b;
837
+ while (width > 0) {
838
+ data = *(uint32_t *) src;
839
+#ifdef SWAP_WORDS
840
+ data = bswap32(data);
841
+#endif
842
+ b = data & 0xff;
843
+ data >>= 8;
844
+ g = data & 0xff;
845
+ data >>= 8;
846
+ r = data & 0xff;
847
+ data >>= 8;
848
+ if (data & 1) {
849
+ SKIP_PIXEL(dest);
850
+ } else {
851
+ COPY_PIXEL(dest, rgb_to_pixel32(r, g, b));
852
+ }
853
+ width -= 1;
854
+ src += 4;
855
+ }
856
+}
857
+
858
+/* Overlay planes disabled, no transparency */
859
+static drawfn pxa2xx_draw_fn_32[16] = {
860
+ [0 ... 0xf] = NULL,
861
+ [pxa_lcdc_2bpp] = pxa2xx_draw_line2,
862
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
863
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
864
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16,
865
+ [pxa_lcdc_18bpp] = pxa2xx_draw_line18,
866
+ [pxa_lcdc_18pbpp] = pxa2xx_draw_line18p,
867
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24,
868
+};
869
+
870
+/* Overlay planes enabled, transparency used */
871
+static drawfn pxa2xx_draw_fn_32t[16] = {
872
+ [0 ... 0xf] = NULL,
873
+ [pxa_lcdc_4bpp] = pxa2xx_draw_line4,
874
+ [pxa_lcdc_8bpp] = pxa2xx_draw_line8,
875
+ [pxa_lcdc_16bpp] = pxa2xx_draw_line16t,
876
+ [pxa_lcdc_19bpp] = pxa2xx_draw_line19,
877
+ [pxa_lcdc_19pbpp] = pxa2xx_draw_line19p,
878
+ [pxa_lcdc_24bpp] = pxa2xx_draw_line24t,
879
+ [pxa_lcdc_25bpp] = pxa2xx_draw_line25,
880
+};
881
+
882
+#undef COPY_PIXEL
883
+#undef SKIP_PIXEL
884
+
885
+#ifdef SWAP_WORDS
886
+# undef SWAP_WORDS
887
+#endif
888
889
/* Route internal interrupt lines to the global IC */
890
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
891
--
117
--
892
2.20.1
118
2.34.1
893
119
894
120
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
The MPS2 SCC device is broadly the same for all FPGA images, but has
2
surface is always 32 bits per pixel. Remove the legacy dead code
2
minor differences in the behaviour of the CFG registers depending on
3
from the pxa2xx_lcd display device which was handling the possibility
3
the image. In many cases we don't really care about the functionality
4
that the console surface was some other format.
4
controlled by these registers and a reads-as-written or similar
5
behaviour is sufficient for the moment.
6
7
For the AN536 the required behaviour is:
8
9
* A_CFG0 has CPU reset and halt bits
10
- implement as reads-as-written for the moment
11
* A_CFG1 has flash or ATCM address 0 remap handling
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.
5
34
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
35
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
36
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20210211141515.8755-5-peter.maydell@linaro.org
37
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
38
Message-id: 20240206132931.38376-8-peter.maydell@linaro.org
9
---
39
---
10
hw/display/pxa2xx_lcd.c | 79 +++++++++--------------------------------
40
include/hw/misc/mps2-scc.h | 1 +
11
1 file changed, 17 insertions(+), 62 deletions(-)
41
hw/misc/mps2-scc.c | 101 +++++++++++++++++++++++++++++++++----
12
42
2 files changed, 92 insertions(+), 10 deletions(-)
13
diff --git a/hw/display/pxa2xx_lcd.c b/hw/display/pxa2xx_lcd.c
43
44
diff --git a/include/hw/misc/mps2-scc.h b/include/hw/misc/mps2-scc.h
14
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/display/pxa2xx_lcd.c
46
--- a/include/hw/misc/mps2-scc.h
16
+++ b/hw/display/pxa2xx_lcd.c
47
+++ b/include/hw/misc/mps2-scc.h
17
@@ -XXX,XX +XXX,XX @@ struct PXA2xxLCDState {
48
@@ -XXX,XX +XXX,XX @@ struct MPS2SCC {
18
49
uint32_t cfg4;
19
int invalidated;
50
uint32_t cfg5;
20
QemuConsole *con;
51
uint32_t cfg6;
21
- drawfn *line_fn[2];
52
+ uint32_t cfg7;
22
int dest_width;
53
uint32_t cfgdata_rtn;
23
int xres, yres;
54
uint32_t cfgdata_out;
24
int pal_for;
55
uint32_t cfgctrl;
25
@@ -XXX,XX +XXX,XX @@ typedef struct QEMU_PACKED {
56
diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c
26
#define LDCMD_SOFINT    (1 << 22)
57
index XXXXXXX..XXXXXXX 100644
27
#define LDCMD_PAL    (1 << 26)
58
--- a/hw/misc/mps2-scc.c
28
59
+++ b/hw/misc/mps2-scc.c
29
+#define BITS 32
60
@@ -XXX,XX +XXX,XX @@ REG32(CFG3, 0xc)
30
+#include "pxa2xx_template.h"
61
REG32(CFG4, 0x10)
31
+
62
REG32(CFG5, 0x14)
32
/* Route internal interrupt lines to the global IC */
63
REG32(CFG6, 0x18)
33
static void pxa2xx_lcdc_int_update(PXA2xxLCDState *s)
64
+REG32(CFG7, 0x1c)
34
{
65
REG32(CFGDATA_RTN, 0xa0)
35
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_palette_parse(PXA2xxLCDState *s, int ch, int bpp)
66
REG32(CFGDATA_OUT, 0xa4)
36
}
67
REG32(CFGCTRL, 0xa8)
37
}
68
@@ -XXX,XX +XXX,XX @@ static int scc_partno(MPS2SCC *s)
38
69
/* Is CFG_REG2 present? */
39
+static inline drawfn pxa2xx_drawfn(PXA2xxLCDState *s)
70
static bool have_cfg2(MPS2SCC *s)
40
+{
71
{
41
+ if (s->transp) {
72
- return scc_partno(s) == 0x524 || scc_partno(s) == 0x547;
42
+ return pxa2xx_draw_fn_32t[s->bpp];
73
+ return scc_partno(s) == 0x524 || scc_partno(s) == 0x547 ||
43
+ } else {
74
+ scc_partno(s) == 0x536;
44
+ return pxa2xx_draw_fn_32[s->bpp];
75
}
76
77
/* Is CFG_REG3 present? */
78
static bool have_cfg3(MPS2SCC *s)
79
{
80
- return scc_partno(s) != 0x524 && scc_partno(s) != 0x547;
81
+ return scc_partno(s) != 0x524 && scc_partno(s) != 0x547 &&
82
+ scc_partno(s) != 0x536;
83
}
84
85
/* Is CFG_REG5 present? */
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));
179
+ }
180
}
181
break;
182
case A_CFG2:
183
if (!have_cfg2(s)) {
184
goto bad_offset;
185
}
186
- /* AN524: QSPI Select signal */
187
+ /* AN524, AN536: QSPI Select signal */
188
s->cfg2 = value;
189
break;
190
case A_CFG5:
191
if (!have_cfg5(s)) {
192
goto bad_offset;
193
}
194
- /* AN524: ACLK frequency in Hz */
195
+ /* AN524, AN536: ACLK frequency in Hz */
196
s->cfg5 = value;
197
break;
198
case A_CFG6:
199
@@ -XXX,XX +XXX,XX @@ static void mps2_scc_write(void *opaque, hwaddr offset, uint64_t value,
200
goto bad_offset;
201
}
202
/* AN524: Clock divider for BRAM */
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",
227
+ .version_id = 1,
228
+ .minimum_version_id = 1,
229
+ .needed = cfg7_needed,
230
+ .fields = (const VMStateField[]) {
231
+ VMSTATE_UINT32(cfg7, MPS2SCC),
232
+ VMSTATE_END_OF_LIST()
45
+ }
233
+ }
46
+}
234
+};
47
+
235
+
48
static void pxa2xx_lcdc_dma0_redraw_rot0(PXA2xxLCDState *s,
236
static const VMStateDescription mps2_scc_vmstate = {
49
hwaddr addr, int *miny, int *maxy)
237
.name = "mps2-scc",
50
{
238
.version_id = 3,
51
DisplaySurface *surface = qemu_console_surface(s->con);
239
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription mps2_scc_vmstate = {
52
int src_width, dest_width;
240
VMSTATE_VARRAY_UINT32(oscclk, MPS2SCC, num_oscclk,
53
- drawfn fn = NULL;
241
0, vmstate_info_uint32, uint32_t),
54
- if (s->dest_width)
242
VMSTATE_END_OF_LIST()
55
- fn = s->line_fn[s->transp][s->bpp];
243
+ },
56
+ drawfn fn = pxa2xx_drawfn(s);
244
+ .subsections = (const VMStateDescription * const []) {
57
if (!fn)
245
+ &vmstate_cfg7,
58
return;
246
+ NULL
59
60
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot90(PXA2xxLCDState *s,
61
{
62
DisplaySurface *surface = qemu_console_surface(s->con);
63
int src_width, dest_width;
64
- drawfn fn = NULL;
65
- if (s->dest_width)
66
- fn = s->line_fn[s->transp][s->bpp];
67
+ drawfn fn = pxa2xx_drawfn(s);
68
if (!fn)
69
return;
70
71
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot180(PXA2xxLCDState *s,
72
{
73
DisplaySurface *surface = qemu_console_surface(s->con);
74
int src_width, dest_width;
75
- drawfn fn = NULL;
76
- if (s->dest_width) {
77
- fn = s->line_fn[s->transp][s->bpp];
78
- }
79
+ drawfn fn = pxa2xx_drawfn(s);
80
if (!fn) {
81
return;
82
}
83
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_lcdc_dma0_redraw_rot270(PXA2xxLCDState *s,
84
{
85
DisplaySurface *surface = qemu_console_surface(s->con);
86
int src_width, dest_width;
87
- drawfn fn = NULL;
88
- if (s->dest_width) {
89
- fn = s->line_fn[s->transp][s->bpp];
90
- }
91
+ drawfn fn = pxa2xx_drawfn(s);
92
if (!fn) {
93
return;
94
}
95
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pxa2xx_lcdc = {
96
}
247
}
97
};
248
};
98
249
99
-#define BITS 8
100
-#include "pxa2xx_template.h"
101
-#define BITS 15
102
-#include "pxa2xx_template.h"
103
-#define BITS 16
104
-#include "pxa2xx_template.h"
105
-#define BITS 24
106
-#include "pxa2xx_template.h"
107
-#define BITS 32
108
-#include "pxa2xx_template.h"
109
-
110
static const GraphicHwOps pxa2xx_ops = {
111
.invalidate = pxa2xx_invalidate_display,
112
.gfx_update = pxa2xx_update_display,
113
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
114
hwaddr base, qemu_irq irq)
115
{
116
PXA2xxLCDState *s;
117
- DisplaySurface *surface;
118
119
s = (PXA2xxLCDState *) g_malloc0(sizeof(PXA2xxLCDState));
120
s->invalidated = 1;
121
@@ -XXX,XX +XXX,XX @@ PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
122
memory_region_add_subregion(sysmem, base, &s->iomem);
123
124
s->con = graphic_console_init(NULL, 0, &pxa2xx_ops, s);
125
- surface = qemu_console_surface(s->con);
126
-
127
- switch (surface_bits_per_pixel(surface)) {
128
- case 0:
129
- s->dest_width = 0;
130
- break;
131
- case 8:
132
- s->line_fn[0] = pxa2xx_draw_fn_8;
133
- s->line_fn[1] = pxa2xx_draw_fn_8t;
134
- s->dest_width = 1;
135
- break;
136
- case 15:
137
- s->line_fn[0] = pxa2xx_draw_fn_15;
138
- s->line_fn[1] = pxa2xx_draw_fn_15t;
139
- s->dest_width = 2;
140
- break;
141
- case 16:
142
- s->line_fn[0] = pxa2xx_draw_fn_16;
143
- s->line_fn[1] = pxa2xx_draw_fn_16t;
144
- s->dest_width = 2;
145
- break;
146
- case 24:
147
- s->line_fn[0] = pxa2xx_draw_fn_24;
148
- s->line_fn[1] = pxa2xx_draw_fn_24t;
149
- s->dest_width = 3;
150
- break;
151
- case 32:
152
- s->line_fn[0] = pxa2xx_draw_fn_32;
153
- s->line_fn[1] = pxa2xx_draw_fn_32t;
154
- s->dest_width = 4;
155
- break;
156
- default:
157
- fprintf(stderr, "%s: Bad color depth\n", __func__);
158
- exit(1);
159
- }
160
+ s->dest_width = 4;
161
162
vmstate_register(NULL, 0, &vmstate_pxa2xx_lcdc, s);
163
164
--
250
--
165
2.20.1
251
2.34.1
166
252
167
253
diff view generated by jsdifflib
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.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
Add a model of the Xilinx Versal Accelerator RAM (XRAM).
3
family CPU, and it does not use any equivalent to the M-profile
4
This is mainly a stub to make firmware happy. The size of
4
"Subsystem for Embedded" SoC-equivalent that we model in hw/arm/armsse.c.
5
the RAMs can be probed. The interrupt mask logic is
5
It's therefore more convenient for us to model it as a completely
6
modelled but none of the interrups will ever be raised
6
separate C file.
7
unless injected.
7
8
8
This commit adds the basic skeleton of the board model, and the
9
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
9
code to create all the RAM and ROM. We assume that we're probably
10
Message-id: 20210308224637.2949533-2-edgar.iglesias@gmail.com
10
going to want to add more images in future, so use the same
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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
12
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
13
---
19
---
14
include/hw/misc/xlnx-versal-xramc.h | 97 +++++++++++
20
MAINTAINERS | 3 +-
15
hw/misc/xlnx-versal-xramc.c | 253 ++++++++++++++++++++++++++++
21
configs/devices/arm-softmmu/default.mak | 1 +
16
hw/misc/meson.build | 1 +
22
hw/arm/mps3r.c | 239 ++++++++++++++++++++++++
17
3 files changed, 351 insertions(+)
23
hw/arm/Kconfig | 5 +
18
create mode 100644 include/hw/misc/xlnx-versal-xramc.h
24
hw/arm/meson.build | 1 +
19
create mode 100644 hw/misc/xlnx-versal-xramc.c
25
5 files changed, 248 insertions(+), 1 deletion(-)
20
26
create mode 100644 hw/arm/mps3r.c
21
diff --git a/include/hw/misc/xlnx-versal-xramc.h b/include/hw/misc/xlnx-versal-xramc.h
27
28
diff --git a/MAINTAINERS b/MAINTAINERS
29
index XXXXXXX..XXXXXXX 100644
30
--- a/MAINTAINERS
31
+++ b/MAINTAINERS
32
@@ -XXX,XX +XXX,XX @@ F: include/hw/misc/imx7_*.h
33
F: hw/pci-host/designware.c
34
F: include/hw/pci-host/designware.h
35
36
-MPS2
37
+MPS2 / MPS3
38
M: Peter Maydell <peter.maydell@linaro.org>
39
L: qemu-arm@nongnu.org
40
S: Maintained
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
22
new file mode 100644
60
new file mode 100644
23
index XXXXXXX..XXXXXXX
61
index XXXXXXX..XXXXXXX
24
--- /dev/null
62
--- /dev/null
25
+++ b/include/hw/misc/xlnx-versal-xramc.h
63
+++ b/hw/arm/mps3r.c
26
@@ -XXX,XX +XXX,XX @@
64
@@ -XXX,XX +XXX,XX @@
27
+/*
65
+/*
28
+ * QEMU model of the Xilinx XRAM Controller.
66
+ * Arm MPS3 board emulation for Cortex-R-based FPGA images.
67
+ * (For M-profile images see mps2.c and mps2tz.c.)
29
+ *
68
+ *
30
+ * Copyright (c) 2021 Xilinx Inc.
69
+ * Copyright (c) 2017 Linaro Limited
31
+ * SPDX-License-Identifier: GPL-2.0-or-later
70
+ * Written by Peter Maydell
32
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
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.
33
+ */
75
+ */
34
+
76
+
35
+#ifndef XLNX_VERSAL_XRAMC_H
36
+#define XLNX_VERSAL_XRAMC_H
37
+
38
+#include "hw/sysbus.h"
39
+#include "hw/register.h"
40
+
41
+#define TYPE_XLNX_XRAM_CTRL "xlnx.versal-xramc"
42
+
43
+#define XLNX_XRAM_CTRL(obj) \
44
+ OBJECT_CHECK(XlnxXramCtrl, (obj), TYPE_XLNX_XRAM_CTRL)
45
+
46
+REG32(XRAM_ERR_CTRL, 0x0)
47
+ FIELD(XRAM_ERR_CTRL, UE_RES, 3, 1)
48
+ FIELD(XRAM_ERR_CTRL, PWR_ERR_RES, 2, 1)
49
+ FIELD(XRAM_ERR_CTRL, PZ_ERR_RES, 1, 1)
50
+ FIELD(XRAM_ERR_CTRL, APB_ERR_RES, 0, 1)
51
+REG32(XRAM_ISR, 0x4)
52
+ FIELD(XRAM_ISR, INV_APB, 0, 1)
53
+REG32(XRAM_IMR, 0x8)
54
+ FIELD(XRAM_IMR, INV_APB, 0, 1)
55
+REG32(XRAM_IEN, 0xc)
56
+ FIELD(XRAM_IEN, INV_APB, 0, 1)
57
+REG32(XRAM_IDS, 0x10)
58
+ FIELD(XRAM_IDS, INV_APB, 0, 1)
59
+REG32(XRAM_ECC_CNTL, 0x14)
60
+ FIELD(XRAM_ECC_CNTL, FI_MODE, 2, 1)
61
+ FIELD(XRAM_ECC_CNTL, DET_ONLY, 1, 1)
62
+ FIELD(XRAM_ECC_CNTL, ECC_ON_OFF, 0, 1)
63
+REG32(XRAM_CLR_EXE, 0x18)
64
+ FIELD(XRAM_CLR_EXE, MON_7, 7, 1)
65
+ FIELD(XRAM_CLR_EXE, MON_6, 6, 1)
66
+ FIELD(XRAM_CLR_EXE, MON_5, 5, 1)
67
+ FIELD(XRAM_CLR_EXE, MON_4, 4, 1)
68
+ FIELD(XRAM_CLR_EXE, MON_3, 3, 1)
69
+ FIELD(XRAM_CLR_EXE, MON_2, 2, 1)
70
+ FIELD(XRAM_CLR_EXE, MON_1, 1, 1)
71
+ FIELD(XRAM_CLR_EXE, MON_0, 0, 1)
72
+REG32(XRAM_CE_FFA, 0x1c)
73
+ FIELD(XRAM_CE_FFA, ADDR, 0, 20)
74
+REG32(XRAM_CE_FFD0, 0x20)
75
+REG32(XRAM_CE_FFD1, 0x24)
76
+REG32(XRAM_CE_FFD2, 0x28)
77
+REG32(XRAM_CE_FFD3, 0x2c)
78
+REG32(XRAM_CE_FFE, 0x30)
79
+ FIELD(XRAM_CE_FFE, SYNDROME, 0, 16)
80
+REG32(XRAM_UE_FFA, 0x34)
81
+ FIELD(XRAM_UE_FFA, ADDR, 0, 20)
82
+REG32(XRAM_UE_FFD0, 0x38)
83
+REG32(XRAM_UE_FFD1, 0x3c)
84
+REG32(XRAM_UE_FFD2, 0x40)
85
+REG32(XRAM_UE_FFD3, 0x44)
86
+REG32(XRAM_UE_FFE, 0x48)
87
+ FIELD(XRAM_UE_FFE, SYNDROME, 0, 16)
88
+REG32(XRAM_FI_D0, 0x4c)
89
+REG32(XRAM_FI_D1, 0x50)
90
+REG32(XRAM_FI_D2, 0x54)
91
+REG32(XRAM_FI_D3, 0x58)
92
+REG32(XRAM_FI_SY, 0x5c)
93
+ FIELD(XRAM_FI_SY, DATA, 0, 16)
94
+REG32(XRAM_RMW_UE_FFA, 0x70)
95
+ FIELD(XRAM_RMW_UE_FFA, ADDR, 0, 20)
96
+REG32(XRAM_FI_CNTR, 0x74)
97
+ FIELD(XRAM_FI_CNTR, COUNT, 0, 24)
98
+REG32(XRAM_IMP, 0x80)
99
+ FIELD(XRAM_IMP, SIZE, 0, 4)
100
+REG32(XRAM_PRDY_DBG, 0x84)
101
+ FIELD(XRAM_PRDY_DBG, ISLAND3, 12, 4)
102
+ FIELD(XRAM_PRDY_DBG, ISLAND2, 8, 4)
103
+ FIELD(XRAM_PRDY_DBG, ISLAND1, 4, 4)
104
+ FIELD(XRAM_PRDY_DBG, ISLAND0, 0, 4)
105
+REG32(XRAM_SAFETY_CHK, 0xff8)
106
+
107
+#define XRAM_CTRL_R_MAX (R_XRAM_SAFETY_CHK + 1)
108
+
109
+typedef struct XlnxXramCtrl {
110
+ SysBusDevice parent_obj;
111
+ MemoryRegion ram;
112
+ qemu_irq irq;
113
+
114
+ struct {
115
+ uint64_t size;
116
+ unsigned int encoded_size;
117
+ } cfg;
118
+
119
+ RegisterInfoArray *reg_array;
120
+ uint32_t regs[XRAM_CTRL_R_MAX];
121
+ RegisterInfo regs_info[XRAM_CTRL_R_MAX];
122
+} XlnxXramCtrl;
123
+#endif
124
diff --git a/hw/misc/xlnx-versal-xramc.c b/hw/misc/xlnx-versal-xramc.c
125
new file mode 100644
126
index XXXXXXX..XXXXXXX
127
--- /dev/null
128
+++ b/hw/misc/xlnx-versal-xramc.c
129
@@ -XXX,XX +XXX,XX @@
130
+/*
77
+/*
131
+ * QEMU model of the Xilinx XRAM Controller.
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.
132
+ *
83
+ *
133
+ * Copyright (c) 2021 Xilinx Inc.
84
+ * We model the following FPGA images here:
134
+ * SPDX-License-Identifier: GPL-2.0-or-later
85
+ * "mps3-an536" -- dual Cortex-R52 as documented in Arm Application Note AN536
135
+ * Written by Edgar E. Iglesias <edgar.iglesias@xilinx.com>
86
+ *
87
+ * Application Note AN536:
88
+ * https://developer.arm.com/documentation/dai0536/latest/
136
+ */
89
+ */
137
+
90
+
138
+#include "qemu/osdep.h"
91
+#include "qemu/osdep.h"
139
+#include "qemu/units.h"
92
+#include "qemu/units.h"
140
+#include "qapi/error.h"
93
+#include "qapi/error.h"
141
+#include "migration/vmstate.h"
94
+#include "exec/address-spaces.h"
142
+#include "hw/sysbus.h"
95
+#include "cpu.h"
143
+#include "hw/register.h"
96
+#include "hw/boards.h"
144
+#include "hw/qdev-properties.h"
97
+#include "hw/arm/boot.h"
145
+#include "hw/irq.h"
98
+
146
+#include "hw/misc/xlnx-versal-xramc.h"
99
+/* Define the layout of RAM and ROM in a board */
147
+
100
+typedef struct RAMInfo {
148
+#ifndef XLNX_XRAM_CTRL_ERR_DEBUG
101
+ const char *name;
149
+#define XLNX_XRAM_CTRL_ERR_DEBUG 0
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)
150
+#endif
116
+#endif
151
+
117
+
152
+static void xram_update_irq(XlnxXramCtrl *s)
118
+/*
153
+{
119
+ * Flag values:
154
+ bool pending = s->regs[R_XRAM_ISR] & ~s->regs[R_XRAM_IMR];
120
+ * IS_MAIN: this is the main machine RAM
155
+ qemu_set_irq(s->irq, pending);
121
+ * IS_ROM: this area is read-only
156
+}
122
+ */
157
+
123
+#define IS_MAIN 1
158
+static void xram_isr_postw(RegisterInfo *reg, uint64_t val64)
124
+#define IS_ROM 2
159
+{
125
+
160
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
126
+#define MPS3R_RAM_MAX 9
161
+ xram_update_irq(s);
127
+
162
+}
128
+typedef enum MPS3RFPGAType {
163
+
129
+ FPGA_AN536,
164
+static uint64_t xram_ien_prew(RegisterInfo *reg, uint64_t val64)
130
+} MPS3RFPGAType;
165
+{
131
+
166
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
132
+struct MPS3RMachineClass {
167
+ uint32_t val = val64;
133
+ MachineClass parent;
168
+
134
+ MPS3RFPGAType fpga_type;
169
+ s->regs[R_XRAM_IMR] &= ~val;
135
+ const RAMInfo *raminfo;
170
+ xram_update_irq(s);
171
+ return 0;
172
+}
173
+
174
+static uint64_t xram_ids_prew(RegisterInfo *reg, uint64_t val64)
175
+{
176
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(reg->opaque);
177
+ uint32_t val = val64;
178
+
179
+ s->regs[R_XRAM_IMR] |= val;
180
+ xram_update_irq(s);
181
+ return 0;
182
+}
183
+
184
+static const RegisterAccessInfo xram_ctrl_regs_info[] = {
185
+ { .name = "XRAM_ERR_CTRL", .addr = A_XRAM_ERR_CTRL,
186
+ .reset = 0xf,
187
+ .rsvd = 0xfffffff0,
188
+ },{ .name = "XRAM_ISR", .addr = A_XRAM_ISR,
189
+ .rsvd = 0xfffff800,
190
+ .w1c = 0x7ff,
191
+ .post_write = xram_isr_postw,
192
+ },{ .name = "XRAM_IMR", .addr = A_XRAM_IMR,
193
+ .reset = 0x7ff,
194
+ .rsvd = 0xfffff800,
195
+ .ro = 0x7ff,
196
+ },{ .name = "XRAM_IEN", .addr = A_XRAM_IEN,
197
+ .rsvd = 0xfffff800,
198
+ .pre_write = xram_ien_prew,
199
+ },{ .name = "XRAM_IDS", .addr = A_XRAM_IDS,
200
+ .rsvd = 0xfffff800,
201
+ .pre_write = xram_ids_prew,
202
+ },{ .name = "XRAM_ECC_CNTL", .addr = A_XRAM_ECC_CNTL,
203
+ .rsvd = 0xfffffff8,
204
+ },{ .name = "XRAM_CLR_EXE", .addr = A_XRAM_CLR_EXE,
205
+ .rsvd = 0xffffff00,
206
+ },{ .name = "XRAM_CE_FFA", .addr = A_XRAM_CE_FFA,
207
+ .rsvd = 0xfff00000,
208
+ .ro = 0xfffff,
209
+ },{ .name = "XRAM_CE_FFD0", .addr = A_XRAM_CE_FFD0,
210
+ .ro = 0xffffffff,
211
+ },{ .name = "XRAM_CE_FFD1", .addr = A_XRAM_CE_FFD1,
212
+ .ro = 0xffffffff,
213
+ },{ .name = "XRAM_CE_FFD2", .addr = A_XRAM_CE_FFD2,
214
+ .ro = 0xffffffff,
215
+ },{ .name = "XRAM_CE_FFD3", .addr = A_XRAM_CE_FFD3,
216
+ .ro = 0xffffffff,
217
+ },{ .name = "XRAM_CE_FFE", .addr = A_XRAM_CE_FFE,
218
+ .rsvd = 0xffff0000,
219
+ .ro = 0xffff,
220
+ },{ .name = "XRAM_UE_FFA", .addr = A_XRAM_UE_FFA,
221
+ .rsvd = 0xfff00000,
222
+ .ro = 0xfffff,
223
+ },{ .name = "XRAM_UE_FFD0", .addr = A_XRAM_UE_FFD0,
224
+ .ro = 0xffffffff,
225
+ },{ .name = "XRAM_UE_FFD1", .addr = A_XRAM_UE_FFD1,
226
+ .ro = 0xffffffff,
227
+ },{ .name = "XRAM_UE_FFD2", .addr = A_XRAM_UE_FFD2,
228
+ .ro = 0xffffffff,
229
+ },{ .name = "XRAM_UE_FFD3", .addr = A_XRAM_UE_FFD3,
230
+ .ro = 0xffffffff,
231
+ },{ .name = "XRAM_UE_FFE", .addr = A_XRAM_UE_FFE,
232
+ .rsvd = 0xffff0000,
233
+ .ro = 0xffff,
234
+ },{ .name = "XRAM_FI_D0", .addr = A_XRAM_FI_D0,
235
+ },{ .name = "XRAM_FI_D1", .addr = A_XRAM_FI_D1,
236
+ },{ .name = "XRAM_FI_D2", .addr = A_XRAM_FI_D2,
237
+ },{ .name = "XRAM_FI_D3", .addr = A_XRAM_FI_D3,
238
+ },{ .name = "XRAM_FI_SY", .addr = A_XRAM_FI_SY,
239
+ .rsvd = 0xffff0000,
240
+ },{ .name = "XRAM_RMW_UE_FFA", .addr = A_XRAM_RMW_UE_FFA,
241
+ .rsvd = 0xfff00000,
242
+ .ro = 0xfffff,
243
+ },{ .name = "XRAM_FI_CNTR", .addr = A_XRAM_FI_CNTR,
244
+ .rsvd = 0xff000000,
245
+ },{ .name = "XRAM_IMP", .addr = A_XRAM_IMP,
246
+ .reset = 0x4,
247
+ .rsvd = 0xfffffff0,
248
+ .ro = 0xf,
249
+ },{ .name = "XRAM_PRDY_DBG", .addr = A_XRAM_PRDY_DBG,
250
+ .reset = 0xffff,
251
+ .rsvd = 0xffff0000,
252
+ .ro = 0xffff,
253
+ },{ .name = "XRAM_SAFETY_CHK", .addr = A_XRAM_SAFETY_CHK,
254
+ }
255
+};
136
+};
256
+
137
+
257
+static void xram_ctrl_reset_enter(Object *obj, ResetType type)
138
+struct MPS3RMachineState {
258
+{
139
+ MachineState parent;
259
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
140
+ MemoryRegion ram[MPS3R_RAM_MAX];
260
+ unsigned int i;
141
+};
261
+
142
+
262
+ for (i = 0; i < ARRAY_SIZE(s->regs_info); ++i) {
143
+#define TYPE_MPS3R_MACHINE "mps3r"
263
+ register_reset(&s->regs_info[i]);
144
+#define TYPE_MPS3R_AN536_MACHINE MACHINE_TYPE_NAME("mps3-an536")
264
+ }
145
+
265
+
146
+OBJECT_DECLARE_TYPE(MPS3RMachineState, MPS3RMachineClass, MPS3R_MACHINE)
266
+ ARRAY_FIELD_DP32(s->regs, XRAM_IMP, SIZE, s->cfg.encoded_size);
147
+
267
+}
148
+static const RAMInfo an536_raminfo[] = {
268
+
149
+ {
269
+static void xram_ctrl_reset_hold(Object *obj)
150
+ .name = "ATCM",
270
+{
151
+ .base = 0x00000000,
271
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
152
+ .size = 0x00008000,
272
+
153
+ .mrindex = 0,
273
+ xram_update_irq(s);
154
+ }, {
274
+}
155
+ /* We model the QSPI flash as simple ROM for now */
275
+
156
+ .name = "QSPI",
276
+static const MemoryRegionOps xram_ctrl_ops = {
157
+ .base = 0x08000000,
277
+ .read = register_read_memory,
158
+ .size = 0x00800000,
278
+ .write = register_write_memory,
159
+ .flags = IS_ROM,
279
+ .endianness = DEVICE_LITTLE_ENDIAN,
160
+ .mrindex = 1,
280
+ .valid = {
161
+ }, {
281
+ .min_access_size = 4,
162
+ .name = "BRAM",
282
+ .max_access_size = 4,
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,
283
+ },
300
+ },
284
+};
301
+};
285
+
302
+
286
+static void xram_ctrl_realize(DeviceState *dev, Error **errp)
303
+DEFINE_TYPES(mps3r_machine_types);
287
+{
304
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
288
+ SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
289
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(dev);
290
+
291
+ switch (s->cfg.size) {
292
+ case 64 * KiB:
293
+ s->cfg.encoded_size = 0;
294
+ break;
295
+ case 128 * KiB:
296
+ s->cfg.encoded_size = 1;
297
+ break;
298
+ case 256 * KiB:
299
+ s->cfg.encoded_size = 2;
300
+ break;
301
+ case 512 * KiB:
302
+ s->cfg.encoded_size = 3;
303
+ break;
304
+ case 1 * MiB:
305
+ s->cfg.encoded_size = 4;
306
+ break;
307
+ default:
308
+ error_setg(errp, "Unsupported XRAM size %" PRId64, s->cfg.size);
309
+ return;
310
+ }
311
+
312
+ memory_region_init_ram(&s->ram, OBJECT(s),
313
+ object_get_canonical_path_component(OBJECT(s)),
314
+ s->cfg.size, &error_fatal);
315
+ sysbus_init_mmio(sbd, &s->ram);
316
+}
317
+
318
+static void xram_ctrl_init(Object *obj)
319
+{
320
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
321
+ SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
322
+
323
+ s->reg_array =
324
+ register_init_block32(DEVICE(obj), xram_ctrl_regs_info,
325
+ ARRAY_SIZE(xram_ctrl_regs_info),
326
+ s->regs_info, s->regs,
327
+ &xram_ctrl_ops,
328
+ XLNX_XRAM_CTRL_ERR_DEBUG,
329
+ XRAM_CTRL_R_MAX * 4);
330
+ sysbus_init_mmio(sbd, &s->reg_array->mem);
331
+ sysbus_init_irq(sbd, &s->irq);
332
+}
333
+
334
+static void xram_ctrl_finalize(Object *obj)
335
+{
336
+ XlnxXramCtrl *s = XLNX_XRAM_CTRL(obj);
337
+ register_finalize_block(s->reg_array);
338
+}
339
+
340
+static const VMStateDescription vmstate_xram_ctrl = {
341
+ .name = TYPE_XLNX_XRAM_CTRL,
342
+ .version_id = 1,
343
+ .minimum_version_id = 1,
344
+ .fields = (VMStateField[]) {
345
+ VMSTATE_UINT32_ARRAY(regs, XlnxXramCtrl, XRAM_CTRL_R_MAX),
346
+ VMSTATE_END_OF_LIST(),
347
+ }
348
+};
349
+
350
+static Property xram_ctrl_properties[] = {
351
+ DEFINE_PROP_UINT64("size", XlnxXramCtrl, cfg.size, 1 * MiB),
352
+ DEFINE_PROP_END_OF_LIST(),
353
+};
354
+
355
+static void xram_ctrl_class_init(ObjectClass *klass, void *data)
356
+{
357
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
358
+ DeviceClass *dc = DEVICE_CLASS(klass);
359
+
360
+ dc->realize = xram_ctrl_realize;
361
+ dc->vmsd = &vmstate_xram_ctrl;
362
+ device_class_set_props(dc, xram_ctrl_properties);
363
+
364
+ rc->phases.enter = xram_ctrl_reset_enter;
365
+ rc->phases.hold = xram_ctrl_reset_hold;
366
+}
367
+
368
+static const TypeInfo xram_ctrl_info = {
369
+ .name = TYPE_XLNX_XRAM_CTRL,
370
+ .parent = TYPE_SYS_BUS_DEVICE,
371
+ .instance_size = sizeof(XlnxXramCtrl),
372
+ .class_init = xram_ctrl_class_init,
373
+ .instance_init = xram_ctrl_init,
374
+ .instance_finalize = xram_ctrl_finalize,
375
+};
376
+
377
+static void xram_ctrl_register_types(void)
378
+{
379
+ type_register_static(&xram_ctrl_info);
380
+}
381
+
382
+type_init(xram_ctrl_register_types)
383
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
384
index XXXXXXX..XXXXXXX 100644
305
index XXXXXXX..XXXXXXX 100644
385
--- a/hw/misc/meson.build
306
--- a/hw/arm/Kconfig
386
+++ b/hw/misc/meson.build
307
+++ b/hw/arm/Kconfig
387
@@ -XXX,XX +XXX,XX @@ softmmu_ss.add(when: 'CONFIG_RASPI', if_true: files(
308
@@ -XXX,XX +XXX,XX @@ config MAINSTONE
388
))
309
select PFLASH_CFI01
389
softmmu_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
310
select SMC91C111
390
softmmu_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c', 'zynq-xadc.c'))
311
391
+softmmu_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal-xramc.c'))
312
+config MPS3R
392
softmmu_ss.add(when: 'CONFIG_STM32F2XX_SYSCFG', if_true: files('stm32f2xx_syscfg.c'))
313
+ bool
393
softmmu_ss.add(when: 'CONFIG_STM32F4XX_SYSCFG', if_true: files('stm32f4xx_syscfg.c'))
314
+ default y
394
softmmu_ss.add(when: 'CONFIG_STM32F4XX_EXTI', if_true: files('stm32f4xx_exti.c'))
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'))
395
--
332
--
396
2.20.1
333
2.34.1
397
334
398
335
diff view generated by jsdifflib
Deleted patch
1
From: "Edgar E. Iglesias" <edgar.iglesias@xilinx.com>
2
1
3
Connect the support for the Versal Accelerator RAMs (XRAMs).
4
5
Reviewed-by: Luc Michel <luc@lmichel.fr>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com>
8
Message-id: 20210308224637.2949533-3-edgar.iglesias@gmail.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
docs/system/arm/xlnx-versal-virt.rst | 1 +
12
include/hw/arm/xlnx-versal.h | 13 ++++++++++
13
hw/arm/xlnx-versal.c | 36 ++++++++++++++++++++++++++++
14
3 files changed, 50 insertions(+)
15
16
diff --git a/docs/system/arm/xlnx-versal-virt.rst b/docs/system/arm/xlnx-versal-virt.rst
17
index XXXXXXX..XXXXXXX 100644
18
--- a/docs/system/arm/xlnx-versal-virt.rst
19
+++ b/docs/system/arm/xlnx-versal-virt.rst
20
@@ -XXX,XX +XXX,XX @@ Implemented devices:
21
- 8 ADMA (Xilinx zDMA) channels
22
- 2 SD Controllers
23
- OCM (256KB of On Chip Memory)
24
+- XRAM (4MB of on chip Accelerator RAM)
25
- DDR memory
26
27
QEMU does not yet model any other devices, including the PL and the AI Engine.
28
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
29
index XXXXXXX..XXXXXXX 100644
30
--- a/include/hw/arm/xlnx-versal.h
31
+++ b/include/hw/arm/xlnx-versal.h
32
@@ -XXX,XX +XXX,XX @@
33
34
#include "hw/sysbus.h"
35
#include "hw/arm/boot.h"
36
+#include "hw/or-irq.h"
37
#include "hw/sd/sdhci.h"
38
#include "hw/intc/arm_gicv3.h"
39
#include "hw/char/pl011.h"
40
@@ -XXX,XX +XXX,XX @@
41
#include "hw/rtc/xlnx-zynqmp-rtc.h"
42
#include "qom/object.h"
43
#include "hw/usb/xlnx-usb-subsystem.h"
44
+#include "hw/misc/xlnx-versal-xramc.h"
45
46
#define TYPE_XLNX_VERSAL "xlnx-versal"
47
OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
48
@@ -XXX,XX +XXX,XX @@ OBJECT_DECLARE_SIMPLE_TYPE(Versal, XLNX_VERSAL)
49
#define XLNX_VERSAL_NR_GEMS 2
50
#define XLNX_VERSAL_NR_ADMAS 8
51
#define XLNX_VERSAL_NR_SDS 2
52
+#define XLNX_VERSAL_NR_XRAM 4
53
#define XLNX_VERSAL_NR_IRQS 192
54
55
struct Versal {
56
@@ -XXX,XX +XXX,XX @@ struct Versal {
57
XlnxZDMA adma[XLNX_VERSAL_NR_ADMAS];
58
VersalUsb2 usb;
59
} iou;
60
+
61
+ struct {
62
+ qemu_or_irq irq_orgate;
63
+ XlnxXramCtrl ctrl[XLNX_VERSAL_NR_XRAM];
64
+ } xram;
65
} lpd;
66
67
/* The Platform Management Controller subsystem. */
68
@@ -XXX,XX +XXX,XX @@ struct Versal {
69
#define VERSAL_GEM1_IRQ_0 58
70
#define VERSAL_GEM1_WAKE_IRQ_0 59
71
#define VERSAL_ADMA_IRQ_0 60
72
+#define VERSAL_XRAM_IRQ_0 79
73
#define VERSAL_RTC_APB_ERR_IRQ 121
74
#define VERSAL_SD0_IRQ_0 126
75
#define VERSAL_RTC_ALARM_IRQ 142
76
@@ -XXX,XX +XXX,XX @@ struct Versal {
77
#define MM_OCM 0xfffc0000U
78
#define MM_OCM_SIZE 0x40000
79
80
+#define MM_XRAM 0xfe800000
81
+#define MM_XRAMC 0xff8e0000
82
+#define MM_XRAMC_SIZE 0x10000
83
+
84
#define MM_USB2_CTRL_REGS 0xFF9D0000
85
#define MM_USB2_CTRL_REGS_SIZE 0x10000
86
87
diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c
88
index XXXXXXX..XXXXXXX 100644
89
--- a/hw/arm/xlnx-versal.c
90
+++ b/hw/arm/xlnx-versal.c
91
@@ -XXX,XX +XXX,XX @@
92
*/
93
94
#include "qemu/osdep.h"
95
+#include "qemu/units.h"
96
#include "qapi/error.h"
97
#include "qemu/log.h"
98
#include "qemu/module.h"
99
@@ -XXX,XX +XXX,XX @@ static void versal_create_rtc(Versal *s, qemu_irq *pic)
100
sysbus_connect_irq(sbd, 1, pic[VERSAL_RTC_APB_ERR_IRQ]);
101
}
102
103
+static void versal_create_xrams(Versal *s, qemu_irq *pic)
104
+{
105
+ int nr_xrams = ARRAY_SIZE(s->lpd.xram.ctrl);
106
+ DeviceState *orgate;
107
+ int i;
108
+
109
+ /* XRAM IRQs get ORed into a single line. */
110
+ object_initialize_child(OBJECT(s), "xram-irq-orgate",
111
+ &s->lpd.xram.irq_orgate, TYPE_OR_IRQ);
112
+ orgate = DEVICE(&s->lpd.xram.irq_orgate);
113
+ object_property_set_int(OBJECT(orgate),
114
+ "num-lines", nr_xrams, &error_fatal);
115
+ qdev_realize(orgate, NULL, &error_fatal);
116
+ qdev_connect_gpio_out(orgate, 0, pic[VERSAL_XRAM_IRQ_0]);
117
+
118
+ for (i = 0; i < ARRAY_SIZE(s->lpd.xram.ctrl); i++) {
119
+ SysBusDevice *sbd;
120
+ MemoryRegion *mr;
121
+
122
+ object_initialize_child(OBJECT(s), "xram[*]", &s->lpd.xram.ctrl[i],
123
+ TYPE_XLNX_XRAM_CTRL);
124
+ sbd = SYS_BUS_DEVICE(&s->lpd.xram.ctrl[i]);
125
+ sysbus_realize(sbd, &error_fatal);
126
+
127
+ mr = sysbus_mmio_get_region(sbd, 0);
128
+ memory_region_add_subregion(&s->mr_ps,
129
+ MM_XRAMC + i * MM_XRAMC_SIZE, mr);
130
+ mr = sysbus_mmio_get_region(sbd, 1);
131
+ memory_region_add_subregion(&s->mr_ps, MM_XRAM + i * MiB, mr);
132
+
133
+ sysbus_connect_irq(sbd, 0, qdev_get_gpio_in(orgate, i));
134
+ }
135
+}
136
+
137
/* This takes the board allocated linear DDR memory and creates aliases
138
* for each split DDR range/aperture on the Versal address map.
139
*/
140
@@ -XXX,XX +XXX,XX @@ static void versal_realize(DeviceState *dev, Error **errp)
141
versal_create_admas(s, pic);
142
versal_create_sds(s, pic);
143
versal_create_rtc(s, pic);
144
+ versal_create_xrams(s, pic);
145
versal_map_ddr(s);
146
versal_unimp(s);
147
148
--
149
2.20.1
150
151
diff view generated by jsdifflib
1
From: Hao Wu <wuhaotsh@google.com>
1
Create the CPUs, the GIC, and the per-CPU RAM block for
2
the mps3-an536 board.
2
3
3
This patch adds fan_splitters (split IRQs) in NPCM7XX boards. Each fan
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
splitter corresponds to 1 PWM output and can connect to multiple fan
5
Message-id: 20240206132931.38376-10-peter.maydell@linaro.org
5
inputs (MFT devices).
6
---
6
In NPCM7XX boards(NPCM750 EVB and Quanta GSJ boards), we initializes
7
hw/arm/mps3r.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++++-
7
these splitters and connect them to their corresponding modules
8
1 file changed, 177 insertions(+), 3 deletions(-)
8
according their specific device trees.
9
9
10
Reviewed-by: Doug Evans <dje@google.com>
10
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
11
Reviewed-by: Tyrone Ting <kfting@nuvoton.com>
12
Signed-off-by: Hao Wu <wuhaotsh@google.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20210311180855.149764-5-wuhaotsh@google.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/arm/npcm7xx.h | 11 ++++-
18
hw/arm/npcm7xx_boards.c | 99 ++++++++++++++++++++++++++++++++++++++++
19
2 files changed, 109 insertions(+), 1 deletion(-)
20
21
diff --git a/include/hw/arm/npcm7xx.h b/include/hw/arm/npcm7xx.h
22
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/npcm7xx.h
12
--- a/hw/arm/mps3r.c
24
+++ b/include/hw/arm/npcm7xx.h
13
+++ b/hw/arm/mps3r.c
25
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
26
15
#include "qemu/osdep.h"
16
#include "qemu/units.h"
17
#include "qapi/error.h"
18
+#include "qapi/qmp/qlist.h"
19
#include "exec/address-spaces.h"
20
#include "cpu.h"
27
#include "hw/boards.h"
21
#include "hw/boards.h"
28
#include "hw/adc/npcm7xx_adc.h"
22
+#include "hw/qdev-properties.h"
29
+#include "hw/core/split-irq.h"
23
#include "hw/arm/boot.h"
30
#include "hw/cpu/a9mpcore.h"
24
+#include "hw/arm/bsa.h"
31
#include "hw/gpio/npcm7xx_gpio.h"
25
+#include "hw/intc/arm_gicv3.h"
32
#include "hw/i2c/npcm7xx_smbus.h"
26
33
@@ -XXX,XX +XXX,XX @@
27
/* Define the layout of RAM and ROM in a board */
34
#define NPCM7XX_GIC_CPU_IF_ADDR (0xf03fe100) /* GIC within A9 */
28
typedef struct RAMInfo {
35
#define NPCM7XX_BOARD_SETUP_ADDR (0xffff1000) /* Boot ROM */
29
@@ -XXX,XX +XXX,XX @@ typedef struct RAMInfo {
36
30
#define IS_ROM 2
37
+#define NPCM7XX_NR_PWM_MODULES 2
31
38
+
32
#define MPS3R_RAM_MAX 9
39
typedef struct NPCM7xxMachine {
33
+#define MPS3R_CPU_MAX 2
40
MachineState parent;
34
+
35
+#define PERIPHBASE 0xf0000000
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;
45
};
46
47
struct MPS3RMachineState {
48
MachineState parent;
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)
78
+{
41
+ /*
79
+ /*
42
+ * PWM fan splitter. each splitter connects to one PWM output and
80
+ * Power the secondary CPU off. This means we don't need to write any
43
+ * multiple MFT inputs.
81
+ * boot code into guest memory. Note that the 'cpu' argument to this
82
+ * function is the primary CPU we passed to arm_load_kernel(), not
83
+ * the secondary. Loop around all the other CPUs, as the boot.c
84
+ * code does for the "disable secondaries if PSCI is enabled" case.
44
+ */
85
+ */
45
+ SplitIRQ fan_splitter[NPCM7XX_NR_PWM_MODULES *
86
+ for (CPUState *cs = first_cpu; cs; cs = CPU_NEXT(cs)) {
46
+ NPCM7XX_PWM_PER_MODULE];
87
+ if (cs != first_cpu) {
47
} NPCM7xxMachine;
88
+ object_property_set_bool(OBJECT(cs), "start-powered-off", true,
48
89
+ &error_abort);
49
#define TYPE_NPCM7XX_MACHINE MACHINE_TYPE_NAME("npcm7xx")
50
@@ -XXX,XX +XXX,XX @@ typedef struct NPCM7xxState {
51
NPCM7xxCLKState clk;
52
NPCM7xxTimerCtrlState tim[3];
53
NPCM7xxADCState adc;
54
- NPCM7xxPWMState pwm[2];
55
+ NPCM7xxPWMState pwm[NPCM7XX_NR_PWM_MODULES];
56
NPCM7xxMFTState mft[8];
57
NPCM7xxOTPState key_storage;
58
NPCM7xxOTPState fuse_array;
59
diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c
60
index XXXXXXX..XXXXXXX 100644
61
--- a/hw/arm/npcm7xx_boards.c
62
+++ b/hw/arm/npcm7xx_boards.c
63
@@ -XXX,XX +XXX,XX @@
64
#include "hw/core/cpu.h"
65
#include "hw/i2c/smbus_eeprom.h"
66
#include "hw/loader.h"
67
+#include "hw/qdev-core.h"
68
#include "hw/qdev-properties.h"
69
#include "qapi/error.h"
70
#include "qemu-common.h"
71
@@ -XXX,XX +XXX,XX @@ static void at24c_eeprom_init(NPCM7xxState *soc, int bus, uint8_t addr,
72
i2c_slave_realize_and_unref(i2c_dev, i2c_bus, &error_abort);
73
}
74
75
+static void npcm7xx_init_pwm_splitter(NPCM7xxMachine *machine,
76
+ NPCM7xxState *soc, const int *fan_counts)
77
+{
78
+ SplitIRQ *splitters = machine->fan_splitter;
79
+
80
+ /*
81
+ * PWM 0~3 belong to module 0 output 0~3.
82
+ * PWM 4~7 belong to module 1 output 0~3.
83
+ */
84
+ for (int i = 0; i < NPCM7XX_NR_PWM_MODULES; ++i) {
85
+ for (int j = 0; j < NPCM7XX_PWM_PER_MODULE; ++j) {
86
+ int splitter_no = i * NPCM7XX_PWM_PER_MODULE + j;
87
+ DeviceState *splitter;
88
+
89
+ if (fan_counts[splitter_no] < 1) {
90
+ continue;
91
+ }
92
+ object_initialize_child(OBJECT(machine), "fan-splitter[*]",
93
+ &splitters[splitter_no], TYPE_SPLIT_IRQ);
94
+ splitter = DEVICE(&splitters[splitter_no]);
95
+ qdev_prop_set_uint16(splitter, "num-lines",
96
+ fan_counts[splitter_no]);
97
+ qdev_realize(splitter, NULL, &error_abort);
98
+ qdev_connect_gpio_out_named(DEVICE(&soc->pwm[i]), "duty-gpio-out",
99
+ j, qdev_get_gpio_in(splitter, 0));
100
+ }
90
+ }
101
+ }
91
+ }
102
+}
92
+}
103
+
93
+
104
+static void npcm7xx_connect_pwm_fan(NPCM7xxState *soc, SplitIRQ *splitter,
94
+static void mps3r_secondary_cpu_reset(ARMCPU *cpu,
105
+ int fan_no, int output_no)
95
+ const struct arm_boot_info *info)
106
+{
96
+{
107
+ DeviceState *fan;
97
+ /* We don't need to do anything here because the CPU will be off */
108
+ int fan_input;
98
+}
109
+ qemu_irq fan_duty_gpio;
99
+
110
+
100
+static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
111
+ g_assert(fan_no >= 0 && fan_no <= NPCM7XX_MFT_MAX_FAN_INPUT);
101
+{
102
+ MachineState *machine = MACHINE(mms);
103
+ DeviceState *gicdev;
104
+ QList *redist_region_count;
105
+
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);
112
+ /*
118
+ /*
113
+ * Fan 0~1 belong to module 0 input 0~1.
119
+ * Wire the outputs from each CPU's generic timer and the GICv3
114
+ * Fan 2~3 belong to module 1 input 0~1.
120
+ * maintenance interrupt signal to the appropriate GIC PPI inputs,
115
+ * ...
121
+ * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs.
116
+ * Fan 14~15 belong to module 7 input 0~1.
117
+ * Fan 16~17 belong to module 0 input 2~3.
118
+ * Fan 18~19 belong to module 1 input 2~3.
119
+ */
122
+ */
120
+ if (fan_no < 16) {
123
+ for (int i = 0; i < machine->smp.cpus; i++) {
121
+ fan = DEVICE(&soc->mft[fan_no / 2]);
124
+ DeviceState *cpudev = DEVICE(mms->cpu[i]);
122
+ fan_input = fan_no % 2;
125
+ SysBusDevice *gicsbd = SYS_BUS_DEVICE(&mms->gic);
123
+ } else {
126
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
124
+ fan = DEVICE(&soc->mft[(fan_no - 16) / 2]);
127
+ int irq;
125
+ fan_input = fan_no % 2 + 2;
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));
126
+ }
161
+ }
127
+
128
+ /* Connect the Fan to PWM module */
129
+ fan_duty_gpio = qdev_get_gpio_in_named(fan, "duty", fan_input);
130
+ qdev_connect_gpio_out(DEVICE(splitter), output_no, fan_duty_gpio);
131
+}
162
+}
132
+
163
+
133
static void npcm750_evb_i2c_init(NPCM7xxState *soc)
164
static void mps3r_common_init(MachineState *machine)
134
{
165
{
135
/* lm75 temperature sensor on SVB, tmp105 is compatible */
166
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
136
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_i2c_init(NPCM7xxState *soc)
167
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
137
i2c_slave_create_simple(npcm7xx_i2c_get_bus(soc, 6), "tmp105", 0x48);
168
MemoryRegion *mr = mr_for_raminfo(mms, ri);
169
memory_region_add_subregion(sysmem, ri->base, mr);
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);
138
}
215
}
139
216
140
+static void npcm750_evb_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
217
static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
141
+{
218
@@ -XXX,XX +XXX,XX @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc)
142
+ SplitIRQ *splitter = machine->fan_splitter;
219
/* Found the entry for "system memory" */
143
+ static const int fan_counts[] = {2, 2, 2, 2, 2, 2, 2, 2};
220
mc->default_ram_size = p->size;
144
+
221
mc->default_ram_id = p->name;
145
+ npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
222
+ mmc->loader_start = p->base;
146
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
223
return;
147
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
224
}
148
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
225
}
149
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
226
@@ -XXX,XX +XXX,XX @@ static void mps3r_an536_class_init(ObjectClass *oc, void *data)
150
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
227
};
151
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
228
152
+ npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x06, 0);
229
mc->desc = "ARM MPS3 with AN536 FPGA image for Cortex-R52";
153
+ npcm7xx_connect_pwm_fan(soc, &splitter[3], 0x07, 1);
230
- mc->default_cpus = 2;
154
+ npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x08, 0);
231
- mc->min_cpus = mc->default_cpus;
155
+ npcm7xx_connect_pwm_fan(soc, &splitter[4], 0x09, 1);
232
- mc->max_cpus = mc->default_cpus;
156
+ npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0a, 0);
233
+ /*
157
+ npcm7xx_connect_pwm_fan(soc, &splitter[5], 0x0b, 1);
234
+ * In the real FPGA image there are always two cores, but the standard
158
+ npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0c, 0);
235
+ * initial setting for the SCC SYSCON 0x000 register is 0x21, meaning
159
+ npcm7xx_connect_pwm_fan(soc, &splitter[6], 0x0d, 1);
236
+ * that the second core is held in reset and halted. Many images built for
160
+ npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0e, 0);
237
+ * the board do not expect the second core to run at startup (especially
161
+ npcm7xx_connect_pwm_fan(soc, &splitter[7], 0x0f, 1);
238
+ * since on the real FPGA image it is not possible to use LDREX/STREX
162
+}
239
+ * in RAM between the two cores, so a true SMP setup isn't supported).
163
+
240
+ *
164
static void quanta_gsj_i2c_init(NPCM7xxState *soc)
241
+ * As QEMU's equivalent of this, we support both -smp 1 and -smp 2,
165
{
242
+ * with the default being -smp 1. This seems a more intuitive UI for
166
/* GSJ machine have 4 max31725 temperature sensors, tmp105 is compatible. */
243
+ * QEMU users than, for instance, having a machine property to allow
167
@@ -XXX,XX +XXX,XX @@ static void quanta_gsj_i2c_init(NPCM7xxState *soc)
244
+ * the user to set the initial value of the SYSCON 0x000 register.
168
/* TODO: Add additional i2c devices. */
245
+ */
169
}
246
+ mc->default_cpus = 1;
170
247
+ mc->min_cpus = 1;
171
+static void quanta_gsj_fan_init(NPCM7xxMachine *machine, NPCM7xxState *soc)
248
+ mc->max_cpus = 2;
172
+{
249
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-r52");
173
+ SplitIRQ *splitter = machine->fan_splitter;
250
mc->valid_cpu_types = valid_cpu_types;
174
+ static const int fan_counts[] = {2, 2, 2, 0, 0, 0, 0, 0};
251
mmc->raminfo = an536_raminfo;
175
+
176
+ npcm7xx_init_pwm_splitter(machine, soc, fan_counts);
177
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x00, 0);
178
+ npcm7xx_connect_pwm_fan(soc, &splitter[0], 0x01, 1);
179
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x02, 0);
180
+ npcm7xx_connect_pwm_fan(soc, &splitter[1], 0x03, 1);
181
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x04, 0);
182
+ npcm7xx_connect_pwm_fan(soc, &splitter[2], 0x05, 1);
183
+}
184
+
185
static void npcm750_evb_init(MachineState *machine)
186
{
187
NPCM7xxState *soc;
188
@@ -XXX,XX +XXX,XX @@ static void npcm750_evb_init(MachineState *machine)
189
npcm7xx_load_bootrom(machine, soc);
190
npcm7xx_connect_flash(&soc->fiu[0], 0, "w25q256", drive_get(IF_MTD, 0, 0));
191
npcm750_evb_i2c_init(soc);
192
+ npcm750_evb_fan_init(NPCM7XX_MACHINE(machine), soc);
193
npcm7xx_load_kernel(machine, soc);
194
}
195
196
@@ -XXX,XX +XXX,XX @@ static void quanta_gsj_init(MachineState *machine)
197
npcm7xx_connect_flash(&soc->fiu[0], 0, "mx25l25635e",
198
drive_get(IF_MTD, 0, 0));
199
quanta_gsj_i2c_init(soc);
200
+ quanta_gsj_fan_init(NPCM7XX_MACHINE(machine), soc);
201
npcm7xx_load_kernel(machine, soc);
202
}
203
204
--
252
--
205
2.20.1
253
2.34.1
206
207
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
This board has a lot of UARTs: there is one UART per CPU in the
2
per-CPU peripheral part of the address map, whose interrupts are
3
connected as per-CPU interrupt lines. Then there are 4 UARTs in the
4
normal part of the peripheral space, whose interrupts are shared
5
peripheral interrupts.
2
6
3
If the whole SID range (32b) is invalidated (SMMU_CMD_CFGI_ALL),
7
Connect and wire them all up; this involves some OR gates where
4
@end overflows and we fail to handle the command properly.
8
multiple overflow interrupts are wired into one GIC input.
5
9
6
Once this gets fixed, the current code really is awkward in the
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
sense it loops over the whole range instead of removing the
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
currently cached configs through a hash table lookup.
12
Message-id: 20240206132931.38376-11-peter.maydell@linaro.org
13
---
14
hw/arm/mps3r.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++
15
1 file changed, 94 insertions(+)
9
16
10
Fix both the overflow and the lookup.
17
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
11
12
Signed-off-by: Eric Auger <eric.auger@redhat.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20210309102742.30442-7-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
hw/arm/smmu-internal.h | 5 +++++
18
hw/arm/smmuv3.c | 34 ++++++++++++++++++++--------------
19
2 files changed, 25 insertions(+), 14 deletions(-)
20
21
diff --git a/hw/arm/smmu-internal.h b/hw/arm/smmu-internal.h
22
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
23
--- a/hw/arm/smmu-internal.h
19
--- a/hw/arm/mps3r.c
24
+++ b/hw/arm/smmu-internal.h
20
+++ b/hw/arm/mps3r.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUIOTLBPageInvInfo {
21
@@ -XXX,XX +XXX,XX @@
26
uint64_t mask;
22
#include "qapi/qmp/qlist.h"
27
} SMMUIOTLBPageInvInfo;
23
#include "exec/address-spaces.h"
28
24
#include "cpu.h"
29
+typedef struct SMMUSIDRange {
25
+#include "sysemu/sysemu.h"
30
+ uint32_t start;
26
#include "hw/boards.h"
31
+ uint32_t end;
27
+#include "hw/or-irq.h"
32
+} SMMUSIDRange;
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
33
+
64
+
34
#endif
65
static const RAMInfo an536_raminfo[] = {
35
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
66
{
36
index XXXXXXX..XXXXXXX 100644
67
.name = "ATCM",
37
--- a/hw/arm/smmuv3.c
68
@@ -XXX,XX +XXX,XX @@ static void create_gic(MPS3RMachineState *mms, MemoryRegion *sysmem)
38
+++ b/hw/arm/smmuv3.c
39
@@ -XXX,XX +XXX,XX @@
40
41
#include "hw/arm/smmuv3.h"
42
#include "smmuv3-internal.h"
43
+#include "smmu-internal.h"
44
45
/**
46
* smmuv3_trigger_irq - pulse @irq if enabled and update
47
@@ -XXX,XX +XXX,XX @@ static void smmuv3_s1_range_inval(SMMUState *s, Cmd *cmd)
48
}
69
}
49
}
70
}
50
71
51
+static gboolean
72
+/*
52
+smmuv3_invalidate_ste(gpointer key, gpointer value, gpointer user_data)
73
+ * Create UART uartno, and map it into the MemoryRegion mem at address baseaddr.
74
+ * The qemu_irq arguments are where we connect the various IRQs from the UART.
75
+ */
76
+static void create_uart(MPS3RMachineState *mms, int uartno, MemoryRegion *mem,
77
+ hwaddr baseaddr, qemu_irq txirq, qemu_irq rxirq,
78
+ qemu_irq txoverirq, qemu_irq rxoverirq,
79
+ qemu_irq combirq)
53
+{
80
+{
54
+ SMMUDevice *sdev = (SMMUDevice *)key;
81
+ g_autofree char *s = g_strdup_printf("uart%d", uartno);
55
+ uint32_t sid = smmu_get_sid(sdev);
82
+ SysBusDevice *sbd;
56
+ SMMUSIDRange *sid_range = (SMMUSIDRange *)user_data;
57
+
83
+
58
+ if (sid < sid_range->start || sid > sid_range->end) {
84
+ assert(uartno < ARRAY_SIZE(mms->uart));
59
+ return false;
85
+ object_initialize_child(OBJECT(mms), s, &mms->uart[uartno],
60
+ }
86
+ TYPE_CMSDK_APB_UART);
61
+ trace_smmuv3_config_cache_inv(sid);
87
+ qdev_prop_set_uint32(DEVICE(&mms->uart[uartno]), "pclk-frq", CLK_FRQ);
62
+ return true;
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);
63
+}
98
+}
64
+
99
+
65
static int smmuv3_cmdq_consume(SMMUv3State *s)
100
static void mps3r_common_init(MachineState *machine)
66
{
101
{
67
SMMUState *bs = ARM_SMMU(s);
102
MPS3RMachineState *mms = MPS3R_MACHINE(machine);
68
@@ -XXX,XX +XXX,XX @@ static int smmuv3_cmdq_consume(SMMUv3State *s)
103
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
69
}
104
MemoryRegion *sysmem = get_system_memory();
70
case SMMU_CMD_CFGI_STE_RANGE: /* same as SMMU_CMD_CFGI_ALL */
105
+ DeviceState *gicdev;
71
{
106
72
- uint32_t start = CMD_SID(&cmd), end, i;
107
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
73
+ uint32_t start = CMD_SID(&cmd);
108
MemoryRegion *mr = mr_for_raminfo(mms, ri);
74
uint8_t range = CMD_STE_RANGE(&cmd);
109
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
75
+ uint64_t end = start + (1ULL << (range + 1)) - 1;
110
}
76
+ SMMUSIDRange sid_range = {start, end};
111
77
112
create_gic(mms, sysmem);
78
if (CMD_SSEC(&cmd)) {
113
+ gicdev = DEVICE(&mms->gic);
79
cmd_error = SMMU_CERROR_ILL;
114
+
80
break;
115
+ /*
81
}
116
+ * UARTs 0 and 1 are per-CPU; their interrupts are wired to
82
-
117
+ * the relevant CPU's PPI 0..3, aka INTID 16..19
83
- end = start + (1 << (range + 1)) - 1;
118
+ */
84
trace_smmuv3_cmdq_cfgi_ste_range(start, end);
119
+ for (int i = 0; i < machine->smp.cpus; i++) {
85
-
120
+ int intidbase = NUM_SPIS + i * GIC_INTERNAL;
86
- for (i = start; i <= end; i++) {
121
+ g_autofree char *s = g_strdup_printf("cpu-uart-oflow-orgate%d", i);
87
- IOMMUMemoryRegion *mr = smmu_iommu_mr(bs, i);
122
+ DeviceState *orgate;
88
- SMMUDevice *sdev;
123
+
89
-
124
+ /* The two overflow IRQs from the UART are ORed together into PPI 3 */
90
- if (!mr) {
125
+ object_initialize_child(OBJECT(mms), s, &mms->cpu_uart_oflow[i],
91
- continue;
126
+ TYPE_OR_IRQ);
92
- }
127
+ orgate = DEVICE(&mms->cpu_uart_oflow[i]);
93
- sdev = container_of(mr, SMMUDevice, iommu);
128
+ qdev_prop_set_uint32(orgate, "num-lines", 2);
94
- smmuv3_flush_config(sdev);
129
+ qdev_realize(orgate, NULL, &error_fatal);
95
- }
130
+ qdev_connect_gpio_out(orgate, 0,
96
+ g_hash_table_foreach_remove(bs->configs, smmuv3_invalidate_ste,
131
+ qdev_get_gpio_in(gicdev, intidbase + 19));
97
+ &sid_range);
132
+
98
break;
133
+ create_uart(mms, i, &mms->cpu_sysmem[i], 0xe7c00000,
99
}
134
+ qdev_get_gpio_in(gicdev, intidbase + 17), /* tx */
100
case SMMU_CMD_CFGI_CD:
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;
101
--
166
--
102
2.20.1
167
2.34.1
103
168
104
169
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
Add the GPIO, watchdog, dual-timer and I2C devices to the mps3-an536
2
board. These are all simple devices that just need to be created and
3
wired up.
2
4
3
Currently get_naturally_aligned_size() is used by the intel iommu
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
to compute the maximum invalidation range based on @size which is
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
a power of 2 while being aligned with the @start address and less
7
Message-id: 20240206132931.38376-12-peter.maydell@linaro.org
6
than the maximum range defined by @gaw.
8
---
9
hw/arm/mps3r.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
10
1 file changed, 59 insertions(+)
7
11
8
This helper is also useful for other iommu devices (virtio-iommu,
12
diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c
9
SMMUv3) to make sure IOMMU UNMAP notifiers only are called with
10
power of 2 range sizes.
11
12
Let's move this latter into dma-helpers.c and rename it into
13
dma_aligned_pow2_mask(). Also rewrite the helper so that it
14
accomodates UINT64_MAX values for the size mask and max mask.
15
It now returns a mask instead of a size. Change the caller.
16
17
Signed-off-by: Eric Auger <eric.auger@redhat.com>
18
Reviewed-by: Peter Xu <peterx@redhat.com>
19
Message-id: 20210309102742.30442-3-eric.auger@redhat.com
20
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
21
---
22
include/sysemu/dma.h | 12 ++++++++++++
23
hw/i386/intel_iommu.c | 30 +++++++-----------------------
24
softmmu/dma-helpers.c | 26 ++++++++++++++++++++++++++
25
3 files changed, 45 insertions(+), 23 deletions(-)
26
27
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
28
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
29
--- a/include/sysemu/dma.h
14
--- a/hw/arm/mps3r.c
30
+++ b/include/sysemu/dma.h
15
+++ b/hw/arm/mps3r.c
31
@@ -XXX,XX +XXX,XX @@ uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
16
@@ -XXX,XX +XXX,XX @@
32
void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
17
#include "sysemu/sysemu.h"
33
QEMUSGList *sg, enum BlockAcctType type);
18
#include "hw/boards.h"
34
19
#include "hw/or-irq.h"
35
+/**
20
+#include "hw/qdev-clock.h"
36
+ * dma_aligned_pow2_mask: Return the address bit mask of the largest
21
#include "hw/qdev-properties.h"
37
+ * power of 2 size less or equal than @end - @start + 1, aligned with @start,
22
#include "hw/arm/boot.h"
38
+ * and bounded by 1 << @max_addr_bits bits.
23
#include "hw/arm/bsa.h"
39
+ *
24
#include "hw/char/cmsdk-apb-uart.h"
40
+ * @start: range start address
25
+#include "hw/i2c/arm_sbcon_i2c.h"
41
+ * @end: range end address (greater than @start)
26
#include "hw/intc/arm_gicv3.h"
42
+ * @max_addr_bits: max address bits (<= 64)
27
+#include "hw/misc/unimp.h"
43
+ */
28
+#include "hw/timer/cmsdk-apb-dualtimer.h"
44
+uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end,
29
+#include "hw/watchdog/cmsdk-apb-watchdog.h"
45
+ int max_addr_bits);
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);
46
+
50
+
47
#endif
51
for (const RAMInfo *ri = mmc->raminfo; ri->name; ri++) {
48
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
52
MemoryRegion *mr = mr_for_raminfo(mms, ri);
49
index XXXXXXX..XXXXXXX 100644
53
memory_region_add_subregion(sysmem, ri->base, mr);
50
--- a/hw/i386/intel_iommu.c
54
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
51
+++ b/hw/i386/intel_iommu.c
55
qdev_get_gpio_in(gicdev, combirq));
52
@@ -XXX,XX +XXX,XX @@
53
#include "hw/i386/x86-iommu.h"
54
#include "hw/pci-host/q35.h"
55
#include "sysemu/kvm.h"
56
+#include "sysemu/dma.h"
57
#include "sysemu/sysemu.h"
58
#include "hw/i386/apic_internal.h"
59
#include "kvm/kvm_i386.h"
60
@@ -XXX,XX +XXX,XX @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, int devfn)
61
return vtd_dev_as;
62
}
63
64
-static uint64_t get_naturally_aligned_size(uint64_t start,
65
- uint64_t size, int gaw)
66
-{
67
- uint64_t max_mask = 1ULL << gaw;
68
- uint64_t alignment = start ? start & -start : max_mask;
69
-
70
- alignment = MIN(alignment, max_mask);
71
- size = MIN(size, max_mask);
72
-
73
- if (alignment <= size) {
74
- /* Increase the alignment of start */
75
- return alignment;
76
- } else {
77
- /* Find the largest page mask from size */
78
- return 1ULL << (63 - clz64(size));
79
- }
80
-}
81
-
82
/* Unmap the whole range in the notifier's scope. */
83
static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
84
{
85
@@ -XXX,XX +XXX,XX @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
86
87
while (remain >= VTD_PAGE_SIZE) {
88
IOMMUTLBEvent event;
89
- uint64_t mask = get_naturally_aligned_size(start, remain, s->aw_bits);
90
+ uint64_t mask = dma_aligned_pow2_mask(start, end, s->aw_bits);
91
+ uint64_t size = mask + 1;
92
93
- assert(mask);
94
+ assert(size);
95
96
event.type = IOMMU_NOTIFIER_UNMAP;
97
event.entry.iova = start;
98
- event.entry.addr_mask = mask - 1;
99
+ event.entry.addr_mask = mask;
100
event.entry.target_as = &address_space_memory;
101
event.entry.perm = IOMMU_NONE;
102
/* This field is meaningless for unmap */
103
@@ -XXX,XX +XXX,XX @@ static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n)
104
105
memory_region_notify_iommu_one(n, &event);
106
107
- start += mask;
108
- remain -= mask;
109
+ start += size;
110
+ remain -= size;
111
}
56
}
112
57
113
assert(!remain);
58
+ for (int i = 0; i < 4; i++) {
114
diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c
59
+ /* CMSDK GPIO controllers */
115
index XXXXXXX..XXXXXXX 100644
60
+ g_autofree char *s = g_strdup_printf("gpio%d", i);
116
--- a/softmmu/dma-helpers.c
61
+ create_unimplemented_device(s, 0xe0000000 + i * 0x1000, 0x1000);
117
+++ b/softmmu/dma-helpers.c
118
@@ -XXX,XX +XXX,XX @@ void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie,
119
{
120
block_acct_start(blk_get_stats(blk), cookie, sg->size, type);
121
}
122
+
123
+uint64_t dma_aligned_pow2_mask(uint64_t start, uint64_t end, int max_addr_bits)
124
+{
125
+ uint64_t max_mask = UINT64_MAX, addr_mask = end - start;
126
+ uint64_t alignment_mask, size_mask;
127
+
128
+ if (max_addr_bits != 64) {
129
+ max_mask = (1ULL << max_addr_bits) - 1;
130
+ }
62
+ }
131
+
63
+
132
+ alignment_mask = start ? (start & -start) - 1 : max_mask;
64
+ object_initialize_child(OBJECT(mms), "watchdog", &mms->watchdog,
133
+ alignment_mask = MIN(alignment_mask, max_mask);
65
+ TYPE_CMSDK_APB_WATCHDOG);
134
+ size_mask = MIN(addr_mask, max_mask);
66
+ qdev_connect_clock_in(DEVICE(&mms->watchdog), "WDOGCLK", mms->clk);
67
+ sysbus_realize(SYS_BUS_DEVICE(&mms->watchdog), &error_fatal);
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);
135
+
71
+
136
+ if (alignment_mask <= size_mask) {
72
+ object_initialize_child(OBJECT(mms), "dualtimer", &mms->dualtimer,
137
+ /* Increase the alignment of start */
73
+ TYPE_CMSDK_APB_DUALTIMER);
138
+ return alignment_mask;
74
+ qdev_connect_clock_in(DEVICE(&mms->dualtimer), "TIMCLK", mms->clk);
139
+ } else {
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->dualtimer), &error_fatal);
140
+ /* Find the largest page mask from size */
76
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->dualtimer), 0,
141
+ if (addr_mask == UINT64_MAX) {
77
+ qdev_get_gpio_in(gicdev, 3));
142
+ return UINT64_MAX;
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"));
143
+ }
102
+ }
144
+ return (1ULL << (63 - clz64(addr_mask + 1))) - 1;
145
+ }
103
+ }
146
+}
147
+
104
+
105
mms->bootinfo.ram_size = machine->ram_size;
106
mms->bootinfo.board_id = -1;
107
mms->bootinfo.loader_start = mmc->loader_start;
148
--
108
--
149
2.20.1
109
2.34.1
150
110
151
111
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Convert all sid printouts to sid=0x%x.
4
5
Signed-off-by: Eric Auger <eric.auger@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Message-id: 20210309102742.30442-8-eric.auger@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/trace-events | 24 ++++++++++++------------
11
1 file changed, 12 insertions(+), 12 deletions(-)
12
13
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/trace-events
16
+++ b/hw/arm/trace-events
17
@@ -XXX,XX +XXX,XX @@ smmuv3_cmdq_opcode(const char *opcode) "<--- %s"
18
smmuv3_cmdq_consume_out(uint32_t prod, uint32_t cons, uint8_t prod_wrap, uint8_t cons_wrap) "prod:%d, cons:%d, prod_wrap:%d, cons_wrap:%d "
19
smmuv3_cmdq_consume_error(const char *cmd_name, uint8_t cmd_error) "Error on %s command execution: %d"
20
smmuv3_write_mmio(uint64_t addr, uint64_t val, unsigned size, uint32_t r) "addr: 0x%"PRIx64" val:0x%"PRIx64" size: 0x%x(%d)"
21
-smmuv3_record_event(const char *type, uint32_t sid) "%s sid=%d"
22
-smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "SID:0x%x features:0x%x, sid_split:0x%x"
23
+smmuv3_record_event(const char *type, uint32_t sid) "%s sid=0x%x"
24
+smmuv3_find_ste(uint16_t sid, uint32_t features, uint16_t sid_split) "sid=0x%x features:0x%x, sid_split:0x%x"
25
smmuv3_find_ste_2lvl(uint64_t strtab_base, uint64_t l1ptr, int l1_ste_offset, uint64_t l2ptr, int l2_ste_offset, int max_l2_ste) "strtab_base:0x%"PRIx64" l1ptr:0x%"PRIx64" l1_off:0x%x, l2ptr:0x%"PRIx64" l2_off:0x%x max_l2_ste:%d"
26
smmuv3_get_ste(uint64_t addr) "STE addr: 0x%"PRIx64
27
-smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
28
-smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d STE bypass iova:0x%"PRIx64" is_write=%d"
29
-smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=%d abort on iova:0x%"PRIx64" is_write=%d"
30
-smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=%d iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
31
+smmuv3_translate_disable(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x bypass (smmu disabled) iova:0x%"PRIx64" is_write=%d"
32
+smmuv3_translate_bypass(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x STE bypass iova:0x%"PRIx64" is_write=%d"
33
+smmuv3_translate_abort(const char *n, uint16_t sid, uint64_t addr, bool is_write) "%s sid=0x%x abort on iova:0x%"PRIx64" is_write=%d"
34
+smmuv3_translate_success(const char *n, uint16_t sid, uint64_t iova, uint64_t translated, int perm) "%s sid=0x%x iova=0x%"PRIx64" translated=0x%"PRIx64" perm=0x%x"
35
smmuv3_get_cd(uint64_t addr) "CD addr: 0x%"PRIx64
36
smmuv3_decode_cd(uint32_t oas) "oas=%d"
37
smmuv3_decode_cd_tt(int i, uint32_t tsz, uint64_t ttb, uint32_t granule_sz, bool had) "TT[%d]:tsz:%d ttb:0x%"PRIx64" granule_sz:%d had:%d"
38
-smmuv3_cmdq_cfgi_ste(int streamid) "streamid =%d"
39
+smmuv3_cmdq_cfgi_ste(int streamid) "streamid= 0x%x"
40
smmuv3_cmdq_cfgi_ste_range(int start, int end) "start=0x%x - end=0x%x"
41
-smmuv3_cmdq_cfgi_cd(uint32_t sid) "streamid = %d"
42
-smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid %d (hits=%d, misses=%d, hit rate=%d)"
43
-smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid %d (hits=%d, misses=%d, hit rate=%d)"
44
-smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid =%d asid =%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
45
+smmuv3_cmdq_cfgi_cd(uint32_t sid) "sid=0x%x"
46
+smmuv3_config_cache_hit(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache HIT for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
47
+smmuv3_config_cache_miss(uint32_t sid, uint32_t hits, uint32_t misses, uint32_t perc) "Config cache MISS for sid=0x%x (hits=%d, misses=%d, hit rate=%d)"
48
+smmuv3_s1_range_inval(int vmid, int asid, uint64_t addr, uint8_t tg, uint64_t num_pages, uint8_t ttl, bool leaf) "vmid=%d asid=%d addr=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64" ttl=%d leaf=%d"
49
smmuv3_cmdq_tlbi_nh(void) ""
50
smmuv3_cmdq_tlbi_nh_asid(uint16_t asid) "asid=%d"
51
-smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid %d"
52
+smmuv3_config_cache_inv(uint32_t sid) "Config cache INV for sid=0x%x"
53
smmuv3_notify_flag_add(const char *iommu) "ADD SMMUNotifier node for iommu mr=%s"
54
smmuv3_notify_flag_del(const char *iommu) "DEL SMMUNotifier node for iommu mr=%s"
55
smmuv3_inv_notifiers_iova(const char *name, uint16_t asid, uint64_t iova, uint8_t tg, uint64_t num_pages) "iommu mr=%s asid=%d iova=0x%"PRIx64" tg=%d num_pages=0x%"PRIx64
56
--
57
2.20.1
58
59
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Missed out on compressing the second half of a predicate
4
with length vl % 512 > 256.
5
6
Adjust all of the x + (y << s) to x | (y << s) as a
7
general style fix. Drop the extract64 because the input
8
uint64_t are known to be already zero-extended from the
9
current size of the predicate.
10
11
Reported-by: Laurent Desnogues <laurent.desnogues@gmail.com>
12
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20210309155305.11301-2-richard.henderson@linaro.org
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
target/arm/sve_helper.c | 30 +++++++++++++++++++++---------
18
1 file changed, 21 insertions(+), 9 deletions(-)
19
20
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/sve_helper.c
23
+++ b/target/arm/sve_helper.c
24
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
25
if (oprsz <= 8) {
26
l = compress_bits(n[0] >> odd, esz);
27
h = compress_bits(m[0] >> odd, esz);
28
- d[0] = extract64(l + (h << (4 * oprsz)), 0, 8 * oprsz);
29
+ d[0] = l | (h << (4 * oprsz));
30
} else {
31
ARMPredicateReg tmp_m;
32
intptr_t oprsz_16 = oprsz / 16;
33
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
34
h = n[2 * i + 1];
35
l = compress_bits(l >> odd, esz);
36
h = compress_bits(h >> odd, esz);
37
- d[i] = l + (h << 32);
38
+ d[i] = l | (h << 32);
39
}
40
41
- /* For VL which is not a power of 2, the results from M do not
42
- align nicely with the uint64_t for D. Put the aligned results
43
- from M into TMP_M and then copy it into place afterward. */
44
+ /*
45
+ * For VL which is not a multiple of 512, the results from M do not
46
+ * align nicely with the uint64_t for D. Put the aligned results
47
+ * from M into TMP_M and then copy it into place afterward.
48
+ */
49
if (oprsz & 15) {
50
- d[i] = compress_bits(n[2 * i] >> odd, esz);
51
+ int final_shift = (oprsz & 15) * 2;
52
+
53
+ l = n[2 * i + 0];
54
+ h = n[2 * i + 1];
55
+ l = compress_bits(l >> odd, esz);
56
+ h = compress_bits(h >> odd, esz);
57
+ d[i] = l | (h << final_shift);
58
59
for (i = 0; i < oprsz_16; i++) {
60
l = m[2 * i + 0];
61
h = m[2 * i + 1];
62
l = compress_bits(l >> odd, esz);
63
h = compress_bits(h >> odd, esz);
64
- tmp_m.p[i] = l + (h << 32);
65
+ tmp_m.p[i] = l | (h << 32);
66
}
67
- tmp_m.p[i] = compress_bits(m[2 * i] >> odd, esz);
68
+ l = m[2 * i + 0];
69
+ h = m[2 * i + 1];
70
+ l = compress_bits(l >> odd, esz);
71
+ h = compress_bits(h >> odd, esz);
72
+ tmp_m.p[i] = l | (h << final_shift);
73
74
swap_memmove(vd + oprsz / 2, &tmp_m, oprsz / 2);
75
} else {
76
@@ -XXX,XX +XXX,XX @@ void HELPER(sve_uzp_p)(void *vd, void *vn, void *vm, uint32_t pred_desc)
77
h = m[2 * i + 1];
78
l = compress_bits(l >> odd, esz);
79
h = compress_bits(h >> odd, esz);
80
- d[oprsz_16 + i] = l + (h << 32);
81
+ d[oprsz_16 + i] = l | (h << 32);
82
}
83
}
84
}
85
--
86
2.20.1
87
88
diff view generated by jsdifflib
Deleted patch
1
From: Niek Linnenbank <nieklinnenbank@gmail.com>
2
1
3
The image for Armbian 19.11.3 bionic has been removed from the armbian server.
4
Without the image as input the test arm_orangepi_bionic_19_11 cannot run.
5
6
This commit removes the test completely and merges the code of the generic function
7
do_test_arm_orangepi_uboot_armbian back with the 20.08 test.
8
9
Signed-off-by: Niek Linnenbank <nieklinnenbank@gmail.com>
10
Reviewed-by: Willian Rampazzo <willianr@redhat.com>
11
Message-id: 20210310195820.21950-3-nieklinnenbank@gmail.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
14
tests/acceptance/boot_linux_console.py | 72 ++++++++------------------
15
1 file changed, 23 insertions(+), 49 deletions(-)
16
17
diff --git a/tests/acceptance/boot_linux_console.py b/tests/acceptance/boot_linux_console.py
18
index XXXXXXX..XXXXXXX 100644
19
--- a/tests/acceptance/boot_linux_console.py
20
+++ b/tests/acceptance/boot_linux_console.py
21
@@ -XXX,XX +XXX,XX @@ def test_arm_orangepi_sd(self):
22
# Wait for VM to shut down gracefully
23
self.vm.wait()
24
25
- def do_test_arm_orangepi_uboot_armbian(self, image_path):
26
+ @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
27
+ 'Test artifacts fetched from unreliable apt.armbian.com')
28
+ @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
29
+ def test_arm_orangepi_bionic_20_08(self):
30
+ """
31
+ :avocado: tags=arch:arm
32
+ :avocado: tags=machine:orangepi-pc
33
+ :avocado: tags=device:sd
34
+ """
35
+
36
+ # This test download a 275 MiB compressed image and expand it
37
+ # to 1036 MiB, but the underlying filesystem is 1552 MiB...
38
+ # As we expand it to 2 GiB we are safe.
39
+
40
+ image_url = ('https://dl.armbian.com/orangepipc/archive/'
41
+ 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
42
+ image_hash = ('b4d6775f5673486329e45a0586bf06b6'
43
+ 'dbe792199fd182ac6b9c7bb6c7d3e6dd')
44
+ image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
45
+ algorithm='sha256')
46
+ image_path = archive.extract(image_path_xz, self.workdir)
47
+ image_pow2ceil_expand(image_path)
48
+
49
self.vm.set_console()
50
self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
51
'-nic', 'user',
52
@@ -XXX,XX +XXX,XX @@ def do_test_arm_orangepi_uboot_armbian(self, image_path):
53
'to <orangepipc>')
54
self.wait_for_console_pattern('Starting Load Kernel Modules...')
55
56
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
57
- 'Test artifacts fetched from unreliable apt.armbian.com')
58
- @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
59
- @skipUnless(P7ZIP_AVAILABLE, '7z not installed')
60
- def test_arm_orangepi_bionic_19_11(self):
61
- """
62
- :avocado: tags=arch:arm
63
- :avocado: tags=machine:orangepi-pc
64
- :avocado: tags=device:sd
65
- """
66
-
67
- # This test download a 196MB compressed image and expand it to 1GB
68
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
69
- 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.7z')
70
- image_hash = '196a8ffb72b0123d92cea4a070894813d305c71e'
71
- image_path_7z = self.fetch_asset(image_url, asset_hash=image_hash)
72
- image_name = 'Armbian_19.11.3_Orangepipc_bionic_current_5.3.9.img'
73
- image_path = os.path.join(self.workdir, image_name)
74
- process.run("7z e -o%s %s" % (self.workdir, image_path_7z))
75
- image_pow2ceil_expand(image_path)
76
-
77
- self.do_test_arm_orangepi_uboot_armbian(image_path)
78
-
79
- @skipUnless(os.getenv('ARMBIAN_ARTIFACTS_CACHED'),
80
- 'Test artifacts fetched from unreliable apt.armbian.com')
81
- @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
82
- def test_arm_orangepi_bionic_20_08(self):
83
- """
84
- :avocado: tags=arch:arm
85
- :avocado: tags=machine:orangepi-pc
86
- :avocado: tags=device:sd
87
- """
88
-
89
- # This test download a 275 MiB compressed image and expand it
90
- # to 1036 MiB, but the underlying filesystem is 1552 MiB...
91
- # As we expand it to 2 GiB we are safe.
92
-
93
- image_url = ('https://dl.armbian.com/orangepipc/archive/'
94
- 'Armbian_20.08.1_Orangepipc_bionic_current_5.8.5.img.xz')
95
- image_hash = ('b4d6775f5673486329e45a0586bf06b6'
96
- 'dbe792199fd182ac6b9c7bb6c7d3e6dd')
97
- image_path_xz = self.fetch_asset(image_url, asset_hash=image_hash,
98
- algorithm='sha256')
99
- image_path = archive.extract(image_path_xz, self.workdir)
100
- image_pow2ceil_expand(image_path)
101
-
102
- self.do_test_arm_orangepi_uboot_armbian(image_path)
103
-
104
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
105
def test_arm_orangepi_uboot_netbsd9(self):
106
"""
107
--
108
2.20.1
109
110
diff view generated by jsdifflib
1
For a long time now the UI layer has guaranteed that the console
1
Add the remaining devices (or unimplemented-device stubs) for
2
surface is always 32 bits per pixel. Remove the legacy dead
2
this board: SPI controllers, SCC, FPGAIO, I2S, RTC, the
3
code from the pl110 display device which was handling the
3
QSPI write-config block, and ethernet.
4
possibility that the console surface was some other format.
5
4
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20210211141515.8755-2-peter.maydell@linaro.org
7
Message-id: 20240206132931.38376-13-peter.maydell@linaro.org
9
---
8
---
10
hw/display/pl110.c | 53 +++++++---------------------------------------
9
hw/arm/mps3r.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
11
1 file changed, 8 insertions(+), 45 deletions(-)
10
1 file changed, 74 insertions(+)
12
11
13
diff --git a/hw/display/pl110.c b/hw/display/pl110.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/hw/display/pl110.c
14
--- a/hw/arm/mps3r.c
16
+++ b/hw/display/pl110.c
15
+++ b/hw/arm/mps3r.c
17
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
16
@@ -XXX,XX +XXX,XX @@
18
pl111_id
17
#include "hw/char/cmsdk-apb-uart.h"
18
#include "hw/i2c/arm_sbcon_i2c.h"
19
#include "hw/intc/arm_gicv3.h"
20
+#include "hw/misc/mps2-scc.h"
21
+#include "hw/misc/mps2-fpgaio.h"
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;
19
};
39
};
20
40
21
-#define BITS 8
41
@@ -XXX,XX +XXX,XX @@ static const RAMInfo an536_raminfo[] = {
22
-#include "pl110_template.h"
42
}
23
-#define BITS 15
43
};
24
-#include "pl110_template.h"
44
25
-#define BITS 16
45
+static const int an536_oscclk[] = {
26
-#include "pl110_template.h"
46
+ 24000000, /* 24MHz reference for RTC and timers */
27
-#define BITS 24
47
+ 50000000, /* 50MHz ACLK */
28
-#include "pl110_template.h"
48
+ 50000000, /* 50MHz MCLK */
29
#define BITS 32
49
+ 50000000, /* 50MHz GPUCLK */
30
#include "pl110_template.h"
50
+ 24576000, /* 24.576MHz AUDCLK */
31
51
+ 23750000, /* 23.75MHz HDLCDCLK */
32
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
52
+ 100000000, /* 100MHz DDR4_REF_CLK */
33
PL110State *s = (PL110State *)opaque;
53
+};
34
SysBusDevice *sbd;
54
+
35
DisplaySurface *surface = qemu_console_surface(s->con);
55
static MemoryRegion *mr_for_raminfo(MPS3RMachineState *mms,
36
- drawfn* fntable;
56
const RAMInfo *raminfo)
37
drawfn fn;
57
{
38
- int dest_width;
58
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
39
int src_width;
59
MPS3RMachineClass *mmc = MPS3R_MACHINE_GET_CLASS(mms);
40
int bpp_offset;
60
MemoryRegion *sysmem = get_system_memory();
41
int first;
61
DeviceState *gicdev;
42
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
62
+ QList *oscclk;
43
63
44
sbd = SYS_BUS_DEVICE(s);
64
mms->clk = clock_new(OBJECT(machine), "CLK");
45
65
clock_set_hz(mms->clk, CLK_FRQ);
46
- switch (surface_bits_per_pixel(surface)) {
66
@@ -XXX,XX +XXX,XX @@ static void mps3r_common_init(MachineState *machine)
47
- case 0:
48
- return;
49
- case 8:
50
- fntable = pl110_draw_fn_8;
51
- dest_width = 1;
52
- break;
53
- case 15:
54
- fntable = pl110_draw_fn_15;
55
- dest_width = 2;
56
- break;
57
- case 16:
58
- fntable = pl110_draw_fn_16;
59
- dest_width = 2;
60
- break;
61
- case 24:
62
- fntable = pl110_draw_fn_24;
63
- dest_width = 3;
64
- break;
65
- case 32:
66
- fntable = pl110_draw_fn_32;
67
- dest_width = 4;
68
- break;
69
- default:
70
- fprintf(stderr, "pl110: Bad color depth\n");
71
- exit(1);
72
- }
73
if (s->cr & PL110_CR_BGR)
74
bpp_offset = 0;
75
else
76
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
77
}
67
}
78
}
68
}
79
69
80
- if (s->cr & PL110_CR_BEBO)
70
+ for (int i = 0; i < ARRAY_SIZE(mms->spi); i++) {
81
- fn = fntable[s->bpp + 8 + bpp_offset];
71
+ g_autofree char *s = g_strdup_printf("spi%d", i);
82
- else if (s->cr & PL110_CR_BEPO)
72
+ hwaddr baseaddr = 0xe0104000 + i * 0x1000;
83
- fn = fntable[s->bpp + 16 + bpp_offset];
73
+
84
- else
74
+ object_initialize_child(OBJECT(mms), s, &mms->spi[i], TYPE_PL022);
85
- fn = fntable[s->bpp + bpp_offset];
75
+ sysbus_realize(SYS_BUS_DEVICE(&mms->spi[i]), &error_fatal);
86
+ if (s->cr & PL110_CR_BEBO) {
76
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->spi[i]), 0, baseaddr);
87
+ fn = pl110_draw_fn_32[s->bpp + 8 + bpp_offset];
77
+ sysbus_connect_irq(SYS_BUS_DEVICE(&mms->spi[i]), 0,
88
+ } else if (s->cr & PL110_CR_BEPO) {
78
+ qdev_get_gpio_in(gicdev, 22 + i));
89
+ fn = pl110_draw_fn_32[s->bpp + 16 + bpp_offset];
90
+ } else {
91
+ fn = pl110_draw_fn_32[s->bpp + bpp_offset];
92
+ }
79
+ }
93
80
+
94
src_width = s->cols;
81
+ object_initialize_child(OBJECT(mms), "scc", &mms->scc, TYPE_MPS2_SCC);
95
switch (s->bpp) {
82
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg0", 0);
96
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
83
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-cfg4", 0x2);
97
src_width <<= 2;
84
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-aid", 0x00200008);
98
break;
85
+ qdev_prop_set_uint32(DEVICE(&mms->scc), "scc-id", 0x41055360);
99
}
86
+ oscclk = qlist_new();
100
- dest_width *= s->cols;
87
+ for (int i = 0; i < ARRAY_SIZE(an536_oscclk); i++) {
101
first = 0;
88
+ qlist_append_int(oscclk, an536_oscclk[i]);
102
if (s->invalidate) {
89
+ }
103
framebuffer_update_memory_section(&s->fbsection,
90
+ qdev_prop_set_array(DEVICE(&mms->scc), "oscclk", oscclk);
104
@@ -XXX,XX +XXX,XX @@ static void pl110_update_display(void *opaque)
91
+ sysbus_realize(SYS_BUS_DEVICE(&mms->scc), &error_fatal);
105
92
+ sysbus_mmio_map(SYS_BUS_DEVICE(&mms->scc), 0, 0xe0200000);
106
framebuffer_update_display(surface, &s->fbsection,
93
+
107
s->cols, s->rows,
94
+ create_unimplemented_device("i2s-audio", 0xe0201000, 0x1000);
108
- src_width, dest_width, 0,
95
+
109
+ src_width, s->cols * 4, 0,
96
+ object_initialize_child(OBJECT(mms), "fpgaio", &mms->fpgaio,
110
s->invalidate,
97
+ TYPE_MPS2_FPGAIO);
111
fn, s->palette,
98
+ qdev_prop_set_uint32(DEVICE(&mms->fpgaio), "prescale-clk", an536_oscclk[1]);
112
&first, &last);
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;
113
--
126
--
114
2.20.1
127
2.34.1
115
128
116
129
diff view generated by jsdifflib
1
The pl110_template.h header has a doubly-nested multiple-include pattern:
1
Add documentation for the mps3-an536 board type.
2
* pl110.c includes it once for each host bit depth (now always 32)
3
* every time it is included, it includes itself 6 times, to account
4
for multiple guest device pixel and byte orders
5
6
Now we only have to deal with 32-bit host bit depths, we can move the
7
code corresponding to the outer layer of this double-nesting to be
8
directly in pl110.c and reduce the template header to a single layer
9
of nesting.
10
2
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Message-id: 20210211141515.8755-3-peter.maydell@linaro.org
5
Message-id: 20240206132931.38376-14-peter.maydell@linaro.org
14
---
6
---
15
hw/display/pl110_template.h | 100 +-----------------------------------
7
docs/system/arm/mps2.rst | 37 ++++++++++++++++++++++++++++++++++---
16
hw/display/pl110.c | 79 ++++++++++++++++++++++++++++
8
1 file changed, 34 insertions(+), 3 deletions(-)
17
2 files changed, 80 insertions(+), 99 deletions(-)
18
9
19
diff --git a/hw/display/pl110_template.h b/hw/display/pl110_template.h
10
diff --git a/docs/system/arm/mps2.rst b/docs/system/arm/mps2.rst
20
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/display/pl110_template.h
12
--- a/docs/system/arm/mps2.rst
22
+++ b/hw/display/pl110_template.h
13
+++ b/docs/system/arm/mps2.rst
23
@@ -XXX,XX +XXX,XX @@
14
@@ -XXX,XX +XXX,XX @@
24
*/
15
-Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an547``)
25
16
-=========================================================================================================================================================
26
#ifndef ORDER
17
+Arm MPS2 and MPS3 boards (``mps2-an385``, ``mps2-an386``, ``mps2-an500``, ``mps2-an505``, ``mps2-an511``, ``mps2-an521``, ``mps3-an524``, ``mps3-an536``, ``mps3-an547``)
27
-
18
+=========================================================================================================================================================================
28
-#if BITS == 8
19
29
-#define COPY_PIXEL(to, from) *(to++) = from
20
-These board models all use Arm M-profile CPUs.
30
-#elif BITS == 15 || BITS == 16
21
+These board models use Arm M-profile or R-profile CPUs.
31
-#define COPY_PIXEL(to, from) do { *(uint16_t *)to = from; to += 2; } while (0)
22
32
-#elif BITS == 24
23
The Arm MPS2, MPS2+ and MPS3 dev boards are FPGA based (the 2+ has a
33
-#define COPY_PIXEL(to, from) \
24
bigger FPGA but is otherwise the same as the 2; the 3 has a bigger
34
- do { \
25
@@ -XXX,XX +XXX,XX @@ FPGA image.
35
- *(to++) = from; \
26
36
- *(to++) = (from) >> 8; \
27
QEMU models the following FPGA images:
37
- *(to++) = (from) >> 16; \
28
38
- } while (0)
29
+FPGA images using M-profile CPUs:
39
-#elif BITS == 32
40
-#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
41
-#else
42
-#error unknown bit depth
43
+#error "pl110_template.h is only for inclusion by pl110.c"
44
#endif
45
46
-#undef RGB
47
-#define BORDER bgr
48
-#define ORDER 0
49
-#include "pl110_template.h"
50
-#define ORDER 1
51
-#include "pl110_template.h"
52
-#define ORDER 2
53
-#include "pl110_template.h"
54
-#undef BORDER
55
-#define RGB
56
-#define BORDER rgb
57
-#define ORDER 0
58
-#include "pl110_template.h"
59
-#define ORDER 1
60
-#include "pl110_template.h"
61
-#define ORDER 2
62
-#include "pl110_template.h"
63
-#undef BORDER
64
-
65
-static drawfn glue(pl110_draw_fn_,BITS)[48] =
66
-{
67
- glue(pl110_draw_line1_lblp_bgr,BITS),
68
- glue(pl110_draw_line2_lblp_bgr,BITS),
69
- glue(pl110_draw_line4_lblp_bgr,BITS),
70
- glue(pl110_draw_line8_lblp_bgr,BITS),
71
- glue(pl110_draw_line16_555_lblp_bgr,BITS),
72
- glue(pl110_draw_line32_lblp_bgr,BITS),
73
- glue(pl110_draw_line16_lblp_bgr,BITS),
74
- glue(pl110_draw_line12_lblp_bgr,BITS),
75
-
76
- glue(pl110_draw_line1_bbbp_bgr,BITS),
77
- glue(pl110_draw_line2_bbbp_bgr,BITS),
78
- glue(pl110_draw_line4_bbbp_bgr,BITS),
79
- glue(pl110_draw_line8_bbbp_bgr,BITS),
80
- glue(pl110_draw_line16_555_bbbp_bgr,BITS),
81
- glue(pl110_draw_line32_bbbp_bgr,BITS),
82
- glue(pl110_draw_line16_bbbp_bgr,BITS),
83
- glue(pl110_draw_line12_bbbp_bgr,BITS),
84
-
85
- glue(pl110_draw_line1_lbbp_bgr,BITS),
86
- glue(pl110_draw_line2_lbbp_bgr,BITS),
87
- glue(pl110_draw_line4_lbbp_bgr,BITS),
88
- glue(pl110_draw_line8_lbbp_bgr,BITS),
89
- glue(pl110_draw_line16_555_lbbp_bgr,BITS),
90
- glue(pl110_draw_line32_lbbp_bgr,BITS),
91
- glue(pl110_draw_line16_lbbp_bgr,BITS),
92
- glue(pl110_draw_line12_lbbp_bgr,BITS),
93
-
94
- glue(pl110_draw_line1_lblp_rgb,BITS),
95
- glue(pl110_draw_line2_lblp_rgb,BITS),
96
- glue(pl110_draw_line4_lblp_rgb,BITS),
97
- glue(pl110_draw_line8_lblp_rgb,BITS),
98
- glue(pl110_draw_line16_555_lblp_rgb,BITS),
99
- glue(pl110_draw_line32_lblp_rgb,BITS),
100
- glue(pl110_draw_line16_lblp_rgb,BITS),
101
- glue(pl110_draw_line12_lblp_rgb,BITS),
102
-
103
- glue(pl110_draw_line1_bbbp_rgb,BITS),
104
- glue(pl110_draw_line2_bbbp_rgb,BITS),
105
- glue(pl110_draw_line4_bbbp_rgb,BITS),
106
- glue(pl110_draw_line8_bbbp_rgb,BITS),
107
- glue(pl110_draw_line16_555_bbbp_rgb,BITS),
108
- glue(pl110_draw_line32_bbbp_rgb,BITS),
109
- glue(pl110_draw_line16_bbbp_rgb,BITS),
110
- glue(pl110_draw_line12_bbbp_rgb,BITS),
111
-
112
- glue(pl110_draw_line1_lbbp_rgb,BITS),
113
- glue(pl110_draw_line2_lbbp_rgb,BITS),
114
- glue(pl110_draw_line4_lbbp_rgb,BITS),
115
- glue(pl110_draw_line8_lbbp_rgb,BITS),
116
- glue(pl110_draw_line16_555_lbbp_rgb,BITS),
117
- glue(pl110_draw_line32_lbbp_rgb,BITS),
118
- glue(pl110_draw_line16_lbbp_rgb,BITS),
119
- glue(pl110_draw_line12_lbbp_rgb,BITS),
120
-};
121
-
122
-#undef BITS
123
-#undef COPY_PIXEL
124
-
125
-#else
126
-
127
#if ORDER == 0
128
#define NAME glue(glue(lblp_, BORDER), BITS)
129
#ifdef HOST_WORDS_BIGENDIAN
130
@@ -XXX,XX +XXX,XX @@ static void glue(pl110_draw_line12_,NAME)(void *opaque, uint8_t *d, const uint8_
131
#undef NAME
132
#undef SWAP_WORDS
133
#undef ORDER
134
-
135
-#endif
136
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
137
index XXXXXXX..XXXXXXX 100644
138
--- a/hw/display/pl110.c
139
+++ b/hw/display/pl110.c
140
@@ -XXX,XX +XXX,XX @@ static const unsigned char *idregs[] = {
141
};
142
143
#define BITS 32
144
+#define COPY_PIXEL(to, from) do { *(uint32_t *)to = from; to += 4; } while (0)
145
+
30
+
146
+#undef RGB
31
``mps2-an385``
147
+#define BORDER bgr
32
Cortex-M3 as documented in Arm Application Note AN385
148
+#define ORDER 0
33
``mps2-an386``
149
#include "pl110_template.h"
34
@@ -XXX,XX +XXX,XX @@ QEMU models the following FPGA images:
150
+#define ORDER 1
35
``mps3-an547``
151
+#include "pl110_template.h"
36
Cortex-M55 on an MPS3, as documented in Arm Application Note AN547
152
+#define ORDER 2
37
153
+#include "pl110_template.h"
38
+FPGA images using R-profile CPUs:
154
+#undef BORDER
155
+#define RGB
156
+#define BORDER rgb
157
+#define ORDER 0
158
+#include "pl110_template.h"
159
+#define ORDER 1
160
+#include "pl110_template.h"
161
+#define ORDER 2
162
+#include "pl110_template.h"
163
+#undef BORDER
164
+
39
+
165
+static drawfn pl110_draw_fn_32[48] = {
40
+``mps3-an536``
166
+ pl110_draw_line1_lblp_bgr32,
41
+ Dual Cortex-R52 on an MPS3, as documented in Arm Application Note AN536
167
+ pl110_draw_line2_lblp_bgr32,
168
+ pl110_draw_line4_lblp_bgr32,
169
+ pl110_draw_line8_lblp_bgr32,
170
+ pl110_draw_line16_555_lblp_bgr32,
171
+ pl110_draw_line32_lblp_bgr32,
172
+ pl110_draw_line16_lblp_bgr32,
173
+ pl110_draw_line12_lblp_bgr32,
174
+
42
+
175
+ pl110_draw_line1_bbbp_bgr32,
43
Differences between QEMU and real hardware:
176
+ pl110_draw_line2_bbbp_bgr32,
44
177
+ pl110_draw_line4_bbbp_bgr32,
45
- AN385/AN386 remapping of low 16K of memory to either ZBT SSRAM1 or to
178
+ pl110_draw_line8_bbbp_bgr32,
46
@@ -XXX,XX +XXX,XX @@ Differences between QEMU and real hardware:
179
+ pl110_draw_line16_555_bbbp_bgr32,
47
flash, but only as simple ROM, so attempting to rewrite the flash
180
+ pl110_draw_line32_bbbp_bgr32,
48
from the guest will fail
181
+ pl110_draw_line16_bbbp_bgr32,
49
- QEMU does not model the USB controller in MPS3 boards
182
+ pl110_draw_line12_bbbp_bgr32,
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.
183
+
64
+
184
+ pl110_draw_line1_lbbp_bgr32,
65
+Note that for the AN536 the first UART is accessible only by
185
+ pl110_draw_line2_lbbp_bgr32,
66
+CPU0, and the second UART is accessible only by CPU1. The
186
+ pl110_draw_line4_lbbp_bgr32,
67
+first UART accessible shared between both CPUs is the third
187
+ pl110_draw_line8_lbbp_bgr32,
68
+UART. Guest software might therefore be built to use either
188
+ pl110_draw_line16_555_lbbp_bgr32,
69
+the first UART or the third UART; if you don't see any output
189
+ pl110_draw_line32_lbbp_bgr32,
70
+from the UART you are looking at, try one of the others.
190
+ pl110_draw_line16_lbbp_bgr32,
71
+(Even if the AN536 machine is started with a single CPU and so
191
+ pl110_draw_line12_lbbp_bgr32,
72
+no "CPU1-only UART", the UART numbering remains the same,
192
+
73
+with the third UART being the first of the shared ones.)
193
+ pl110_draw_line1_lblp_rgb32,
74
194
+ pl110_draw_line2_lblp_rgb32,
75
Machine-specific options
195
+ pl110_draw_line4_lblp_rgb32,
76
""""""""""""""""""""""""
196
+ pl110_draw_line8_lblp_rgb32,
197
+ pl110_draw_line16_555_lblp_rgb32,
198
+ pl110_draw_line32_lblp_rgb32,
199
+ pl110_draw_line16_lblp_rgb32,
200
+ pl110_draw_line12_lblp_rgb32,
201
+
202
+ pl110_draw_line1_bbbp_rgb32,
203
+ pl110_draw_line2_bbbp_rgb32,
204
+ pl110_draw_line4_bbbp_rgb32,
205
+ pl110_draw_line8_bbbp_rgb32,
206
+ pl110_draw_line16_555_bbbp_rgb32,
207
+ pl110_draw_line32_bbbp_rgb32,
208
+ pl110_draw_line16_bbbp_rgb32,
209
+ pl110_draw_line12_bbbp_rgb32,
210
+
211
+ pl110_draw_line1_lbbp_rgb32,
212
+ pl110_draw_line2_lbbp_rgb32,
213
+ pl110_draw_line4_lbbp_rgb32,
214
+ pl110_draw_line8_lbbp_rgb32,
215
+ pl110_draw_line16_555_lbbp_rgb32,
216
+ pl110_draw_line32_lbbp_rgb32,
217
+ pl110_draw_line16_lbbp_rgb32,
218
+ pl110_draw_line12_lbbp_rgb32,
219
+};
220
+
221
+#undef BITS
222
+#undef COPY_PIXEL
223
+
224
225
static int pl110_enabled(PL110State *s)
226
{
227
--
77
--
228
2.20.1
78
2.34.1
229
79
230
80
diff view generated by jsdifflib