1
Hi; here's the latest target-arm queue. Mostly this is refactoring
1
The following changes since commit 8f6330a807f2642dc2a3cdf33347aa28a4c00a87:
2
and cleanup type patches.
3
2
4
thanks
3
Merge tag 'pull-maintainer-updates-060324-1' of https://gitlab.com/stsquad/qemu into staging (2024-03-06 16:56:20 +0000)
5
-- PMM
6
7
The following changes since commit c60be6e3e38cb36dc66129e757ec4b34152232be:
8
9
Merge tag 'pull-sp-20231025' of https://gitlab.com/rth7680/qemu into staging (2023-10-27 09:43:53 +0900)
10
4
11
are available in the Git repository at:
5
are available in the Git repository at:
12
6
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20231027
7
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20240308
14
8
15
for you to fetch changes up to df93de987f423a0ed918c425f5dbd9a25d3c6229:
9
for you to fetch changes up to bbf6c6dbead82292a20951eb1204442a6b838de9:
16
10
17
hw/net/cadence_gem: enforce 32 bits variable size for CRC (2023-10-27 15:27:06 +0100)
11
target/arm: Move v7m-related code from cpu32.c into a separate file (2024-03-08 14:45:03 +0000)
18
12
19
----------------------------------------------------------------
13
----------------------------------------------------------------
20
target-arm queue:
14
target-arm queue:
21
* Correct minor errors in Cortex-A710 definition
15
* Implement FEAT_ECV
22
* Implement Neoverse N2 CPU model
16
* STM32L4x5: Implement GPIO device
23
* Refactor feature test functions out into separate header
17
* Fix 32-bit SMOPA
24
* Fix syndrome for FGT traps on ERET
18
* Refactor v7m related code from cpu32.c into its own file
25
* Remove 'hw/arm/boot.h' includes from various header files
19
* hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
26
* pxa2xx: Refactoring/cleanup
27
* Avoid using 'first_cpu' when first ARM CPU is reachable
28
* misc/led: LED state is set opposite of what is expected
29
* hw/net/cadence_gen: clean up to use FIELD macros
30
* hw/net/cadence_gem: perform PHY access on write only
31
* hw/net/cadence_gem: enforce 32 bits variable size for CRC
32
20
33
----------------------------------------------------------------
21
----------------------------------------------------------------
34
Glenn Miles (1):
22
Inès Varhol (3):
35
misc/led: LED state is set opposite of what is expected
23
hw/gpio: Implement STM32L4x5 GPIO
36
24
hw/arm: Connect STM32L4x5 GPIO to STM32L4x5 SoC
37
Luc Michel (11):
25
tests/qtest: Add STM32L4x5 GPIO QTest testcase
38
hw/net/cadence_gem: use REG32 macro for register definitions
39
hw/net/cadence_gem: use FIELD for screening registers
40
hw/net/cadence_gem: use FIELD to describe NWCTRL register fields
41
hw/net/cadence_gem: use FIELD to describe NWCFG register fields
42
hw/net/cadence_gem: use FIELD to describe DMACFG register fields
43
hw/net/cadence_gem: use FIELD to describe [TX|RX]STATUS register fields
44
hw/net/cadence_gem: use FIELD to describe IRQ register fields
45
hw/net/cadence_gem: use FIELD to describe DESCONF6 register fields
46
hw/net/cadence_gem: use FIELD to describe PHYMNTNC register fields
47
hw/net/cadence_gem: perform PHY access on write only
48
hw/net/cadence_gem: enforce 32 bits variable size for CRC
49
26
50
Peter Maydell (9):
27
Peter Maydell (9):
51
target/arm: Correct minor errors in Cortex-A710 definition
28
target/arm: Move some register related defines to internals.h
52
target/arm: Implement Neoverse N2 CPU model
29
target/arm: Timer _EL02 registers UNDEF for E2H == 0
53
target/arm: Move feature test functions to their own header
30
target/arm: use FIELD macro for CNTHCTL bit definitions
54
target/arm: Move ID_AA64MMFR1 and ID_AA64MMFR2 tests together
31
target/arm: Don't allow RES0 CNTHCTL_EL2 bits to be written
55
target/arm: Move ID_AA64MMFR0 tests up to before MMFR1 and MMFR2
32
target/arm: Implement new FEAT_ECV trap bits
56
target/arm: Move ID_AA64ISAR* test functions together
33
target/arm: Define CNTPCTSS_EL0 and CNTVCTSS_EL0
57
target/arm: Move ID_AA64PFR* tests together
34
target/arm: Implement FEAT_ECV CNTPOFF_EL2 handling
58
target/arm: Move ID_AA64DFR* feature tests together
35
target/arm: Enable FEAT_ECV for 'max' CPU
59
target/arm: Fix syndrome for FGT traps on ERET
36
hw/rtc/sun4v-rtc: Relicense to GPLv2-or-later
60
37
61
Philippe Mathieu-Daudé (20):
38
Richard Henderson (1):
62
hw/arm/allwinner-a10: Remove 'hw/arm/boot.h' from header
39
target/arm: Fix 32-bit SMOPA
63
hw/arm/allwinner-h3: Remove 'hw/arm/boot.h' from header
64
hw/arm/allwinner-r40: Remove 'hw/arm/boot.h' from header
65
hw/arm/fsl-imx25: Remove 'hw/arm/boot.h' from header
66
hw/arm/fsl-imx31: Remove 'hw/arm/boot.h' from header
67
hw/arm/fsl-imx6: Remove 'hw/arm/boot.h' from header
68
hw/arm/fsl-imx6ul: Remove 'hw/arm/boot.h' from header
69
hw/arm/fsl-imx7: Remove 'hw/arm/boot.h' from header
70
hw/arm/xlnx-versal: Remove 'hw/arm/boot.h' from header
71
hw/arm/xlnx-zynqmp: Remove 'hw/arm/boot.h' from header
72
hw/sd/pxa2xx: Realize sysbus device before accessing it
73
hw/sd/pxa2xx: Do not open-code sysbus_create_simple()
74
hw/pcmcia/pxa2xx: Realize sysbus device before accessing it
75
hw/pcmcia/pxa2xx: Do not open-code sysbus_create_simple()
76
hw/pcmcia/pxa2xx: Inline pxa2xx_pcmcia_init()
77
hw/intc/pxa2xx: Convert to Resettable interface
78
hw/intc/pxa2xx: Pass CPU reference using QOM link property
79
hw/intc/pxa2xx: Factor pxa2xx_pic_realize() out of pxa2xx_pic_init()
80
hw/arm/pxa2xx: Realize PXA2XX_I2C device before accessing it
81
hw/arm: Avoid using 'first_cpu' when first ARM CPU is reachable
82
40
83
docs/system/arm/virt.rst | 1 +
41
Thomas Huth (1):
84
bsd-user/arm/target_arch.h | 1 +
42
target/arm: Move v7m-related code from cpu32.c into a separate file
85
include/hw/arm/allwinner-a10.h | 1 -
86
include/hw/arm/allwinner-h3.h | 1 -
87
include/hw/arm/allwinner-r40.h | 1 -
88
include/hw/arm/fsl-imx25.h | 1 -
89
include/hw/arm/fsl-imx31.h | 1 -
90
include/hw/arm/fsl-imx6.h | 1 -
91
include/hw/arm/fsl-imx6ul.h | 1 -
92
include/hw/arm/fsl-imx7.h | 1 -
93
include/hw/arm/pxa.h | 2 -
94
include/hw/arm/xlnx-versal.h | 1 -
95
include/hw/arm/xlnx-zynqmp.h | 1 -
96
linux-user/aarch64/target_prctl.h | 2 +
97
target/arm/cpu-features.h | 994 ++++++++++++++++++++++++++++++++++++++
98
target/arm/cpu.h | 971 -------------------------------------
99
target/arm/internals.h | 1 +
100
target/arm/tcg/translate.h | 2 +-
101
hw/arm/armv7m.c | 1 +
102
hw/arm/bananapi_m2u.c | 3 +-
103
hw/arm/cubieboard.c | 1 +
104
hw/arm/exynos4_boards.c | 7 +-
105
hw/arm/imx25_pdk.c | 1 +
106
hw/arm/kzm.c | 1 +
107
hw/arm/mcimx6ul-evk.c | 1 +
108
hw/arm/mcimx7d-sabre.c | 1 +
109
hw/arm/orangepi.c | 3 +-
110
hw/arm/pxa2xx.c | 17 +-
111
hw/arm/pxa2xx_pic.c | 38 +-
112
hw/arm/realview.c | 2 +-
113
hw/arm/sabrelite.c | 1 +
114
hw/arm/sbsa-ref.c | 1 +
115
hw/arm/virt.c | 1 +
116
hw/arm/xilinx_zynq.c | 2 +-
117
hw/arm/xlnx-versal-virt.c | 1 +
118
hw/arm/xlnx-zcu102.c | 1 +
119
hw/intc/armv7m_nvic.c | 1 +
120
hw/misc/led.c | 2 +-
121
hw/net/cadence_gem.c | 884 ++++++++++++++++++---------------
122
hw/pcmcia/pxa2xx.c | 15 -
123
hw/sd/pxa2xx_mmci.c | 7 +-
124
linux-user/aarch64/cpu_loop.c | 1 +
125
linux-user/aarch64/signal.c | 1 +
126
linux-user/arm/signal.c | 1 +
127
linux-user/elfload.c | 4 +
128
linux-user/mmap.c | 4 +
129
target/arm/arch_dump.c | 1 +
130
target/arm/cpu.c | 1 +
131
target/arm/cpu64.c | 1 +
132
target/arm/debug_helper.c | 1 +
133
target/arm/gdbstub.c | 1 +
134
target/arm/helper.c | 1 +
135
target/arm/kvm64.c | 1 +
136
target/arm/machine.c | 1 +
137
target/arm/ptw.c | 1 +
138
target/arm/tcg/cpu64.c | 115 ++++-
139
target/arm/tcg/hflags.c | 1 +
140
target/arm/tcg/m_helper.c | 1 +
141
target/arm/tcg/op_helper.c | 1 +
142
target/arm/tcg/pauth_helper.c | 1 +
143
target/arm/tcg/tlb_helper.c | 1 +
144
target/arm/tcg/translate-a64.c | 4 +-
145
target/arm/vfp_helper.c | 1 +
146
63 files changed, 1702 insertions(+), 1419 deletions(-)
147
create mode 100644 target/arm/cpu-features.h
148
43
44
MAINTAINERS | 1 +
45
docs/system/arm/b-l475e-iot01a.rst | 2 +-
46
docs/system/arm/emulation.rst | 1 +
47
include/hw/arm/stm32l4x5_soc.h | 2 +
48
include/hw/gpio/stm32l4x5_gpio.h | 71 +++++
49
include/hw/misc/stm32l4x5_syscfg.h | 3 +-
50
include/hw/rtc/sun4v-rtc.h | 2 +-
51
target/arm/cpu-features.h | 10 +
52
target/arm/cpu.h | 129 +--------
53
target/arm/internals.h | 151 ++++++++++
54
hw/arm/stm32l4x5_soc.c | 71 ++++-
55
hw/gpio/stm32l4x5_gpio.c | 477 ++++++++++++++++++++++++++++++++
56
hw/misc/stm32l4x5_syscfg.c | 1 +
57
hw/rtc/sun4v-rtc.c | 2 +-
58
target/arm/helper.c | 189 ++++++++++++-
59
target/arm/tcg/cpu-v7m.c | 290 +++++++++++++++++++
60
target/arm/tcg/cpu32.c | 261 ------------------
61
target/arm/tcg/cpu64.c | 1 +
62
target/arm/tcg/sme_helper.c | 77 +++---
63
tests/qtest/stm32l4x5_gpio-test.c | 551 +++++++++++++++++++++++++++++++++++++
64
tests/tcg/aarch64/sme-smopa-1.c | 47 ++++
65
tests/tcg/aarch64/sme-smopa-2.c | 54 ++++
66
hw/arm/Kconfig | 3 +-
67
hw/gpio/Kconfig | 3 +
68
hw/gpio/meson.build | 1 +
69
hw/gpio/trace-events | 6 +
70
target/arm/meson.build | 3 +
71
target/arm/tcg/meson.build | 3 +
72
target/arm/trace-events | 1 +
73
tests/qtest/meson.build | 3 +-
74
tests/tcg/aarch64/Makefile.target | 2 +-
75
31 files changed, 1962 insertions(+), 456 deletions(-)
76
create mode 100644 include/hw/gpio/stm32l4x5_gpio.h
77
create mode 100644 hw/gpio/stm32l4x5_gpio.c
78
create mode 100644 target/arm/tcg/cpu-v7m.c
79
create mode 100644 tests/qtest/stm32l4x5_gpio-test.c
80
create mode 100644 tests/tcg/aarch64/sme-smopa-1.c
81
create mode 100644 tests/tcg/aarch64/sme-smopa-2.c
82
diff view generated by jsdifflib
Deleted patch
1
Correct a couple of minor errors in the Cortex-A710 definition:
2
* ID_AA64DFR0_EL1.DebugVer is 9 (indicating Armv8.4 debug architecture)
3
* ID_AA64ISAR1_EL1.APA is 5 (indicating more PAuth support)
4
* there is an IMPDEF CPUCFR_EL1, like that on the Neoverse-N1
5
1
6
Fixes: e3d45c0a89576 ("target/arm: Implement cortex-a710")
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Tested-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20230915185453.1871167-2-peter.maydell@linaro.org
11
---
12
target/arm/tcg/cpu64.c | 11 +++++++++--
13
1 file changed, 9 insertions(+), 2 deletions(-)
14
15
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/tcg/cpu64.c
18
+++ b/target/arm/tcg/cpu64.c
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortex_a710_cp_reginfo[] = {
20
{ .name = "CPUPFR_EL3", .state = ARM_CP_STATE_AA64,
21
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 6,
22
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
23
+ /*
24
+ * Report CPUCFR_EL1.SCU as 1, as we do not implement the DSU
25
+ * (and in particular its system registers).
26
+ */
27
+ { .name = "CPUCFR_EL1", .state = ARM_CP_STATE_AA64,
28
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
29
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 4 },
30
31
/*
32
* Stub RAMINDEX, as we don't actually implement caches, BTB,
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_a710_initfn(Object *obj)
34
cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
35
cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
36
cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
37
- cpu->isar.id_aa64dfr0 = 0x000011f010305611ull;
38
+ cpu->isar.id_aa64dfr0 = 0x000011f010305619ull;
39
cpu->isar.id_aa64dfr1 = 0;
40
cpu->id_aa64afr0 = 0;
41
cpu->id_aa64afr1 = 0;
42
cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */
43
- cpu->isar.id_aa64isar1 = 0x0010111101211032ull;
44
+ cpu->isar.id_aa64isar1 = 0x0010111101211052ull;
45
cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull;
46
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
47
cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull;
48
--
49
2.34.1
50
51
diff view generated by jsdifflib
1
Move all the ID_AA64PFR* feature test functions together.
1
cpu.h has a lot of #defines relating to CPU register fields.
2
Most of these aren't actually used outside target/arm code,
3
so there's no point in cluttering up the cpu.h file with them.
4
Move some easy ones to internals.h.
2
5
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20231024163510.2972081-6-peter.maydell@linaro.org
9
Message-id: 20240301183219.2424889-2-peter.maydell@linaro.org
7
---
10
---
8
target/arm/cpu-features.h | 86 +++++++++++++++++++--------------------
11
target/arm/cpu.h | 128 -----------------------------------------
9
1 file changed, 43 insertions(+), 43 deletions(-)
12
target/arm/internals.h | 128 +++++++++++++++++++++++++++++++++++++++++
13
2 files changed, 128 insertions(+), 128 deletions(-)
10
14
11
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu-features.h
17
--- a/target/arm/cpu.h
14
+++ b/target/arm/cpu-features.h
18
+++ b/target/arm/cpu.h
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMGenericTimer {
16
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
20
uint64_t ctl; /* Timer Control register */
17
}
21
} ARMGenericTimer;
18
22
19
+static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
23
-#define VTCR_NSW (1u << 29)
20
+{
24
-#define VTCR_NSA (1u << 30)
21
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
25
-#define VSTCR_SW VTCR_NSW
22
+}
26
-#define VSTCR_SA VTCR_NSA
23
+
27
-
24
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
28
/* Define a maximum sized vector register.
25
+{
29
* For 32-bit, this is a 128-bit NEON/AdvSIMD register.
26
+ int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
30
* For 64-bit, this is a 2048-bit SVE register.
27
+ if (key >= 2) {
31
@@ -XXX,XX +XXX,XX @@ void pmu_init(ARMCPU *cpu);
28
+ return true; /* FEAT_CSV2_2 */
32
#define SCTLR_SPINTMASK (1ULL << 62) /* FEAT_NMI */
29
+ }
33
#define SCTLR_TIDCP (1ULL << 63) /* FEAT_TIDCP1 */
30
+ if (key == 1) {
34
31
+ key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
35
-/* Bit definitions for CPACR (AArch32 only) */
32
+ return key >= 2; /* FEAT_CSV2_1p2 */
36
-FIELD(CPACR, CP10, 20, 2)
33
+ }
37
-FIELD(CPACR, CP11, 22, 2)
34
+ return false;
38
-FIELD(CPACR, TRCDIS, 28, 1) /* matches CPACR_EL1.TTA */
35
+}
39
-FIELD(CPACR, D32DIS, 30, 1) /* up to v7; RAZ in v8 */
36
+
40
-FIELD(CPACR, ASEDIS, 31, 1)
37
+static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
41
-
38
+{
42
-/* Bit definitions for CPACR_EL1 (AArch64 only) */
39
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
43
-FIELD(CPACR_EL1, ZEN, 16, 2)
40
+}
44
-FIELD(CPACR_EL1, FPEN, 20, 2)
41
+
45
-FIELD(CPACR_EL1, SMEN, 24, 2)
42
+static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
46
-FIELD(CPACR_EL1, TTA, 28, 1) /* matches CPACR.TRCDIS */
43
+{
47
-
44
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
48
-/* Bit definitions for HCPTR (AArch32 only) */
45
+}
49
-FIELD(HCPTR, TCP10, 10, 1)
46
+
50
-FIELD(HCPTR, TCP11, 11, 1)
47
+static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
51
-FIELD(HCPTR, TASE, 15, 1)
48
+{
52
-FIELD(HCPTR, TTA, 20, 1)
49
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
53
-FIELD(HCPTR, TAM, 30, 1) /* matches CPTR_EL2.TAM */
50
+}
54
-FIELD(HCPTR, TCPAC, 31, 1) /* matches CPTR_EL2.TCPAC */
51
+
55
-
52
+static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
56
-/* Bit definitions for CPTR_EL2 (AArch64 only) */
53
+{
57
-FIELD(CPTR_EL2, TZ, 8, 1) /* !E2H */
54
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
58
-FIELD(CPTR_EL2, TFP, 10, 1) /* !E2H, matches HCPTR.TCP10 */
55
+}
59
-FIELD(CPTR_EL2, TSM, 12, 1) /* !E2H */
56
+
60
-FIELD(CPTR_EL2, ZEN, 16, 2) /* E2H */
57
+static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
61
-FIELD(CPTR_EL2, FPEN, 20, 2) /* E2H */
58
+{
62
-FIELD(CPTR_EL2, SMEN, 24, 2) /* E2H */
59
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
63
-FIELD(CPTR_EL2, TTA, 28, 1)
60
+}
64
-FIELD(CPTR_EL2, TAM, 30, 1) /* matches HCPTR.TAM */
61
+
65
-FIELD(CPTR_EL2, TCPAC, 31, 1) /* matches HCPTR.TCPAC */
62
static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
66
-
63
{
67
-/* Bit definitions for CPTR_EL3 (AArch64 only) */
64
return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
68
-FIELD(CPTR_EL3, EZ, 8, 1)
65
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
69
-FIELD(CPTR_EL3, TFP, 10, 1)
66
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
70
-FIELD(CPTR_EL3, ESM, 12, 1)
67
}
71
-FIELD(CPTR_EL3, TTA, 20, 1)
68
72
-FIELD(CPTR_EL3, TAM, 30, 1)
69
-static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
73
-FIELD(CPTR_EL3, TCPAC, 31, 1)
70
-{
74
-
71
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
75
-#define MDCR_MTPME (1U << 28)
72
-}
76
-#define MDCR_TDCC (1U << 27)
73
-
77
-#define MDCR_HLP (1U << 26) /* MDCR_EL2 */
74
-static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
78
-#define MDCR_SCCD (1U << 23) /* MDCR_EL3 */
75
-{
79
-#define MDCR_HCCD (1U << 23) /* MDCR_EL2 */
76
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
80
-#define MDCR_EPMAD (1U << 21)
77
-}
81
-#define MDCR_EDAD (1U << 20)
78
-
82
-#define MDCR_TTRF (1U << 19)
79
-static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
83
-#define MDCR_STE (1U << 18) /* MDCR_EL3 */
80
-{
84
-#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
81
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
85
-#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */
82
-}
86
-#define MDCR_SDD (1U << 16)
83
-
87
-#define MDCR_SPD (3U << 14)
84
-static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
88
-#define MDCR_TDRA (1U << 11)
85
-{
89
-#define MDCR_TDOSA (1U << 10)
86
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
90
-#define MDCR_TDA (1U << 9)
87
-}
91
-#define MDCR_TDE (1U << 8)
88
-
92
-#define MDCR_HPME (1U << 7)
89
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
93
-#define MDCR_TPM (1U << 6)
90
{
94
-#define MDCR_TPMCR (1U << 5)
91
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
95
-#define MDCR_HPMN (0x1fU)
92
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
96
-
93
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
97
-/* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */
94
}
98
-#define SDCR_VALID_MASK (MDCR_MTPME | MDCR_TDCC | MDCR_SCCD | \
95
99
- MDCR_EPMAD | MDCR_EDAD | MDCR_TTRF | \
96
-static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
100
- MDCR_STE | MDCR_SPME | MDCR_SPD)
97
-{
101
-
98
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
102
#define CPSR_M (0x1fU)
99
-}
103
#define CPSR_T (1U << 5)
100
-
104
#define CPSR_F (1U << 6)
101
-static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
105
@@ -XXX,XX +XXX,XX @@ FIELD(CPTR_EL3, TCPAC, 31, 1)
102
-{
106
#define XPSR_NZCV CPSR_NZCV
103
- int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
107
#define XPSR_IT CPSR_IT
104
- if (key >= 2) {
108
105
- return true; /* FEAT_CSV2_2 */
109
-#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
106
- }
110
-#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
107
- if (key == 1) {
111
-#define TTBCR_PD0 (1U << 4)
108
- key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
112
-#define TTBCR_PD1 (1U << 5)
109
- return key >= 2; /* FEAT_CSV2_1p2 */
113
-#define TTBCR_EPD0 (1U << 7)
110
- }
114
-#define TTBCR_IRGN0 (3U << 8)
111
- return false;
115
-#define TTBCR_ORGN0 (3U << 10)
112
-}
116
-#define TTBCR_SH0 (3U << 12)
113
-
117
-#define TTBCR_T1SZ (3U << 16)
114
-static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
118
-#define TTBCR_A1 (1U << 22)
115
-{
119
-#define TTBCR_EPD1 (1U << 23)
116
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
120
-#define TTBCR_IRGN1 (3U << 24)
117
-}
121
-#define TTBCR_ORGN1 (3U << 26)
118
-
122
-#define TTBCR_SH1 (1U << 28)
119
static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
123
-#define TTBCR_EAE (1U << 31)
120
{
124
-
121
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
125
-FIELD(VTCR, T0SZ, 0, 6)
126
-FIELD(VTCR, SL0, 6, 2)
127
-FIELD(VTCR, IRGN0, 8, 2)
128
-FIELD(VTCR, ORGN0, 10, 2)
129
-FIELD(VTCR, SH0, 12, 2)
130
-FIELD(VTCR, TG0, 14, 2)
131
-FIELD(VTCR, PS, 16, 3)
132
-FIELD(VTCR, VS, 19, 1)
133
-FIELD(VTCR, HA, 21, 1)
134
-FIELD(VTCR, HD, 22, 1)
135
-FIELD(VTCR, HWU59, 25, 1)
136
-FIELD(VTCR, HWU60, 26, 1)
137
-FIELD(VTCR, HWU61, 27, 1)
138
-FIELD(VTCR, HWU62, 28, 1)
139
-FIELD(VTCR, NSW, 29, 1)
140
-FIELD(VTCR, NSA, 30, 1)
141
-FIELD(VTCR, DS, 32, 1)
142
-FIELD(VTCR, SL2, 33, 1)
143
-
144
/* Bit definitions for ARMv8 SPSR (PSTATE) format.
145
* Only these are valid when in AArch64 mode; in
146
* AArch32 mode SPSRs are basically CPSR-format.
147
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
148
#define HCR_TWEDEN (1ULL << 59)
149
#define HCR_TWEDEL MAKE_64BIT_MASK(60, 4)
150
151
-#define HCRX_ENAS0 (1ULL << 0)
152
-#define HCRX_ENALS (1ULL << 1)
153
-#define HCRX_ENASR (1ULL << 2)
154
-#define HCRX_FNXS (1ULL << 3)
155
-#define HCRX_FGTNXS (1ULL << 4)
156
-#define HCRX_SMPME (1ULL << 5)
157
-#define HCRX_TALLINT (1ULL << 6)
158
-#define HCRX_VINMI (1ULL << 7)
159
-#define HCRX_VFNMI (1ULL << 8)
160
-#define HCRX_CMOW (1ULL << 9)
161
-#define HCRX_MCE2 (1ULL << 10)
162
-#define HCRX_MSCEN (1ULL << 11)
163
-
164
-#define HPFAR_NS (1ULL << 63)
165
-
166
#define SCR_NS (1ULL << 0)
167
#define SCR_IRQ (1ULL << 1)
168
#define SCR_FIQ (1ULL << 2)
169
@@ -XXX,XX +XXX,XX @@ static inline void xpsr_write(CPUARMState *env, uint32_t val, uint32_t mask)
170
#define SCR_GPF (1ULL << 48)
171
#define SCR_NSE (1ULL << 62)
172
173
-#define HSTR_TTEE (1 << 16)
174
-#define HSTR_TJDBX (1 << 17)
175
-
176
-#define CNTHCTL_CNTVMASK (1 << 18)
177
-#define CNTHCTL_CNTPMASK (1 << 19)
178
-
179
/* Return the current FPSCR value. */
180
uint32_t vfp_get_fpscr(CPUARMState *env);
181
void vfp_set_fpscr(CPUARMState *env, uint32_t val);
182
diff --git a/target/arm/internals.h b/target/arm/internals.h
183
index XXXXXXX..XXXXXXX 100644
184
--- a/target/arm/internals.h
185
+++ b/target/arm/internals.h
186
@@ -XXX,XX +XXX,XX @@ FIELD(DBGWCR, WT, 20, 1)
187
FIELD(DBGWCR, MASK, 24, 5)
188
FIELD(DBGWCR, SSCE, 29, 1)
189
190
+#define VTCR_NSW (1u << 29)
191
+#define VTCR_NSA (1u << 30)
192
+#define VSTCR_SW VTCR_NSW
193
+#define VSTCR_SA VTCR_NSA
194
+
195
+/* Bit definitions for CPACR (AArch32 only) */
196
+FIELD(CPACR, CP10, 20, 2)
197
+FIELD(CPACR, CP11, 22, 2)
198
+FIELD(CPACR, TRCDIS, 28, 1) /* matches CPACR_EL1.TTA */
199
+FIELD(CPACR, D32DIS, 30, 1) /* up to v7; RAZ in v8 */
200
+FIELD(CPACR, ASEDIS, 31, 1)
201
+
202
+/* Bit definitions for CPACR_EL1 (AArch64 only) */
203
+FIELD(CPACR_EL1, ZEN, 16, 2)
204
+FIELD(CPACR_EL1, FPEN, 20, 2)
205
+FIELD(CPACR_EL1, SMEN, 24, 2)
206
+FIELD(CPACR_EL1, TTA, 28, 1) /* matches CPACR.TRCDIS */
207
+
208
+/* Bit definitions for HCPTR (AArch32 only) */
209
+FIELD(HCPTR, TCP10, 10, 1)
210
+FIELD(HCPTR, TCP11, 11, 1)
211
+FIELD(HCPTR, TASE, 15, 1)
212
+FIELD(HCPTR, TTA, 20, 1)
213
+FIELD(HCPTR, TAM, 30, 1) /* matches CPTR_EL2.TAM */
214
+FIELD(HCPTR, TCPAC, 31, 1) /* matches CPTR_EL2.TCPAC */
215
+
216
+/* Bit definitions for CPTR_EL2 (AArch64 only) */
217
+FIELD(CPTR_EL2, TZ, 8, 1) /* !E2H */
218
+FIELD(CPTR_EL2, TFP, 10, 1) /* !E2H, matches HCPTR.TCP10 */
219
+FIELD(CPTR_EL2, TSM, 12, 1) /* !E2H */
220
+FIELD(CPTR_EL2, ZEN, 16, 2) /* E2H */
221
+FIELD(CPTR_EL2, FPEN, 20, 2) /* E2H */
222
+FIELD(CPTR_EL2, SMEN, 24, 2) /* E2H */
223
+FIELD(CPTR_EL2, TTA, 28, 1)
224
+FIELD(CPTR_EL2, TAM, 30, 1) /* matches HCPTR.TAM */
225
+FIELD(CPTR_EL2, TCPAC, 31, 1) /* matches HCPTR.TCPAC */
226
+
227
+/* Bit definitions for CPTR_EL3 (AArch64 only) */
228
+FIELD(CPTR_EL3, EZ, 8, 1)
229
+FIELD(CPTR_EL3, TFP, 10, 1)
230
+FIELD(CPTR_EL3, ESM, 12, 1)
231
+FIELD(CPTR_EL3, TTA, 20, 1)
232
+FIELD(CPTR_EL3, TAM, 30, 1)
233
+FIELD(CPTR_EL3, TCPAC, 31, 1)
234
+
235
+#define MDCR_MTPME (1U << 28)
236
+#define MDCR_TDCC (1U << 27)
237
+#define MDCR_HLP (1U << 26) /* MDCR_EL2 */
238
+#define MDCR_SCCD (1U << 23) /* MDCR_EL3 */
239
+#define MDCR_HCCD (1U << 23) /* MDCR_EL2 */
240
+#define MDCR_EPMAD (1U << 21)
241
+#define MDCR_EDAD (1U << 20)
242
+#define MDCR_TTRF (1U << 19)
243
+#define MDCR_STE (1U << 18) /* MDCR_EL3 */
244
+#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
245
+#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */
246
+#define MDCR_SDD (1U << 16)
247
+#define MDCR_SPD (3U << 14)
248
+#define MDCR_TDRA (1U << 11)
249
+#define MDCR_TDOSA (1U << 10)
250
+#define MDCR_TDA (1U << 9)
251
+#define MDCR_TDE (1U << 8)
252
+#define MDCR_HPME (1U << 7)
253
+#define MDCR_TPM (1U << 6)
254
+#define MDCR_TPMCR (1U << 5)
255
+#define MDCR_HPMN (0x1fU)
256
+
257
+/* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */
258
+#define SDCR_VALID_MASK (MDCR_MTPME | MDCR_TDCC | MDCR_SCCD | \
259
+ MDCR_EPMAD | MDCR_EDAD | MDCR_TTRF | \
260
+ MDCR_STE | MDCR_SPME | MDCR_SPD)
261
+
262
+#define TTBCR_N (7U << 0) /* TTBCR.EAE==0 */
263
+#define TTBCR_T0SZ (7U << 0) /* TTBCR.EAE==1 */
264
+#define TTBCR_PD0 (1U << 4)
265
+#define TTBCR_PD1 (1U << 5)
266
+#define TTBCR_EPD0 (1U << 7)
267
+#define TTBCR_IRGN0 (3U << 8)
268
+#define TTBCR_ORGN0 (3U << 10)
269
+#define TTBCR_SH0 (3U << 12)
270
+#define TTBCR_T1SZ (3U << 16)
271
+#define TTBCR_A1 (1U << 22)
272
+#define TTBCR_EPD1 (1U << 23)
273
+#define TTBCR_IRGN1 (3U << 24)
274
+#define TTBCR_ORGN1 (3U << 26)
275
+#define TTBCR_SH1 (1U << 28)
276
+#define TTBCR_EAE (1U << 31)
277
+
278
+FIELD(VTCR, T0SZ, 0, 6)
279
+FIELD(VTCR, SL0, 6, 2)
280
+FIELD(VTCR, IRGN0, 8, 2)
281
+FIELD(VTCR, ORGN0, 10, 2)
282
+FIELD(VTCR, SH0, 12, 2)
283
+FIELD(VTCR, TG0, 14, 2)
284
+FIELD(VTCR, PS, 16, 3)
285
+FIELD(VTCR, VS, 19, 1)
286
+FIELD(VTCR, HA, 21, 1)
287
+FIELD(VTCR, HD, 22, 1)
288
+FIELD(VTCR, HWU59, 25, 1)
289
+FIELD(VTCR, HWU60, 26, 1)
290
+FIELD(VTCR, HWU61, 27, 1)
291
+FIELD(VTCR, HWU62, 28, 1)
292
+FIELD(VTCR, NSW, 29, 1)
293
+FIELD(VTCR, NSA, 30, 1)
294
+FIELD(VTCR, DS, 32, 1)
295
+FIELD(VTCR, SL2, 33, 1)
296
+
297
+#define HCRX_ENAS0 (1ULL << 0)
298
+#define HCRX_ENALS (1ULL << 1)
299
+#define HCRX_ENASR (1ULL << 2)
300
+#define HCRX_FNXS (1ULL << 3)
301
+#define HCRX_FGTNXS (1ULL << 4)
302
+#define HCRX_SMPME (1ULL << 5)
303
+#define HCRX_TALLINT (1ULL << 6)
304
+#define HCRX_VINMI (1ULL << 7)
305
+#define HCRX_VFNMI (1ULL << 8)
306
+#define HCRX_CMOW (1ULL << 9)
307
+#define HCRX_MCE2 (1ULL << 10)
308
+#define HCRX_MSCEN (1ULL << 11)
309
+
310
+#define HPFAR_NS (1ULL << 63)
311
+
312
+#define HSTR_TTEE (1 << 16)
313
+#define HSTR_TJDBX (1 << 17)
314
+
315
+#define CNTHCTL_CNTVMASK (1 << 18)
316
+#define CNTHCTL_CNTPMASK (1 << 19)
317
+
318
/* We use a few fake FSR values for internal purposes in M profile.
319
* M profile cores don't have A/R format FSRs, but currently our
320
* get_phys_addr() code assumes A/R profile and reports failures via
122
--
321
--
123
2.34.1
322
2.34.1
124
323
125
324
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
The timer _EL02 registers should UNDEF for invalid accesses from EL2
2
or EL3 when HCR_EL2.E2H == 0, not take a cp access trap. We were
3
delivering the exception to EL2 with the wrong syndrome.
2
4
3
sysbus_mmio_map() and sysbus_connect_irq() should not be
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
called on unrealized device.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20231020130331.50048-2-philmd@linaro.org
7
Message-id: 20240301183219.2424889-3-peter.maydell@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
hw/sd/pxa2xx_mmci.c | 2 +-
9
target/arm/helper.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
1 file changed, 1 insertion(+), 1 deletion(-)
14
11
15
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/sd/pxa2xx_mmci.c
14
--- a/target/arm/helper.c
18
+++ b/hw/sd/pxa2xx_mmci.c
15
+++ b/target/arm/helper.c
19
@@ -XXX,XX +XXX,XX @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
16
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
20
17
return CP_ACCESS_OK;
21
dev = qdev_new(TYPE_PXA2XX_MMCI);
18
}
22
sbd = SYS_BUS_DEVICE(dev);
19
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
23
+ sysbus_realize_and_unref(sbd, &error_fatal);
20
- return CP_ACCESS_TRAP;
24
sysbus_mmio_map(sbd, 0, base);
21
+ return CP_ACCESS_TRAP_UNCATEGORIZED;
25
sysbus_connect_irq(sbd, 0, irq);
22
}
26
qdev_connect_gpio_out_named(dev, "rx-dma", 0, rx_dma);
23
return CP_ACCESS_OK;
27
qdev_connect_gpio_out_named(dev, "tx-dma", 0, tx_dma);
28
- sysbus_realize_and_unref(sbd, &error_fatal);
29
30
return PXA2XX_MMCI(dev);
31
}
24
}
32
--
25
--
33
2.34.1
26
2.34.1
34
35
diff view generated by jsdifflib
1
The feature test functions isar_feature_*() now take up nearly
1
We prefer the FIELD macro over ad-hoc #defines for register bits;
2
a thousand lines in target/arm/cpu.h. This header file is included
2
switch CNTHCTL to that style before we add any more bits.
3
by a lot of source files, most of which don't need these functions.
4
Move the feature test functions to their own header file.
5
3
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20231024163510.2972081-2-peter.maydell@linaro.org
7
Message-id: 20240301183219.2424889-4-peter.maydell@linaro.org
10
---
8
---
11
bsd-user/arm/target_arch.h | 1 +
9
target/arm/internals.h | 27 +++++++++++++++++++++++++--
12
linux-user/aarch64/target_prctl.h | 2 +
10
target/arm/helper.c | 9 ++++-----
13
target/arm/cpu-features.h | 994 ++++++++++++++++++++++++++++++
11
2 files changed, 29 insertions(+), 7 deletions(-)
14
target/arm/cpu.h | 971 -----------------------------
15
target/arm/internals.h | 1 +
16
target/arm/tcg/translate.h | 2 +-
17
hw/arm/armv7m.c | 1 +
18
hw/intc/armv7m_nvic.c | 1 +
19
linux-user/aarch64/cpu_loop.c | 1 +
20
linux-user/aarch64/signal.c | 1 +
21
linux-user/arm/signal.c | 1 +
22
linux-user/elfload.c | 4 +
23
linux-user/mmap.c | 4 +
24
target/arm/arch_dump.c | 1 +
25
target/arm/cpu.c | 1 +
26
target/arm/cpu64.c | 1 +
27
target/arm/debug_helper.c | 1 +
28
target/arm/gdbstub.c | 1 +
29
target/arm/helper.c | 1 +
30
target/arm/kvm64.c | 1 +
31
target/arm/machine.c | 1 +
32
target/arm/ptw.c | 1 +
33
target/arm/tcg/cpu64.c | 1 +
34
target/arm/tcg/hflags.c | 1 +
35
target/arm/tcg/m_helper.c | 1 +
36
target/arm/tcg/op_helper.c | 1 +
37
target/arm/tcg/pauth_helper.c | 1 +
38
target/arm/tcg/tlb_helper.c | 1 +
39
target/arm/vfp_helper.c | 1 +
40
29 files changed, 1028 insertions(+), 972 deletions(-)
41
create mode 100644 target/arm/cpu-features.h
42
12
43
diff --git a/bsd-user/arm/target_arch.h b/bsd-user/arm/target_arch.h
44
index XXXXXXX..XXXXXXX 100644
45
--- a/bsd-user/arm/target_arch.h
46
+++ b/bsd-user/arm/target_arch.h
47
@@ -XXX,XX +XXX,XX @@
48
#define TARGET_ARCH_H
49
50
#include "qemu.h"
51
+#include "target/arm/cpu-features.h"
52
53
void target_cpu_set_tls(CPUARMState *env, target_ulong newtls);
54
target_ulong target_cpu_get_tls(CPUARMState *env);
55
diff --git a/linux-user/aarch64/target_prctl.h b/linux-user/aarch64/target_prctl.h
56
index XXXXXXX..XXXXXXX 100644
57
--- a/linux-user/aarch64/target_prctl.h
58
+++ b/linux-user/aarch64/target_prctl.h
59
@@ -XXX,XX +XXX,XX @@
60
#ifndef AARCH64_TARGET_PRCTL_H
61
#define AARCH64_TARGET_PRCTL_H
62
63
+#include "target/arm/cpu-features.h"
64
+
65
static abi_long do_prctl_sve_get_vl(CPUArchState *env)
66
{
67
ARMCPU *cpu = env_archcpu(env);
68
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
69
new file mode 100644
70
index XXXXXXX..XXXXXXX
71
--- /dev/null
72
+++ b/target/arm/cpu-features.h
73
@@ -XXX,XX +XXX,XX @@
74
+/*
75
+ * QEMU Arm CPU -- feature test functions
76
+ *
77
+ * Copyright (c) 2023 Linaro Ltd
78
+ *
79
+ * This library is free software; you can redistribute it and/or
80
+ * modify it under the terms of the GNU Lesser General Public
81
+ * License as published by the Free Software Foundation; either
82
+ * version 2.1 of the License, or (at your option) any later version.
83
+ *
84
+ * This library is distributed in the hope that it will be useful,
85
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
86
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
87
+ * Lesser General Public License for more details.
88
+ *
89
+ * You should have received a copy of the GNU Lesser General Public
90
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
91
+ */
92
+
93
+#ifndef TARGET_ARM_FEATURES_H
94
+#define TARGET_ARM_FEATURES_H
95
+
96
+/*
97
+ * Naming convention for isar_feature functions:
98
+ * Functions which test 32-bit ID registers should have _aa32_ in
99
+ * their name. Functions which test 64-bit ID registers should have
100
+ * _aa64_ in their name. These must only be used in code where we
101
+ * know for certain that the CPU has AArch32 or AArch64 respectively
102
+ * or where the correct answer for a CPU which doesn't implement that
103
+ * CPU state is "false" (eg when generating A32 or A64 code, if adding
104
+ * system registers that are specific to that CPU state, for "should
105
+ * we let this system register bit be set" tests where the 32-bit
106
+ * flavour of the register doesn't have the bit, and so on).
107
+ * Functions which simply ask "does this feature exist at all" have
108
+ * _any_ in their name, and always return the logical OR of the _aa64_
109
+ * and the _aa32_ function.
110
+ */
111
+
112
+/*
113
+ * 32-bit feature tests via id registers.
114
+ */
115
+static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
116
+{
117
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
118
+}
119
+
120
+static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
121
+{
122
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
123
+}
124
+
125
+static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
126
+{
127
+ /* (M-profile) low-overhead loops and branch future */
128
+ return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3;
129
+}
130
+
131
+static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
132
+{
133
+ return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
134
+}
135
+
136
+static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
137
+{
138
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
139
+}
140
+
141
+static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
142
+{
143
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1;
144
+}
145
+
146
+static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
147
+{
148
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0;
149
+}
150
+
151
+static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
152
+{
153
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0;
154
+}
155
+
156
+static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
157
+{
158
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0;
159
+}
160
+
161
+static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
162
+{
163
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0;
164
+}
165
+
166
+static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
167
+{
168
+ return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
169
+}
170
+
171
+static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id)
172
+{
173
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, JSCVT) != 0;
174
+}
175
+
176
+static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
177
+{
178
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
179
+}
180
+
181
+static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
182
+{
183
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
184
+}
185
+
186
+static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
187
+{
188
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
189
+}
190
+
191
+static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
192
+{
193
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
194
+}
195
+
196
+static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id)
197
+{
198
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0;
199
+}
200
+
201
+static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
202
+{
203
+ return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0;
204
+}
205
+
206
+static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
207
+{
208
+ return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0;
209
+}
210
+
211
+static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
212
+{
213
+ return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
214
+}
215
+
216
+static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
217
+{
218
+ /*
219
+ * Return true if M-profile state handling insns
220
+ * (VSCCLRM, CLRM, FPCTX access insns) are implemented
221
+ */
222
+ return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3;
223
+}
224
+
225
+static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
226
+{
227
+ /* Sadly this is encoded differently for A-profile and M-profile */
228
+ if (isar_feature_aa32_mprofile(id)) {
229
+ return FIELD_EX32(id->mvfr1, MVFR1, FP16) > 0;
230
+ } else {
231
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) >= 3;
232
+ }
233
+}
234
+
235
+static inline bool isar_feature_aa32_mve(const ARMISARegisters *id)
236
+{
237
+ /*
238
+ * Return true if MVE is supported (either integer or floating point).
239
+ * We must check for M-profile as the MVFR1 field means something
240
+ * else for A-profile.
241
+ */
242
+ return isar_feature_aa32_mprofile(id) &&
243
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) > 0;
244
+}
245
+
246
+static inline bool isar_feature_aa32_mve_fp(const ARMISARegisters *id)
247
+{
248
+ /*
249
+ * Return true if MVE is supported (either integer or floating point).
250
+ * We must check for M-profile as the MVFR1 field means something
251
+ * else for A-profile.
252
+ */
253
+ return isar_feature_aa32_mprofile(id) &&
254
+ FIELD_EX32(id->mvfr1, MVFR1, MVE) >= 2;
255
+}
256
+
257
+static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id)
258
+{
259
+ /*
260
+ * Return true if either VFP or SIMD is implemented.
261
+ * In this case, a minimum of VFP w/ D0-D15.
262
+ */
263
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0;
264
+}
265
+
266
+static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
267
+{
268
+ /* Return true if D16-D31 are implemented */
269
+ return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
270
+}
271
+
272
+static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
273
+{
274
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
275
+}
276
+
277
+static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
278
+{
279
+ /* Return true if CPU supports single precision floating point, VFPv2 */
280
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
281
+}
282
+
283
+static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
284
+{
285
+ /* Return true if CPU supports single precision floating point, VFPv3 */
286
+ return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
287
+}
288
+
289
+static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
290
+{
291
+ /* Return true if CPU supports double precision floating point, VFPv2 */
292
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
293
+}
294
+
295
+static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
296
+{
297
+ /* Return true if CPU supports double precision floating point, VFPv3 */
298
+ return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
299
+}
300
+
301
+static inline bool isar_feature_aa32_vfp(const ARMISARegisters *id)
302
+{
303
+ return isar_feature_aa32_fpsp_v2(id) || isar_feature_aa32_fpdp_v2(id);
304
+}
305
+
306
+/*
307
+ * We always set the FP and SIMD FP16 fields to indicate identical
308
+ * levels of support (assuming SIMD is implemented at all), so
309
+ * we only need one set of accessors.
310
+ */
311
+static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id)
312
+{
313
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 0;
314
+}
315
+
316
+static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
317
+{
318
+ return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
319
+}
320
+
321
+/*
322
+ * Note that this ID register field covers both VFP and Neon FMAC,
323
+ * so should usually be tested in combination with some other
324
+ * check that confirms the presence of whichever of VFP or Neon is
325
+ * relevant, to avoid accidentally enabling a Neon feature on
326
+ * a VFP-no-Neon core or vice-versa.
327
+ */
328
+static inline bool isar_feature_aa32_simdfmac(const ARMISARegisters *id)
329
+{
330
+ return FIELD_EX32(id->mvfr1, MVFR1, SIMDFMAC) != 0;
331
+}
332
+
333
+static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
334
+{
335
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1;
336
+}
337
+
338
+static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
339
+{
340
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 2;
341
+}
342
+
343
+static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
344
+{
345
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 3;
346
+}
347
+
348
+static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
349
+{
350
+ return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 4;
351
+}
352
+
353
+static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id)
354
+{
355
+ return FIELD_EX32(id->id_mmfr0, ID_MMFR0, VMSA) >= 4;
356
+}
357
+
358
+static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
359
+{
360
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0;
361
+}
362
+
363
+static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
364
+{
365
+ return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
366
+}
367
+
368
+static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id)
369
+{
370
+ /* 0xf means "non-standard IMPDEF PMU" */
371
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
372
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
373
+}
374
+
375
+static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id)
376
+{
377
+ /* 0xf means "non-standard IMPDEF PMU" */
378
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
379
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
380
+}
381
+
382
+static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
383
+{
384
+ /* 0xf means "non-standard IMPDEF PMU" */
385
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 &&
386
+ FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
387
+}
388
+
389
+static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
390
+{
391
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
392
+}
393
+
394
+static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
395
+{
396
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
397
+}
398
+
399
+static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
400
+{
401
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
402
+}
403
+
404
+static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
405
+{
406
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
407
+}
408
+
409
+static inline bool isar_feature_aa32_half_evt(const ARMISARegisters *id)
410
+{
411
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 1;
412
+}
413
+
414
+static inline bool isar_feature_aa32_evt(const ARMISARegisters *id)
415
+{
416
+ return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 2;
417
+}
418
+
419
+static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
420
+{
421
+ return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
422
+}
423
+
424
+static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
425
+{
426
+ return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
427
+}
428
+
429
+static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id)
430
+{
431
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 5;
432
+}
433
+
434
+static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
435
+{
436
+ return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
437
+}
438
+
439
+static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id)
440
+{
441
+ return FIELD_EX32(id->dbgdevid, DBGDEVID, DOUBLELOCK) > 0;
442
+}
443
+
444
+/*
445
+ * 64-bit feature tests via id registers.
446
+ */
447
+static inline bool isar_feature_aa64_aes(const ARMISARegisters *id)
448
+{
449
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0;
450
+}
451
+
452
+static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id)
453
+{
454
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1;
455
+}
456
+
457
+static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id)
458
+{
459
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0;
460
+}
461
+
462
+static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id)
463
+{
464
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0;
465
+}
466
+
467
+static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id)
468
+{
469
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1;
470
+}
471
+
472
+static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id)
473
+{
474
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0;
475
+}
476
+
477
+static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id)
478
+{
479
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0;
480
+}
481
+
482
+static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
483
+{
484
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0;
485
+}
486
+
487
+static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
488
+{
489
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0;
490
+}
491
+
492
+static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id)
493
+{
494
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0;
495
+}
496
+
497
+static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id)
498
+{
499
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0;
500
+}
501
+
502
+static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
503
+{
504
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
505
+}
506
+
507
+static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
508
+{
509
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
510
+}
511
+
512
+static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
513
+{
514
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
515
+}
516
+
517
+static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
518
+{
519
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
520
+}
521
+
522
+static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
523
+{
524
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
525
+}
526
+
527
+static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
528
+{
529
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
530
+}
531
+
532
+static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
533
+{
534
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
535
+}
536
+
537
+/*
538
+ * These are the values from APA/API/APA3.
539
+ * In general these must be compared '>=', per the normal Arm ARM
540
+ * treatment of fields in ID registers.
541
+ */
542
+typedef enum {
543
+ PauthFeat_None = 0,
544
+ PauthFeat_1 = 1,
545
+ PauthFeat_EPAC = 2,
546
+ PauthFeat_2 = 3,
547
+ PauthFeat_FPAC = 4,
548
+ PauthFeat_FPACCOMBINED = 5,
549
+} ARMPauthFeature;
550
+
551
+static inline ARMPauthFeature
552
+isar_feature_pauth_feature(const ARMISARegisters *id)
553
+{
554
+ /*
555
+ * Architecturally, only one of {APA,API,APA3} may be active (non-zero)
556
+ * and the other two must be zero. Thus we may avoid conditionals.
557
+ */
558
+ return (FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) |
559
+ FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, API) |
560
+ FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3));
561
+}
562
+
563
+static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
564
+{
565
+ /*
566
+ * Return true if any form of pauth is enabled, as this
567
+ * predicate controls migration of the 128-bit keys.
568
+ */
569
+ return isar_feature_pauth_feature(id) != PauthFeat_None;
570
+}
571
+
572
+static inline bool isar_feature_aa64_pauth_qarma5(const ARMISARegisters *id)
573
+{
574
+ /*
575
+ * Return true if pauth is enabled with the architected QARMA5 algorithm.
576
+ * QEMU will always enable or disable both APA and GPA.
577
+ */
578
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
579
+}
580
+
581
+static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
582
+{
583
+ /*
584
+ * Return true if pauth is enabled with the architected QARMA3 algorithm.
585
+ * QEMU will always enable or disable both APA3 and GPA3.
586
+ */
587
+ return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0;
588
+}
589
+
590
+static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
591
+{
592
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
593
+}
594
+
595
+static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
596
+{
597
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0;
598
+}
599
+
600
+static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
601
+{
602
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
603
+}
604
+
605
+static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
606
+{
607
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
608
+}
609
+
610
+static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
611
+{
612
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
613
+}
614
+
615
+static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
616
+{
617
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
618
+}
619
+
620
+static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
621
+{
622
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
623
+}
624
+
625
+static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
626
+{
627
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
628
+}
629
+
630
+static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
631
+{
632
+ /* We always set the AdvSIMD and FP fields identically. */
633
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf;
634
+}
635
+
636
+static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
637
+{
638
+ /* We always set the AdvSIMD and FP fields identically wrt FP16. */
639
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
640
+}
641
+
642
+static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id)
643
+{
644
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL0) >= 2;
645
+}
646
+
647
+static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
648
+{
649
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2;
650
+}
651
+
652
+static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id)
653
+{
654
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL2) >= 2;
655
+}
656
+
657
+static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
658
+{
659
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0;
660
+}
661
+
662
+static inline bool isar_feature_aa64_doublefault(const ARMISARegisters *id)
663
+{
664
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) >= 2;
665
+}
666
+
667
+static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
668
+{
669
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
670
+}
671
+
672
+static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
673
+{
674
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
675
+}
676
+
677
+static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
678
+{
679
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
680
+}
681
+
682
+static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
683
+{
684
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
685
+}
686
+
687
+static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
688
+{
689
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
690
+}
691
+
692
+static inline bool isar_feature_aa64_pan(const ARMISARegisters *id)
693
+{
694
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0;
695
+}
696
+
697
+static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
698
+{
699
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
700
+}
701
+
702
+static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id)
703
+{
704
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3;
705
+}
706
+
707
+static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
708
+{
709
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;
710
+}
711
+
712
+static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
713
+{
714
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR1, TIDCP1) != 0;
715
+}
716
+
717
+static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
718
+{
719
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
720
+}
721
+
722
+static inline bool isar_feature_aa64_st(const ARMISARegisters *id)
723
+{
724
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, ST) != 0;
725
+}
726
+
727
+static inline bool isar_feature_aa64_lse2(const ARMISARegisters *id)
728
+{
729
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, AT) != 0;
730
+}
731
+
732
+static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id)
733
+{
734
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, FWB) != 0;
735
+}
736
+
737
+static inline bool isar_feature_aa64_ids(const ARMISARegisters *id)
738
+{
739
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, IDS) != 0;
740
+}
741
+
742
+static inline bool isar_feature_aa64_half_evt(const ARMISARegisters *id)
743
+{
744
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 1;
745
+}
746
+
747
+static inline bool isar_feature_aa64_evt(const ARMISARegisters *id)
748
+{
749
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2;
750
+}
751
+
752
+static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
753
+{
754
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
755
+}
756
+
757
+static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
758
+{
759
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
760
+}
761
+
762
+static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
763
+{
764
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
765
+}
766
+
767
+static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
768
+{
769
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
770
+}
771
+
772
+static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
773
+{
774
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
775
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
776
+}
777
+
778
+static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id)
779
+{
780
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
781
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
782
+}
783
+
784
+static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
785
+{
786
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 &&
787
+ FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
788
+}
789
+
790
+static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
791
+{
792
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
793
+}
794
+
795
+static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
796
+{
797
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
798
+}
799
+
800
+static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
801
+{
802
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
803
+}
804
+
805
+static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id)
806
+{
807
+ return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0;
808
+}
809
+
810
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
811
+{
812
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
813
+}
814
+
815
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
816
+{
817
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
818
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
819
+}
820
+
821
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
822
+{
823
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
824
+}
825
+
826
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
827
+{
828
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
829
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
830
+}
831
+
832
+static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
833
+{
834
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
835
+}
836
+
837
+static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
838
+{
839
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
840
+}
841
+
842
+static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
843
+{
844
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
845
+}
846
+
847
+static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
848
+{
849
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
850
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
851
+}
852
+
853
+static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
854
+{
855
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
856
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
857
+}
858
+
859
+static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
860
+{
861
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
862
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
863
+}
864
+
865
+static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
866
+{
867
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
868
+}
869
+
870
+static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
871
+{
872
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
873
+}
874
+
875
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
876
+{
877
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
878
+}
879
+
880
+static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
881
+{
882
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
883
+}
884
+
885
+static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
886
+{
887
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
888
+}
889
+
890
+static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
891
+{
892
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
893
+}
894
+
895
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
896
+{
897
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
898
+}
899
+
900
+static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
901
+{
902
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
903
+}
904
+
905
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
906
+{
907
+ int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
908
+ if (key >= 2) {
909
+ return true; /* FEAT_CSV2_2 */
910
+ }
911
+ if (key == 1) {
912
+ key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
913
+ return key >= 2; /* FEAT_CSV2_1p2 */
914
+ }
915
+ return false;
916
+}
917
+
918
+static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
919
+{
920
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
921
+}
922
+
923
+static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
924
+{
925
+ return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
926
+}
927
+
928
+static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
929
+{
930
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
931
+}
932
+
933
+static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id)
934
+{
935
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) != 0;
936
+}
937
+
938
+static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id)
939
+{
940
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2;
941
+}
942
+
943
+static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
944
+{
945
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
946
+}
947
+
948
+static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id)
949
+{
950
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0;
951
+}
952
+
953
+static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
954
+{
955
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0;
956
+}
957
+
958
+static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id)
959
+{
960
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0;
961
+}
962
+
963
+static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id)
964
+{
965
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0;
966
+}
967
+
968
+static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id)
969
+{
970
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0;
971
+}
972
+
973
+static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id)
974
+{
975
+ return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0;
976
+}
977
+
978
+static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id)
979
+{
980
+ return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, F64F64);
981
+}
982
+
983
+static inline bool isar_feature_aa64_sme_i16i64(const ARMISARegisters *id)
984
+{
985
+ return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, I16I64) == 0xf;
986
+}
987
+
988
+static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id)
989
+{
990
+ return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64);
991
+}
992
+
993
+static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
994
+{
995
+ return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
996
+}
997
+
998
+static inline bool isar_feature_aa64_mops(const ARMISARegisters *id)
999
+{
1000
+ return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS);
1001
+}
1002
+
1003
+/*
1004
+ * Feature tests for "does this exist in either 32-bit or 64-bit?"
1005
+ */
1006
+static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
1007
+{
1008
+ return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
1009
+}
1010
+
1011
+static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
1012
+{
1013
+ return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
1014
+}
1015
+
1016
+static inline bool isar_feature_any_pmuv3p1(const ARMISARegisters *id)
1017
+{
1018
+ return isar_feature_aa64_pmuv3p1(id) || isar_feature_aa32_pmuv3p1(id);
1019
+}
1020
+
1021
+static inline bool isar_feature_any_pmuv3p4(const ARMISARegisters *id)
1022
+{
1023
+ return isar_feature_aa64_pmuv3p4(id) || isar_feature_aa32_pmuv3p4(id);
1024
+}
1025
+
1026
+static inline bool isar_feature_any_pmuv3p5(const ARMISARegisters *id)
1027
+{
1028
+ return isar_feature_aa64_pmuv3p5(id) || isar_feature_aa32_pmuv3p5(id);
1029
+}
1030
+
1031
+static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
1032
+{
1033
+ return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
1034
+}
1035
+
1036
+static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
1037
+{
1038
+ return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
1039
+}
1040
+
1041
+static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
1042
+{
1043
+ return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
1044
+}
1045
+
1046
+static inline bool isar_feature_any_ras(const ARMISARegisters *id)
1047
+{
1048
+ return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id);
1049
+}
1050
+
1051
+static inline bool isar_feature_any_half_evt(const ARMISARegisters *id)
1052
+{
1053
+ return isar_feature_aa64_half_evt(id) || isar_feature_aa32_half_evt(id);
1054
+}
1055
+
1056
+static inline bool isar_feature_any_evt(const ARMISARegisters *id)
1057
+{
1058
+ return isar_feature_aa64_evt(id) || isar_feature_aa32_evt(id);
1059
+}
1060
+
1061
+/*
1062
+ * Forward to the above feature tests given an ARMCPU pointer.
1063
+ */
1064
+#define cpu_isar_feature(name, cpu) \
1065
+ ({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
1066
+
1067
+#endif
1068
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
1069
index XXXXXXX..XXXXXXX 100644
1070
--- a/target/arm/cpu.h
1071
+++ b/target/arm/cpu.h
1072
@@ -XXX,XX +XXX,XX @@ static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x)
1073
}
1074
#endif
1075
1076
-/*
1077
- * Naming convention for isar_feature functions:
1078
- * Functions which test 32-bit ID registers should have _aa32_ in
1079
- * their name. Functions which test 64-bit ID registers should have
1080
- * _aa64_ in their name. These must only be used in code where we
1081
- * know for certain that the CPU has AArch32 or AArch64 respectively
1082
- * or where the correct answer for a CPU which doesn't implement that
1083
- * CPU state is "false" (eg when generating A32 or A64 code, if adding
1084
- * system registers that are specific to that CPU state, for "should
1085
- * we let this system register bit be set" tests where the 32-bit
1086
- * flavour of the register doesn't have the bit, and so on).
1087
- * Functions which simply ask "does this feature exist at all" have
1088
- * _any_ in their name, and always return the logical OR of the _aa64_
1089
- * and the _aa32_ function.
1090
- */
1091
-
1092
-/*
1093
- * 32-bit feature tests via id registers.
1094
- */
1095
-static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
1096
-{
1097
- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
1098
-}
1099
-
1100
-static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
1101
-{
1102
- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
1103
-}
1104
-
1105
-static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
1106
-{
1107
- /* (M-profile) low-overhead loops and branch future */
1108
- return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3;
1109
-}
1110
-
1111
-static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
1112
-{
1113
- return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
1114
-}
1115
-
1116
-static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
1117
-{
1118
- return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
1119
-}
1120
-
1121
-static inline bool isar_feature_aa32_pmull(const ARMISARegisters *id)
1122
-{
1123
- return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) > 1;
1124
-}
1125
-
1126
-static inline bool isar_feature_aa32_sha1(const ARMISARegisters *id)
1127
-{
1128
- return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA1) != 0;
1129
-}
1130
-
1131
-static inline bool isar_feature_aa32_sha2(const ARMISARegisters *id)
1132
-{
1133
- return FIELD_EX32(id->id_isar5, ID_ISAR5, SHA2) != 0;
1134
-}
1135
-
1136
-static inline bool isar_feature_aa32_crc32(const ARMISARegisters *id)
1137
-{
1138
- return FIELD_EX32(id->id_isar5, ID_ISAR5, CRC32) != 0;
1139
-}
1140
-
1141
-static inline bool isar_feature_aa32_rdm(const ARMISARegisters *id)
1142
-{
1143
- return FIELD_EX32(id->id_isar5, ID_ISAR5, RDM) != 0;
1144
-}
1145
-
1146
-static inline bool isar_feature_aa32_vcma(const ARMISARegisters *id)
1147
-{
1148
- return FIELD_EX32(id->id_isar5, ID_ISAR5, VCMA) != 0;
1149
-}
1150
-
1151
-static inline bool isar_feature_aa32_jscvt(const ARMISARegisters *id)
1152
-{
1153
- return FIELD_EX32(id->id_isar6, ID_ISAR6, JSCVT) != 0;
1154
-}
1155
-
1156
-static inline bool isar_feature_aa32_dp(const ARMISARegisters *id)
1157
-{
1158
- return FIELD_EX32(id->id_isar6, ID_ISAR6, DP) != 0;
1159
-}
1160
-
1161
-static inline bool isar_feature_aa32_fhm(const ARMISARegisters *id)
1162
-{
1163
- return FIELD_EX32(id->id_isar6, ID_ISAR6, FHM) != 0;
1164
-}
1165
-
1166
-static inline bool isar_feature_aa32_sb(const ARMISARegisters *id)
1167
-{
1168
- return FIELD_EX32(id->id_isar6, ID_ISAR6, SB) != 0;
1169
-}
1170
-
1171
-static inline bool isar_feature_aa32_predinv(const ARMISARegisters *id)
1172
-{
1173
- return FIELD_EX32(id->id_isar6, ID_ISAR6, SPECRES) != 0;
1174
-}
1175
-
1176
-static inline bool isar_feature_aa32_bf16(const ARMISARegisters *id)
1177
-{
1178
- return FIELD_EX32(id->id_isar6, ID_ISAR6, BF16) != 0;
1179
-}
1180
-
1181
-static inline bool isar_feature_aa32_i8mm(const ARMISARegisters *id)
1182
-{
1183
- return FIELD_EX32(id->id_isar6, ID_ISAR6, I8MM) != 0;
1184
-}
1185
-
1186
-static inline bool isar_feature_aa32_ras(const ARMISARegisters *id)
1187
-{
1188
- return FIELD_EX32(id->id_pfr0, ID_PFR0, RAS) != 0;
1189
-}
1190
-
1191
-static inline bool isar_feature_aa32_mprofile(const ARMISARegisters *id)
1192
-{
1193
- return FIELD_EX32(id->id_pfr1, ID_PFR1, MPROGMOD) != 0;
1194
-}
1195
-
1196
-static inline bool isar_feature_aa32_m_sec_state(const ARMISARegisters *id)
1197
-{
1198
- /*
1199
- * Return true if M-profile state handling insns
1200
- * (VSCCLRM, CLRM, FPCTX access insns) are implemented
1201
- */
1202
- return FIELD_EX32(id->id_pfr1, ID_PFR1, SECURITY) >= 3;
1203
-}
1204
-
1205
-static inline bool isar_feature_aa32_fp16_arith(const ARMISARegisters *id)
1206
-{
1207
- /* Sadly this is encoded differently for A-profile and M-profile */
1208
- if (isar_feature_aa32_mprofile(id)) {
1209
- return FIELD_EX32(id->mvfr1, MVFR1, FP16) > 0;
1210
- } else {
1211
- return FIELD_EX32(id->mvfr1, MVFR1, FPHP) >= 3;
1212
- }
1213
-}
1214
-
1215
-static inline bool isar_feature_aa32_mve(const ARMISARegisters *id)
1216
-{
1217
- /*
1218
- * Return true if MVE is supported (either integer or floating point).
1219
- * We must check for M-profile as the MVFR1 field means something
1220
- * else for A-profile.
1221
- */
1222
- return isar_feature_aa32_mprofile(id) &&
1223
- FIELD_EX32(id->mvfr1, MVFR1, MVE) > 0;
1224
-}
1225
-
1226
-static inline bool isar_feature_aa32_mve_fp(const ARMISARegisters *id)
1227
-{
1228
- /*
1229
- * Return true if MVE is supported (either integer or floating point).
1230
- * We must check for M-profile as the MVFR1 field means something
1231
- * else for A-profile.
1232
- */
1233
- return isar_feature_aa32_mprofile(id) &&
1234
- FIELD_EX32(id->mvfr1, MVFR1, MVE) >= 2;
1235
-}
1236
-
1237
-static inline bool isar_feature_aa32_vfp_simd(const ARMISARegisters *id)
1238
-{
1239
- /*
1240
- * Return true if either VFP or SIMD is implemented.
1241
- * In this case, a minimum of VFP w/ D0-D15.
1242
- */
1243
- return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) > 0;
1244
-}
1245
-
1246
-static inline bool isar_feature_aa32_simd_r32(const ARMISARegisters *id)
1247
-{
1248
- /* Return true if D16-D31 are implemented */
1249
- return FIELD_EX32(id->mvfr0, MVFR0, SIMDREG) >= 2;
1250
-}
1251
-
1252
-static inline bool isar_feature_aa32_fpshvec(const ARMISARegisters *id)
1253
-{
1254
- return FIELD_EX32(id->mvfr0, MVFR0, FPSHVEC) > 0;
1255
-}
1256
-
1257
-static inline bool isar_feature_aa32_fpsp_v2(const ARMISARegisters *id)
1258
-{
1259
- /* Return true if CPU supports single precision floating point, VFPv2 */
1260
- return FIELD_EX32(id->mvfr0, MVFR0, FPSP) > 0;
1261
-}
1262
-
1263
-static inline bool isar_feature_aa32_fpsp_v3(const ARMISARegisters *id)
1264
-{
1265
- /* Return true if CPU supports single precision floating point, VFPv3 */
1266
- return FIELD_EX32(id->mvfr0, MVFR0, FPSP) >= 2;
1267
-}
1268
-
1269
-static inline bool isar_feature_aa32_fpdp_v2(const ARMISARegisters *id)
1270
-{
1271
- /* Return true if CPU supports double precision floating point, VFPv2 */
1272
- return FIELD_EX32(id->mvfr0, MVFR0, FPDP) > 0;
1273
-}
1274
-
1275
-static inline bool isar_feature_aa32_fpdp_v3(const ARMISARegisters *id)
1276
-{
1277
- /* Return true if CPU supports double precision floating point, VFPv3 */
1278
- return FIELD_EX32(id->mvfr0, MVFR0, FPDP) >= 2;
1279
-}
1280
-
1281
-static inline bool isar_feature_aa32_vfp(const ARMISARegisters *id)
1282
-{
1283
- return isar_feature_aa32_fpsp_v2(id) || isar_feature_aa32_fpdp_v2(id);
1284
-}
1285
-
1286
-/*
1287
- * We always set the FP and SIMD FP16 fields to indicate identical
1288
- * levels of support (assuming SIMD is implemented at all), so
1289
- * we only need one set of accessors.
1290
- */
1291
-static inline bool isar_feature_aa32_fp16_spconv(const ARMISARegisters *id)
1292
-{
1293
- return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 0;
1294
-}
1295
-
1296
-static inline bool isar_feature_aa32_fp16_dpconv(const ARMISARegisters *id)
1297
-{
1298
- return FIELD_EX32(id->mvfr1, MVFR1, FPHP) > 1;
1299
-}
1300
-
1301
-/*
1302
- * Note that this ID register field covers both VFP and Neon FMAC,
1303
- * so should usually be tested in combination with some other
1304
- * check that confirms the presence of whichever of VFP or Neon is
1305
- * relevant, to avoid accidentally enabling a Neon feature on
1306
- * a VFP-no-Neon core or vice-versa.
1307
- */
1308
-static inline bool isar_feature_aa32_simdfmac(const ARMISARegisters *id)
1309
-{
1310
- return FIELD_EX32(id->mvfr1, MVFR1, SIMDFMAC) != 0;
1311
-}
1312
-
1313
-static inline bool isar_feature_aa32_vsel(const ARMISARegisters *id)
1314
-{
1315
- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 1;
1316
-}
1317
-
1318
-static inline bool isar_feature_aa32_vcvt_dr(const ARMISARegisters *id)
1319
-{
1320
- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 2;
1321
-}
1322
-
1323
-static inline bool isar_feature_aa32_vrint(const ARMISARegisters *id)
1324
-{
1325
- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 3;
1326
-}
1327
-
1328
-static inline bool isar_feature_aa32_vminmaxnm(const ARMISARegisters *id)
1329
-{
1330
- return FIELD_EX32(id->mvfr2, MVFR2, FPMISC) >= 4;
1331
-}
1332
-
1333
-static inline bool isar_feature_aa32_pxn(const ARMISARegisters *id)
1334
-{
1335
- return FIELD_EX32(id->id_mmfr0, ID_MMFR0, VMSA) >= 4;
1336
-}
1337
-
1338
-static inline bool isar_feature_aa32_pan(const ARMISARegisters *id)
1339
-{
1340
- return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) != 0;
1341
-}
1342
-
1343
-static inline bool isar_feature_aa32_ats1e1(const ARMISARegisters *id)
1344
-{
1345
- return FIELD_EX32(id->id_mmfr3, ID_MMFR3, PAN) >= 2;
1346
-}
1347
-
1348
-static inline bool isar_feature_aa32_pmuv3p1(const ARMISARegisters *id)
1349
-{
1350
- /* 0xf means "non-standard IMPDEF PMU" */
1351
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
1352
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
1353
-}
1354
-
1355
-static inline bool isar_feature_aa32_pmuv3p4(const ARMISARegisters *id)
1356
-{
1357
- /* 0xf means "non-standard IMPDEF PMU" */
1358
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 5 &&
1359
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
1360
-}
1361
-
1362
-static inline bool isar_feature_aa32_pmuv3p5(const ARMISARegisters *id)
1363
-{
1364
- /* 0xf means "non-standard IMPDEF PMU" */
1365
- return FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) >= 6 &&
1366
- FIELD_EX32(id->id_dfr0, ID_DFR0, PERFMON) != 0xf;
1367
-}
1368
-
1369
-static inline bool isar_feature_aa32_hpd(const ARMISARegisters *id)
1370
-{
1371
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, HPDS) != 0;
1372
-}
1373
-
1374
-static inline bool isar_feature_aa32_ac2(const ARMISARegisters *id)
1375
-{
1376
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, AC2) != 0;
1377
-}
1378
-
1379
-static inline bool isar_feature_aa32_ccidx(const ARMISARegisters *id)
1380
-{
1381
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, CCIDX) != 0;
1382
-}
1383
-
1384
-static inline bool isar_feature_aa32_tts2uxn(const ARMISARegisters *id)
1385
-{
1386
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, XNX) != 0;
1387
-}
1388
-
1389
-static inline bool isar_feature_aa32_half_evt(const ARMISARegisters *id)
1390
-{
1391
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 1;
1392
-}
1393
-
1394
-static inline bool isar_feature_aa32_evt(const ARMISARegisters *id)
1395
-{
1396
- return FIELD_EX32(id->id_mmfr4, ID_MMFR4, EVT) >= 2;
1397
-}
1398
-
1399
-static inline bool isar_feature_aa32_dit(const ARMISARegisters *id)
1400
-{
1401
- return FIELD_EX32(id->id_pfr0, ID_PFR0, DIT) != 0;
1402
-}
1403
-
1404
-static inline bool isar_feature_aa32_ssbs(const ARMISARegisters *id)
1405
-{
1406
- return FIELD_EX32(id->id_pfr2, ID_PFR2, SSBS) != 0;
1407
-}
1408
-
1409
-static inline bool isar_feature_aa32_debugv7p1(const ARMISARegisters *id)
1410
-{
1411
- return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 5;
1412
-}
1413
-
1414
-static inline bool isar_feature_aa32_debugv8p2(const ARMISARegisters *id)
1415
-{
1416
- return FIELD_EX32(id->id_dfr0, ID_DFR0, COPDBG) >= 8;
1417
-}
1418
-
1419
-static inline bool isar_feature_aa32_doublelock(const ARMISARegisters *id)
1420
-{
1421
- return FIELD_EX32(id->dbgdevid, DBGDEVID, DOUBLELOCK) > 0;
1422
-}
1423
-
1424
-/*
1425
- * 64-bit feature tests via id registers.
1426
- */
1427
-static inline bool isar_feature_aa64_aes(const ARMISARegisters *id)
1428
-{
1429
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) != 0;
1430
-}
1431
-
1432
-static inline bool isar_feature_aa64_pmull(const ARMISARegisters *id)
1433
-{
1434
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, AES) > 1;
1435
-}
1436
-
1437
-static inline bool isar_feature_aa64_sha1(const ARMISARegisters *id)
1438
-{
1439
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA1) != 0;
1440
-}
1441
-
1442
-static inline bool isar_feature_aa64_sha256(const ARMISARegisters *id)
1443
-{
1444
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) != 0;
1445
-}
1446
-
1447
-static inline bool isar_feature_aa64_sha512(const ARMISARegisters *id)
1448
-{
1449
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA2) > 1;
1450
-}
1451
-
1452
-static inline bool isar_feature_aa64_crc32(const ARMISARegisters *id)
1453
-{
1454
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, CRC32) != 0;
1455
-}
1456
-
1457
-static inline bool isar_feature_aa64_atomics(const ARMISARegisters *id)
1458
-{
1459
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, ATOMIC) != 0;
1460
-}
1461
-
1462
-static inline bool isar_feature_aa64_rdm(const ARMISARegisters *id)
1463
-{
1464
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RDM) != 0;
1465
-}
1466
-
1467
-static inline bool isar_feature_aa64_sha3(const ARMISARegisters *id)
1468
-{
1469
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SHA3) != 0;
1470
-}
1471
-
1472
-static inline bool isar_feature_aa64_sm3(const ARMISARegisters *id)
1473
-{
1474
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM3) != 0;
1475
-}
1476
-
1477
-static inline bool isar_feature_aa64_sm4(const ARMISARegisters *id)
1478
-{
1479
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, SM4) != 0;
1480
-}
1481
-
1482
-static inline bool isar_feature_aa64_dp(const ARMISARegisters *id)
1483
-{
1484
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, DP) != 0;
1485
-}
1486
-
1487
-static inline bool isar_feature_aa64_fhm(const ARMISARegisters *id)
1488
-{
1489
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, FHM) != 0;
1490
-}
1491
-
1492
-static inline bool isar_feature_aa64_condm_4(const ARMISARegisters *id)
1493
-{
1494
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) != 0;
1495
-}
1496
-
1497
-static inline bool isar_feature_aa64_condm_5(const ARMISARegisters *id)
1498
-{
1499
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TS) >= 2;
1500
-}
1501
-
1502
-static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
1503
-{
1504
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
1505
-}
1506
-
1507
-static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
1508
-{
1509
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
1510
-}
1511
-
1512
-static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
1513
-{
1514
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
1515
-}
1516
-
1517
-/*
1518
- * These are the values from APA/API/APA3.
1519
- * In general these must be compared '>=', per the normal Arm ARM
1520
- * treatment of fields in ID registers.
1521
- */
1522
-typedef enum {
1523
- PauthFeat_None = 0,
1524
- PauthFeat_1 = 1,
1525
- PauthFeat_EPAC = 2,
1526
- PauthFeat_2 = 3,
1527
- PauthFeat_FPAC = 4,
1528
- PauthFeat_FPACCOMBINED = 5,
1529
-} ARMPauthFeature;
1530
-
1531
-static inline ARMPauthFeature
1532
-isar_feature_pauth_feature(const ARMISARegisters *id)
1533
-{
1534
- /*
1535
- * Architecturally, only one of {APA,API,APA3} may be active (non-zero)
1536
- * and the other two must be zero. Thus we may avoid conditionals.
1537
- */
1538
- return (FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) |
1539
- FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, API) |
1540
- FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3));
1541
-}
1542
-
1543
-static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
1544
-{
1545
- /*
1546
- * Return true if any form of pauth is enabled, as this
1547
- * predicate controls migration of the 128-bit keys.
1548
- */
1549
- return isar_feature_pauth_feature(id) != PauthFeat_None;
1550
-}
1551
-
1552
-static inline bool isar_feature_aa64_pauth_qarma5(const ARMISARegisters *id)
1553
-{
1554
- /*
1555
- * Return true if pauth is enabled with the architected QARMA5 algorithm.
1556
- * QEMU will always enable or disable both APA and GPA.
1557
- */
1558
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, APA) != 0;
1559
-}
1560
-
1561
-static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
1562
-{
1563
- /*
1564
- * Return true if pauth is enabled with the architected QARMA3 algorithm.
1565
- * QEMU will always enable or disable both APA3 and GPA3.
1566
- */
1567
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0;
1568
-}
1569
-
1570
-static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
1571
-{
1572
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
1573
-}
1574
-
1575
-static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
1576
-{
1577
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0;
1578
-}
1579
-
1580
-static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
1581
-{
1582
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
1583
-}
1584
-
1585
-static inline bool isar_feature_aa64_predinv(const ARMISARegisters *id)
1586
-{
1587
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SPECRES) != 0;
1588
-}
1589
-
1590
-static inline bool isar_feature_aa64_frint(const ARMISARegisters *id)
1591
-{
1592
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FRINTTS) != 0;
1593
-}
1594
-
1595
-static inline bool isar_feature_aa64_dcpop(const ARMISARegisters *id)
1596
-{
1597
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) != 0;
1598
-}
1599
-
1600
-static inline bool isar_feature_aa64_dcpodp(const ARMISARegisters *id)
1601
-{
1602
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, DPB) >= 2;
1603
-}
1604
-
1605
-static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
1606
-{
1607
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
1608
-}
1609
-
1610
-static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
1611
-{
1612
- /* We always set the AdvSIMD and FP fields identically. */
1613
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) != 0xf;
1614
-}
1615
-
1616
-static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
1617
-{
1618
- /* We always set the AdvSIMD and FP fields identically wrt FP16. */
1619
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, FP) == 1;
1620
-}
1621
-
1622
-static inline bool isar_feature_aa64_aa32(const ARMISARegisters *id)
1623
-{
1624
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL0) >= 2;
1625
-}
1626
-
1627
-static inline bool isar_feature_aa64_aa32_el1(const ARMISARegisters *id)
1628
-{
1629
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL1) >= 2;
1630
-}
1631
-
1632
-static inline bool isar_feature_aa64_aa32_el2(const ARMISARegisters *id)
1633
-{
1634
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, EL2) >= 2;
1635
-}
1636
-
1637
-static inline bool isar_feature_aa64_ras(const ARMISARegisters *id)
1638
-{
1639
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) != 0;
1640
-}
1641
-
1642
-static inline bool isar_feature_aa64_doublefault(const ARMISARegisters *id)
1643
-{
1644
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RAS) >= 2;
1645
-}
1646
-
1647
-static inline bool isar_feature_aa64_sve(const ARMISARegisters *id)
1648
-{
1649
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SVE) != 0;
1650
-}
1651
-
1652
-static inline bool isar_feature_aa64_sel2(const ARMISARegisters *id)
1653
-{
1654
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, SEL2) != 0;
1655
-}
1656
-
1657
-static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
1658
-{
1659
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
1660
-}
1661
-
1662
-static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
1663
-{
1664
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
1665
-}
1666
-
1667
-static inline bool isar_feature_aa64_lor(const ARMISARegisters *id)
1668
-{
1669
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, LO) != 0;
1670
-}
1671
-
1672
-static inline bool isar_feature_aa64_pan(const ARMISARegisters *id)
1673
-{
1674
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) != 0;
1675
-}
1676
-
1677
-static inline bool isar_feature_aa64_ats1e1(const ARMISARegisters *id)
1678
-{
1679
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 2;
1680
-}
1681
-
1682
-static inline bool isar_feature_aa64_pan3(const ARMISARegisters *id)
1683
-{
1684
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, PAN) >= 3;
1685
-}
1686
-
1687
-static inline bool isar_feature_aa64_hcx(const ARMISARegisters *id)
1688
-{
1689
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HCX) != 0;
1690
-}
1691
-
1692
-static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
1693
-{
1694
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR1, TIDCP1) != 0;
1695
-}
1696
-
1697
-static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
1698
-{
1699
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
1700
-}
1701
-
1702
-static inline bool isar_feature_aa64_st(const ARMISARegisters *id)
1703
-{
1704
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, ST) != 0;
1705
-}
1706
-
1707
-static inline bool isar_feature_aa64_lse2(const ARMISARegisters *id)
1708
-{
1709
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, AT) != 0;
1710
-}
1711
-
1712
-static inline bool isar_feature_aa64_fwb(const ARMISARegisters *id)
1713
-{
1714
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, FWB) != 0;
1715
-}
1716
-
1717
-static inline bool isar_feature_aa64_ids(const ARMISARegisters *id)
1718
-{
1719
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, IDS) != 0;
1720
-}
1721
-
1722
-static inline bool isar_feature_aa64_half_evt(const ARMISARegisters *id)
1723
-{
1724
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 1;
1725
-}
1726
-
1727
-static inline bool isar_feature_aa64_evt(const ARMISARegisters *id)
1728
-{
1729
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2;
1730
-}
1731
-
1732
-static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
1733
-{
1734
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
1735
-}
1736
-
1737
-static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
1738
-{
1739
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
1740
-}
1741
-
1742
-static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
1743
-{
1744
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
1745
-}
1746
-
1747
-static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
1748
-{
1749
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
1750
-}
1751
-
1752
-static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
1753
-{
1754
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
1755
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
1756
-}
1757
-
1758
-static inline bool isar_feature_aa64_pmuv3p4(const ARMISARegisters *id)
1759
-{
1760
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 5 &&
1761
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
1762
-}
1763
-
1764
-static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
1765
-{
1766
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 6 &&
1767
- FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
1768
-}
1769
-
1770
-static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
1771
-{
1772
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
1773
-}
1774
-
1775
-static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
1776
-{
1777
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
1778
-}
1779
-
1780
-static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
1781
-{
1782
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
1783
-}
1784
-
1785
-static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id)
1786
-{
1787
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0;
1788
-}
1789
-
1790
-static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
1791
-{
1792
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
1793
-}
1794
-
1795
-static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
1796
-{
1797
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
1798
- return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
1799
-}
1800
-
1801
-static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
1802
-{
1803
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
1804
-}
1805
-
1806
-static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
1807
-{
1808
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
1809
- return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
1810
-}
1811
-
1812
-static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
1813
-{
1814
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
1815
-}
1816
-
1817
-static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
1818
-{
1819
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
1820
-}
1821
-
1822
-static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
1823
-{
1824
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
1825
-}
1826
-
1827
-static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
1828
-{
1829
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
1830
- return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
1831
-}
1832
-
1833
-static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
1834
-{
1835
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
1836
- return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
1837
-}
1838
-
1839
-static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
1840
-{
1841
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
1842
- return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
1843
-}
1844
-
1845
-static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
1846
-{
1847
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
1848
-}
1849
-
1850
-static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
1851
-{
1852
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
1853
-}
1854
-
1855
-static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
1856
-{
1857
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
1858
-}
1859
-
1860
-static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
1861
-{
1862
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
1863
-}
1864
-
1865
-static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
1866
-{
1867
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
1868
-}
1869
-
1870
-static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
1871
-{
1872
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
1873
-}
1874
-
1875
-static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
1876
-{
1877
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
1878
-}
1879
-
1880
-static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
1881
-{
1882
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
1883
-}
1884
-
1885
-static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
1886
-{
1887
- int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
1888
- if (key >= 2) {
1889
- return true; /* FEAT_CSV2_2 */
1890
- }
1891
- if (key == 1) {
1892
- key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
1893
- return key >= 2; /* FEAT_CSV2_1p2 */
1894
- }
1895
- return false;
1896
-}
1897
-
1898
-static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
1899
-{
1900
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
1901
-}
1902
-
1903
-static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
1904
-{
1905
- return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
1906
-}
1907
-
1908
-static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
1909
-{
1910
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
1911
-}
1912
-
1913
-static inline bool isar_feature_aa64_sve2_aes(const ARMISARegisters *id)
1914
-{
1915
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) != 0;
1916
-}
1917
-
1918
-static inline bool isar_feature_aa64_sve2_pmull128(const ARMISARegisters *id)
1919
-{
1920
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, AES) >= 2;
1921
-}
1922
-
1923
-static inline bool isar_feature_aa64_sve2_bitperm(const ARMISARegisters *id)
1924
-{
1925
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BITPERM) != 0;
1926
-}
1927
-
1928
-static inline bool isar_feature_aa64_sve_bf16(const ARMISARegisters *id)
1929
-{
1930
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, BFLOAT16) != 0;
1931
-}
1932
-
1933
-static inline bool isar_feature_aa64_sve2_sha3(const ARMISARegisters *id)
1934
-{
1935
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SHA3) != 0;
1936
-}
1937
-
1938
-static inline bool isar_feature_aa64_sve2_sm4(const ARMISARegisters *id)
1939
-{
1940
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SM4) != 0;
1941
-}
1942
-
1943
-static inline bool isar_feature_aa64_sve_i8mm(const ARMISARegisters *id)
1944
-{
1945
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, I8MM) != 0;
1946
-}
1947
-
1948
-static inline bool isar_feature_aa64_sve_f32mm(const ARMISARegisters *id)
1949
-{
1950
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F32MM) != 0;
1951
-}
1952
-
1953
-static inline bool isar_feature_aa64_sve_f64mm(const ARMISARegisters *id)
1954
-{
1955
- return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, F64MM) != 0;
1956
-}
1957
-
1958
-static inline bool isar_feature_aa64_sme_f64f64(const ARMISARegisters *id)
1959
-{
1960
- return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, F64F64);
1961
-}
1962
-
1963
-static inline bool isar_feature_aa64_sme_i16i64(const ARMISARegisters *id)
1964
-{
1965
- return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, I16I64) == 0xf;
1966
-}
1967
-
1968
-static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id)
1969
-{
1970
- return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64);
1971
-}
1972
-
1973
-static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
1974
-{
1975
- return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
1976
-}
1977
-
1978
-static inline bool isar_feature_aa64_mops(const ARMISARegisters *id)
1979
-{
1980
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS);
1981
-}
1982
-
1983
-/*
1984
- * Feature tests for "does this exist in either 32-bit or 64-bit?"
1985
- */
1986
-static inline bool isar_feature_any_fp16(const ARMISARegisters *id)
1987
-{
1988
- return isar_feature_aa64_fp16(id) || isar_feature_aa32_fp16_arith(id);
1989
-}
1990
-
1991
-static inline bool isar_feature_any_predinv(const ARMISARegisters *id)
1992
-{
1993
- return isar_feature_aa64_predinv(id) || isar_feature_aa32_predinv(id);
1994
-}
1995
-
1996
-static inline bool isar_feature_any_pmuv3p1(const ARMISARegisters *id)
1997
-{
1998
- return isar_feature_aa64_pmuv3p1(id) || isar_feature_aa32_pmuv3p1(id);
1999
-}
2000
-
2001
-static inline bool isar_feature_any_pmuv3p4(const ARMISARegisters *id)
2002
-{
2003
- return isar_feature_aa64_pmuv3p4(id) || isar_feature_aa32_pmuv3p4(id);
2004
-}
2005
-
2006
-static inline bool isar_feature_any_pmuv3p5(const ARMISARegisters *id)
2007
-{
2008
- return isar_feature_aa64_pmuv3p5(id) || isar_feature_aa32_pmuv3p5(id);
2009
-}
2010
-
2011
-static inline bool isar_feature_any_ccidx(const ARMISARegisters *id)
2012
-{
2013
- return isar_feature_aa64_ccidx(id) || isar_feature_aa32_ccidx(id);
2014
-}
2015
-
2016
-static inline bool isar_feature_any_tts2uxn(const ARMISARegisters *id)
2017
-{
2018
- return isar_feature_aa64_tts2uxn(id) || isar_feature_aa32_tts2uxn(id);
2019
-}
2020
-
2021
-static inline bool isar_feature_any_debugv8p2(const ARMISARegisters *id)
2022
-{
2023
- return isar_feature_aa64_debugv8p2(id) || isar_feature_aa32_debugv8p2(id);
2024
-}
2025
-
2026
-static inline bool isar_feature_any_ras(const ARMISARegisters *id)
2027
-{
2028
- return isar_feature_aa64_ras(id) || isar_feature_aa32_ras(id);
2029
-}
2030
-
2031
-static inline bool isar_feature_any_half_evt(const ARMISARegisters *id)
2032
-{
2033
- return isar_feature_aa64_half_evt(id) || isar_feature_aa32_half_evt(id);
2034
-}
2035
-
2036
-static inline bool isar_feature_any_evt(const ARMISARegisters *id)
2037
-{
2038
- return isar_feature_aa64_evt(id) || isar_feature_aa32_evt(id);
2039
-}
2040
-
2041
-/*
2042
- * Forward to the above feature tests given an ARMCPU pointer.
2043
- */
2044
-#define cpu_isar_feature(name, cpu) \
2045
- ({ ARMCPU *cpu_ = (cpu); isar_feature_##name(&cpu_->isar); })
2046
-
2047
#endif
2048
diff --git a/target/arm/internals.h b/target/arm/internals.h
13
diff --git a/target/arm/internals.h b/target/arm/internals.h
2049
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
2050
--- a/target/arm/internals.h
15
--- a/target/arm/internals.h
2051
+++ b/target/arm/internals.h
16
+++ b/target/arm/internals.h
2052
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ FIELD(VTCR, SL2, 33, 1)
2053
#include "hw/registerfields.h"
18
#define HSTR_TTEE (1 << 16)
2054
#include "tcg/tcg-gvec-desc.h"
19
#define HSTR_TJDBX (1 << 17)
2055
#include "syndrome.h"
20
2056
+#include "cpu-features.h"
21
-#define CNTHCTL_CNTVMASK (1 << 18)
2057
22
-#define CNTHCTL_CNTPMASK (1 << 19)
2058
/* register banks for CPU modes */
23
+/*
2059
#define BANK_USRSYS 0
24
+ * Depending on the value of HCR_EL2.E2H, bits 0 and 1
2060
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
25
+ * have different bit definitions, and EL1PCTEN might be
2061
index XXXXXXX..XXXXXXX 100644
26
+ * bit 0 or bit 10. We use _E2H1 and _E2H0 suffixes to
2062
--- a/target/arm/tcg/translate.h
27
+ * disambiguate if necessary.
2063
+++ b/target/arm/tcg/translate.h
28
+ */
2064
@@ -XXX,XX +XXX,XX @@
29
+FIELD(CNTHCTL, EL0PCTEN_E2H1, 0, 1)
2065
#include "exec/translator.h"
30
+FIELD(CNTHCTL, EL0VCTEN_E2H1, 1, 1)
2066
#include "exec/helper-gen.h"
31
+FIELD(CNTHCTL, EL1PCTEN_E2H0, 0, 1)
2067
#include "internals.h"
32
+FIELD(CNTHCTL, EL1PCEN_E2H0, 1, 1)
2068
-
33
+FIELD(CNTHCTL, EVNTEN, 2, 1)
2069
+#include "cpu-features.h"
34
+FIELD(CNTHCTL, EVNTDIR, 3, 1)
2070
35
+FIELD(CNTHCTL, EVNTI, 4, 4)
2071
/* internal defines */
36
+FIELD(CNTHCTL, EL0VTEN, 8, 1)
2072
37
+FIELD(CNTHCTL, EL0PTEN, 9, 1)
2073
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
38
+FIELD(CNTHCTL, EL1PCTEN_E2H1, 10, 1)
2074
index XXXXXXX..XXXXXXX 100644
39
+FIELD(CNTHCTL, EL1PTEN, 11, 1)
2075
--- a/hw/arm/armv7m.c
40
+FIELD(CNTHCTL, ECV, 12, 1)
2076
+++ b/hw/arm/armv7m.c
41
+FIELD(CNTHCTL, EL1TVT, 13, 1)
2077
@@ -XXX,XX +XXX,XX @@
42
+FIELD(CNTHCTL, EL1TVCT, 14, 1)
2078
#include "qemu/module.h"
43
+FIELD(CNTHCTL, EL1NVPCT, 15, 1)
2079
#include "qemu/log.h"
44
+FIELD(CNTHCTL, EL1NVVCT, 16, 1)
2080
#include "target/arm/idau.h"
45
+FIELD(CNTHCTL, EVNTIS, 17, 1)
2081
+#include "target/arm/cpu-features.h"
46
+FIELD(CNTHCTL, CNTVMASK, 18, 1)
2082
#include "migration/vmstate.h"
47
+FIELD(CNTHCTL, CNTPMASK, 19, 1)
2083
48
2084
/* Bitbanded IO. Each word corresponds to a single bit. */
49
/* We use a few fake FSR values for internal purposes in M profile.
2085
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
50
* M profile cores don't have A/R format FSRs, but currently our
2086
index XXXXXXX..XXXXXXX 100644
2087
--- a/hw/intc/armv7m_nvic.c
2088
+++ b/hw/intc/armv7m_nvic.c
2089
@@ -XXX,XX +XXX,XX @@
2090
#include "sysemu/tcg.h"
2091
#include "sysemu/runstate.h"
2092
#include "target/arm/cpu.h"
2093
+#include "target/arm/cpu-features.h"
2094
#include "exec/exec-all.h"
2095
#include "exec/memop.h"
2096
#include "qemu/log.h"
2097
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
2098
index XXXXXXX..XXXXXXX 100644
2099
--- a/linux-user/aarch64/cpu_loop.c
2100
+++ b/linux-user/aarch64/cpu_loop.c
2101
@@ -XXX,XX +XXX,XX @@
2102
#include "qemu/guest-random.h"
2103
#include "semihosting/common-semi.h"
2104
#include "target/arm/syndrome.h"
2105
+#include "target/arm/cpu-features.h"
2106
2107
#define get_user_code_u32(x, gaddr, env) \
2108
({ abi_long __r = get_user_u32((x), (gaddr)); \
2109
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
2110
index XXXXXXX..XXXXXXX 100644
2111
--- a/linux-user/aarch64/signal.c
2112
+++ b/linux-user/aarch64/signal.c
2113
@@ -XXX,XX +XXX,XX @@
2114
#include "user-internals.h"
2115
#include "signal-common.h"
2116
#include "linux-user/trace.h"
2117
+#include "target/arm/cpu-features.h"
2118
2119
struct target_sigcontext {
2120
uint64_t fault_address;
2121
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
2122
index XXXXXXX..XXXXXXX 100644
2123
--- a/linux-user/arm/signal.c
2124
+++ b/linux-user/arm/signal.c
2125
@@ -XXX,XX +XXX,XX @@
2126
#include "user-internals.h"
2127
#include "signal-common.h"
2128
#include "linux-user/trace.h"
2129
+#include "target/arm/cpu-features.h"
2130
2131
struct target_sigcontext {
2132
abi_ulong trap_no;
2133
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
2134
index XXXXXXX..XXXXXXX 100644
2135
--- a/linux-user/elfload.c
2136
+++ b/linux-user/elfload.c
2137
@@ -XXX,XX +XXX,XX @@
2138
#include "target_signal.h"
2139
#include "accel/tcg/debuginfo.h"
2140
2141
+#ifdef TARGET_ARM
2142
+#include "target/arm/cpu-features.h"
2143
+#endif
2144
+
2145
#ifdef _ARCH_PPC64
2146
#undef ARCH_DLINFO
2147
#undef ELF_PLATFORM
2148
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
2149
index XXXXXXX..XXXXXXX 100644
2150
--- a/linux-user/mmap.c
2151
+++ b/linux-user/mmap.c
2152
@@ -XXX,XX +XXX,XX @@
2153
#include "target_mman.h"
2154
#include "qemu/interval-tree.h"
2155
2156
+#ifdef TARGET_ARM
2157
+#include "target/arm/cpu-features.h"
2158
+#endif
2159
+
2160
static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
2161
static __thread int mmap_lock_count;
2162
2163
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
2164
index XXXXXXX..XXXXXXX 100644
2165
--- a/target/arm/arch_dump.c
2166
+++ b/target/arm/arch_dump.c
2167
@@ -XXX,XX +XXX,XX @@
2168
#include "cpu.h"
2169
#include "elf.h"
2170
#include "sysemu/dump.h"
2171
+#include "cpu-features.h"
2172
2173
/* struct user_pt_regs from arch/arm64/include/uapi/asm/ptrace.h */
2174
struct aarch64_user_regs {
2175
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
2176
index XXXXXXX..XXXXXXX 100644
2177
--- a/target/arm/cpu.c
2178
+++ b/target/arm/cpu.c
2179
@@ -XXX,XX +XXX,XX @@
2180
#include "hw/core/tcg-cpu-ops.h"
2181
#endif /* CONFIG_TCG */
2182
#include "internals.h"
2183
+#include "cpu-features.h"
2184
#include "exec/exec-all.h"
2185
#include "hw/qdev-properties.h"
2186
#if !defined(CONFIG_USER_ONLY)
2187
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
2188
index XXXXXXX..XXXXXXX 100644
2189
--- a/target/arm/cpu64.c
2190
+++ b/target/arm/cpu64.c
2191
@@ -XXX,XX +XXX,XX @@
2192
#include "qapi/visitor.h"
2193
#include "hw/qdev-properties.h"
2194
#include "internals.h"
2195
+#include "cpu-features.h"
2196
#include "cpregs.h"
2197
2198
void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
2199
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
2200
index XXXXXXX..XXXXXXX 100644
2201
--- a/target/arm/debug_helper.c
2202
+++ b/target/arm/debug_helper.c
2203
@@ -XXX,XX +XXX,XX @@
2204
#include "qemu/log.h"
2205
#include "cpu.h"
2206
#include "internals.h"
2207
+#include "cpu-features.h"
2208
#include "cpregs.h"
2209
#include "exec/exec-all.h"
2210
#include "exec/helper-proto.h"
2211
diff --git a/target/arm/gdbstub.c b/target/arm/gdbstub.c
2212
index XXXXXXX..XXXXXXX 100644
2213
--- a/target/arm/gdbstub.c
2214
+++ b/target/arm/gdbstub.c
2215
@@ -XXX,XX +XXX,XX @@
2216
#include "gdbstub/helpers.h"
2217
#include "sysemu/tcg.h"
2218
#include "internals.h"
2219
+#include "cpu-features.h"
2220
#include "cpregs.h"
2221
2222
typedef struct RegisterSysregXmlParam {
2223
diff --git a/target/arm/helper.c b/target/arm/helper.c
51
diff --git a/target/arm/helper.c b/target/arm/helper.c
2224
index XXXXXXX..XXXXXXX 100644
52
index XXXXXXX..XXXXXXX 100644
2225
--- a/target/arm/helper.c
53
--- a/target/arm/helper.c
2226
+++ b/target/arm/helper.c
54
+++ b/target/arm/helper.c
2227
@@ -XXX,XX +XXX,XX @@
55
@@ -XXX,XX +XXX,XX @@ static void gt_update_irq(ARMCPU *cpu, int timeridx)
2228
#include "trace.h"
56
* It is RES0 in Secure and NonSecure state.
2229
#include "cpu.h"
57
*/
2230
#include "internals.h"
58
if ((ss == ARMSS_Root || ss == ARMSS_Realm) &&
2231
+#include "cpu-features.h"
59
- ((timeridx == GTIMER_VIRT && (cnthctl & CNTHCTL_CNTVMASK)) ||
2232
#include "exec/helper-proto.h"
60
- (timeridx == GTIMER_PHYS && (cnthctl & CNTHCTL_CNTPMASK)))) {
2233
#include "qemu/main-loop.h"
61
+ ((timeridx == GTIMER_VIRT && (cnthctl & R_CNTHCTL_CNTVMASK_MASK)) ||
2234
#include "qemu/timer.h"
62
+ (timeridx == GTIMER_PHYS && (cnthctl & R_CNTHCTL_CNTPMASK_MASK)))) {
2235
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
63
irqstate = 0;
2236
index XXXXXXX..XXXXXXX 100644
64
}
2237
--- a/target/arm/kvm64.c
65
2238
+++ b/target/arm/kvm64.c
66
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
2239
@@ -XXX,XX +XXX,XX @@
67
{
2240
#include "sysemu/kvm_int.h"
68
ARMCPU *cpu = env_archcpu(env);
2241
#include "kvm_arm.h"
69
uint32_t oldval = env->cp15.cnthctl_el2;
2242
#include "internals.h"
70
-
2243
+#include "cpu-features.h"
71
raw_write(env, ri, value);
2244
#include "hw/acpi/acpi.h"
72
2245
#include "hw/acpi/ghes.h"
73
- if ((oldval ^ value) & CNTHCTL_CNTVMASK) {
2246
74
+ if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
2247
diff --git a/target/arm/machine.c b/target/arm/machine.c
75
gt_update_irq(cpu, GTIMER_VIRT);
2248
index XXXXXXX..XXXXXXX 100644
76
- } else if ((oldval ^ value) & CNTHCTL_CNTPMASK) {
2249
--- a/target/arm/machine.c
77
+ } else if ((oldval ^ value) & R_CNTHCTL_CNTPMASK_MASK) {
2250
+++ b/target/arm/machine.c
78
gt_update_irq(cpu, GTIMER_PHYS);
2251
@@ -XXX,XX +XXX,XX @@
79
}
2252
#include "sysemu/tcg.h"
80
}
2253
#include "kvm_arm.h"
2254
#include "internals.h"
2255
+#include "cpu-features.h"
2256
#include "migration/cpu.h"
2257
2258
static bool vfp_needed(void *opaque)
2259
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
2260
index XXXXXXX..XXXXXXX 100644
2261
--- a/target/arm/ptw.c
2262
+++ b/target/arm/ptw.c
2263
@@ -XXX,XX +XXX,XX @@
2264
#include "exec/exec-all.h"
2265
#include "cpu.h"
2266
#include "internals.h"
2267
+#include "cpu-features.h"
2268
#include "idau.h"
2269
#ifdef CONFIG_TCG
2270
# include "tcg/oversized-guest.h"
2271
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
2272
index XXXXXXX..XXXXXXX 100644
2273
--- a/target/arm/tcg/cpu64.c
2274
+++ b/target/arm/tcg/cpu64.c
2275
@@ -XXX,XX +XXX,XX @@
2276
#include "hw/qdev-properties.h"
2277
#include "qemu/units.h"
2278
#include "internals.h"
2279
+#include "cpu-features.h"
2280
#include "cpregs.h"
2281
2282
static uint64_t make_ccsidr64(unsigned assoc, unsigned linesize,
2283
diff --git a/target/arm/tcg/hflags.c b/target/arm/tcg/hflags.c
2284
index XXXXXXX..XXXXXXX 100644
2285
--- a/target/arm/tcg/hflags.c
2286
+++ b/target/arm/tcg/hflags.c
2287
@@ -XXX,XX +XXX,XX @@
2288
#include "qemu/osdep.h"
2289
#include "cpu.h"
2290
#include "internals.h"
2291
+#include "cpu-features.h"
2292
#include "exec/helper-proto.h"
2293
#include "cpregs.h"
2294
2295
diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c
2296
index XXXXXXX..XXXXXXX 100644
2297
--- a/target/arm/tcg/m_helper.c
2298
+++ b/target/arm/tcg/m_helper.c
2299
@@ -XXX,XX +XXX,XX @@
2300
#include "qemu/osdep.h"
2301
#include "cpu.h"
2302
#include "internals.h"
2303
+#include "cpu-features.h"
2304
#include "gdbstub/helpers.h"
2305
#include "exec/helper-proto.h"
2306
#include "qemu/main-loop.h"
2307
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
2308
index XXXXXXX..XXXXXXX 100644
2309
--- a/target/arm/tcg/op_helper.c
2310
+++ b/target/arm/tcg/op_helper.c
2311
@@ -XXX,XX +XXX,XX @@
2312
#include "cpu.h"
2313
#include "exec/helper-proto.h"
2314
#include "internals.h"
2315
+#include "cpu-features.h"
2316
#include "exec/exec-all.h"
2317
#include "exec/cpu_ldst.h"
2318
#include "cpregs.h"
2319
diff --git a/target/arm/tcg/pauth_helper.c b/target/arm/tcg/pauth_helper.c
2320
index XXXXXXX..XXXXXXX 100644
2321
--- a/target/arm/tcg/pauth_helper.c
2322
+++ b/target/arm/tcg/pauth_helper.c
2323
@@ -XXX,XX +XXX,XX @@
2324
#include "qemu/osdep.h"
2325
#include "cpu.h"
2326
#include "internals.h"
2327
+#include "cpu-features.h"
2328
#include "exec/exec-all.h"
2329
#include "exec/cpu_ldst.h"
2330
#include "exec/helper-proto.h"
2331
diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c
2332
index XXXXXXX..XXXXXXX 100644
2333
--- a/target/arm/tcg/tlb_helper.c
2334
+++ b/target/arm/tcg/tlb_helper.c
2335
@@ -XXX,XX +XXX,XX @@
2336
#include "qemu/osdep.h"
2337
#include "cpu.h"
2338
#include "internals.h"
2339
+#include "cpu-features.h"
2340
#include "exec/exec-all.h"
2341
#include "exec/helper-proto.h"
2342
2343
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
2344
index XXXXXXX..XXXXXXX 100644
2345
--- a/target/arm/vfp_helper.c
2346
+++ b/target/arm/vfp_helper.c
2347
@@ -XXX,XX +XXX,XX @@
2348
#include "cpu.h"
2349
#include "exec/helper-proto.h"
2350
#include "internals.h"
2351
+#include "cpu-features.h"
2352
#ifdef CONFIG_TCG
2353
#include "qemu/log.h"
2354
#include "fpu/softfloat.h"
2355
--
81
--
2356
2.34.1
82
2.34.1
2357
83
2358
84
diff view generated by jsdifflib
1
From: Luc Michel <luc.michel@amd.com>
1
Don't allow the guest to write CNTHCTL_EL2 bits which don't exist.
2
This is not strictly architecturally required, but it is how we've
3
tended to implement registers more recently.
2
4
3
The MDIO access is done only on a write to the PHYMNTNC register. A
5
In particular, bits [19:18] are only present with FEAT_RME,
4
subsequent read is used to retrieve the result but does not trigger an
6
and bits [17:12] will only be present with FEAT_ECV.
5
MDIO access by itself.
6
7
7
Refactor the PHY access logic to perform all accesses (MDIO reads and
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
writes) at PHYMNTNC write time.
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20240301183219.2424889-5-peter.maydell@linaro.org
11
---
12
target/arm/helper.c | 18 ++++++++++++++++++
13
1 file changed, 18 insertions(+)
9
14
10
Signed-off-by: Luc Michel <luc.michel@amd.com>
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
11
Reviewed-by: sai.pavan.boddu@amd.com
12
Message-id: 20231017194422.4124691-11-luc.michel@amd.com
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
---
15
hw/net/cadence_gem.c | 56 ++++++++++++++++++++++++++------------------
16
1 file changed, 33 insertions(+), 23 deletions(-)
17
18
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/hw/net/cadence_gem.c
17
--- a/target/arm/helper.c
21
+++ b/hw/net/cadence_gem.c
18
+++ b/target/arm/helper.c
22
@@ -XXX,XX +XXX,XX @@ static void gem_phy_write(CadenceGEMState *s, unsigned reg_num, uint16_t val)
19
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
23
s->phy_regs[reg_num] = val;
20
{
24
}
21
ARMCPU *cpu = env_archcpu(env);
25
22
uint32_t oldval = env->cp15.cnthctl_el2;
26
+static void gem_handle_phy_access(CadenceGEMState *s)
23
+ uint32_t valid_mask =
27
+{
24
+ R_CNTHCTL_EL0PCTEN_E2H1_MASK |
28
+ uint32_t val = s->regs[R_PHYMNTNC];
25
+ R_CNTHCTL_EL0VCTEN_E2H1_MASK |
29
+ uint32_t phy_addr, reg_num;
26
+ R_CNTHCTL_EVNTEN_MASK |
27
+ R_CNTHCTL_EVNTDIR_MASK |
28
+ R_CNTHCTL_EVNTI_MASK |
29
+ R_CNTHCTL_EL0VTEN_MASK |
30
+ R_CNTHCTL_EL0PTEN_MASK |
31
+ R_CNTHCTL_EL1PCTEN_E2H1_MASK |
32
+ R_CNTHCTL_EL1PTEN_MASK;
30
+
33
+
31
+ phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR);
34
+ if (cpu_isar_feature(aa64_rme, cpu)) {
32
+
35
+ valid_mask |= R_CNTHCTL_CNTVMASK_MASK | R_CNTHCTL_CNTPMASK_MASK;
33
+ if (phy_addr != s->phy_addr) {
34
+ /* no phy at this address */
35
+ if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_READ) {
36
+ s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA, 0xffff);
37
+ }
38
+ return;
39
+ }
36
+ }
40
+
37
+
41
+ reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR);
38
+ /* Clear RES0 bits */
39
+ value &= valid_mask;
42
+
40
+
43
+ switch (FIELD_EX32(val, PHYMNTNC, OP)) {
41
raw_write(env, ri, value);
44
+ case MDIO_OP_READ:
42
45
+ s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA,
43
if ((oldval ^ value) & R_CNTHCTL_CNTVMASK_MASK) {
46
+ gem_phy_read(s, reg_num));
47
+ break;
48
+
49
+ case MDIO_OP_WRITE:
50
+ gem_phy_write(s, reg_num, val);
51
+ break;
52
+
53
+ default:
54
+ break; /* only clause 22 operations are supported */
55
+ }
56
+}
57
+
58
/*
59
* gem_read32:
60
* Read a GEM register.
61
@@ -XXX,XX +XXX,XX @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
62
DB_PRINT("lowering irqs on ISR read\n");
63
/* The interrupts get updated at the end of the function. */
64
break;
65
- case R_PHYMNTNC:
66
- if (FIELD_EX32(retval, PHYMNTNC, OP) == MDIO_OP_READ) {
67
- uint32_t phy_addr, reg_num;
68
-
69
- phy_addr = FIELD_EX32(retval, PHYMNTNC, PHY_ADDR);
70
- if (phy_addr == s->phy_addr) {
71
- reg_num = FIELD_EX32(retval, PHYMNTNC, REG_ADDR);
72
- retval &= 0xFFFF0000;
73
- retval |= gem_phy_read(s, reg_num);
74
- } else {
75
- retval |= 0xFFFF; /* No device at this address */
76
- }
77
- }
78
- break;
79
}
80
81
/* Squash read to clear bits */
82
@@ -XXX,XX +XXX,XX @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
83
s->sar_active[(offset - R_SPADDR1HI) / 2] = true;
84
break;
85
case R_PHYMNTNC:
86
- if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_WRITE) {
87
- uint32_t phy_addr, reg_num;
88
-
89
- phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR);
90
- if (phy_addr == s->phy_addr) {
91
- reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR);
92
- gem_phy_write(s, reg_num, val);
93
- }
94
- }
95
+ gem_handle_phy_access(s);
96
break;
97
}
98
99
--
44
--
100
2.34.1
45
2.34.1
diff view generated by jsdifflib
1
Move the ID_AA64MMFR0 feature test functions up so they are
1
The functionality defined by ID_AA64MMFR0_EL1.ECV == 1 is:
2
before the ones for ID_AA64MMFR1 and ID_AA64MMFR2.
2
* four new trap bits for various counter and timer registers
3
* the CNTHCTL_EL2.EVNTIS and CNTKCTL_EL1.EVNTIS bits which control
4
scaling of the event stream. This is a no-op for us, because we don't
5
implement the event stream (our WFE is a NOP): all we need to do is
6
allow CNTHCTL_EL2.ENVTIS to be read and written.
7
* extensions to PMSCR_EL1.PCT, PMSCR_EL2.PCT, TRFCR_EL1.TS and
8
TRFCR_EL2.TS: these are all no-ops for us, because we don't implement
9
FEAT_SPE or FEAT_TRF.
10
* new registers CNTPCTSS_EL0 and NCTVCTSS_EL0 which are
11
"self-sychronizing" views of the CNTPCT_EL0 and CNTVCT_EL0, meaning
12
that no barriers are needed around their accesses. For us these
13
are just the same as the normal views, because all our sysregs are
14
inherently self-sychronizing.
15
16
In this commit we implement the trap handling and permit the new
17
CNTHCTL_EL2 bits to be written.
3
18
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20231024163510.2972081-4-peter.maydell@linaro.org
21
Message-id: 20240301183219.2424889-6-peter.maydell@linaro.org
8
---
22
---
9
target/arm/cpu-features.h | 120 +++++++++++++++++++-------------------
23
target/arm/cpu-features.h | 5 ++++
10
1 file changed, 60 insertions(+), 60 deletions(-)
24
target/arm/helper.c | 51 +++++++++++++++++++++++++++++++++++----
25
2 files changed, 51 insertions(+), 5 deletions(-)
11
26
12
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
27
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
13
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu-features.h
29
--- a/target/arm/cpu-features.h
15
+++ b/target/arm/cpu-features.h
30
+++ b/target/arm/cpu-features.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
31
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
17
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
32
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
18
}
33
}
19
34
20
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
35
+static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
21
+{
36
+{
22
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
37
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
23
+}
24
+
25
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
26
+{
27
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
28
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
29
+}
30
+
31
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
32
+{
33
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
34
+}
35
+
36
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
37
+{
38
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
39
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
40
+}
41
+
42
+static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
43
+{
44
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
45
+}
46
+
47
+static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
48
+{
49
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
50
+}
51
+
52
+static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
53
+{
54
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
55
+}
56
+
57
+static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
58
+{
59
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
60
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
61
+}
62
+
63
+static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
64
+{
65
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
66
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
67
+}
68
+
69
+static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
70
+{
71
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
72
+ return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
73
+}
74
+
75
+static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
76
+{
77
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
78
+}
38
+}
79
+
39
+
80
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
40
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
81
{
41
{
82
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
42
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
83
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id)
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
84
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0;
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_counter_access(CPUARMState *env, int timeridx,
48
: !extract32(env->cp15.cnthctl_el2, 0, 1))) {
49
return CP_ACCESS_TRAP_EL2;
50
}
51
+ if (has_el2 && timeridx == GTIMER_VIRT) {
52
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVCT)) {
53
+ return CP_ACCESS_TRAP_EL2;
54
+ }
55
+ }
56
break;
57
}
58
return CP_ACCESS_OK;
59
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_timer_access(CPUARMState *env, int timeridx,
60
}
61
}
62
}
63
+ if (has_el2 && timeridx == GTIMER_VIRT) {
64
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1TVT)) {
65
+ return CP_ACCESS_TRAP_EL2;
66
+ }
67
+ }
68
break;
69
}
70
return CP_ACCESS_OK;
71
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
72
if (cpu_isar_feature(aa64_rme, cpu)) {
73
valid_mask |= R_CNTHCTL_CNTVMASK_MASK | R_CNTHCTL_CNTPMASK_MASK;
74
}
75
+ if (cpu_isar_feature(aa64_ecv_traps, cpu)) {
76
+ valid_mask |=
77
+ R_CNTHCTL_EL1TVT_MASK |
78
+ R_CNTHCTL_EL1TVCT_MASK |
79
+ R_CNTHCTL_EL1NVPCT_MASK |
80
+ R_CNTHCTL_EL1NVVCT_MASK |
81
+ R_CNTHCTL_EVNTIS_MASK;
82
+ }
83
84
/* Clear RES0 bits */
85
value &= valid_mask;
86
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
87
{
88
if (arm_current_el(env) == 1) {
89
/* This must be a FEAT_NV access */
90
- /* TODO: FEAT_ECV will need to check CNTHCTL_EL2 here */
91
return CP_ACCESS_OK;
92
}
93
if (!(arm_hcr_el2_eff(env) & HCR_E2H)) {
94
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
95
return CP_ACCESS_OK;
85
}
96
}
86
97
87
-static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
98
+static CPAccessResult access_el1nvpct(CPUARMState *env, const ARMCPRegInfo *ri,
88
-{
99
+ bool isread)
89
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
100
+{
90
-}
101
+ if (arm_current_el(env) == 1) {
91
-
102
+ /* This must be a FEAT_NV access with NVx == 101 */
92
-static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
103
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1NVPCT)) {
93
-{
104
+ return CP_ACCESS_TRAP_EL2;
94
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
105
+ }
95
- return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
106
+ }
96
-}
107
+ return e2h_access(env, ri, isread);
97
-
108
+}
98
-static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
109
+
99
-{
110
+static CPAccessResult access_el1nvvct(CPUARMState *env, const ARMCPRegInfo *ri,
100
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
111
+ bool isread)
101
-}
112
+{
102
-
113
+ if (arm_current_el(env) == 1) {
103
-static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
114
+ /* This must be a FEAT_NV access with NVx == 101 */
104
-{
115
+ if (FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, EL1NVVCT)) {
105
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
116
+ return CP_ACCESS_TRAP_EL2;
106
- return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
117
+ }
107
-}
118
+ }
108
-
119
+ return e2h_access(env, ri, isread);
109
-static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
120
+}
110
-{
121
+
111
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
122
/* Test if system register redirection is to occur in the current state. */
112
-}
123
static bool redirect_for_e2h(CPUARMState *env)
113
-
114
-static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
115
-{
116
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
117
-}
118
-
119
-static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
120
-{
121
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
122
-}
123
-
124
-static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
125
-{
126
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
127
- return t >= 2 || (t == 0 && isar_feature_aa64_tgran4(id));
128
-}
129
-
130
-static inline bool isar_feature_aa64_tgran16_2(const ARMISARegisters *id)
131
-{
132
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
133
- return t >= 2 || (t == 0 && isar_feature_aa64_tgran16(id));
134
-}
135
-
136
-static inline bool isar_feature_aa64_tgran64_2(const ARMISARegisters *id)
137
-{
138
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64_2);
139
- return t >= 2 || (t == 0 && isar_feature_aa64_tgran64(id));
140
-}
141
-
142
-static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
143
-{
144
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
145
-}
146
-
147
static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
148
{
124
{
149
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
125
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
126
{ .name = "CNTP_CTL_EL02", .state = ARM_CP_STATE_AA64,
127
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 2, .opc2 = 1,
128
.type = ARM_CP_IO | ARM_CP_ALIAS,
129
- .access = PL2_RW, .accessfn = e2h_access,
130
+ .access = PL2_RW, .accessfn = access_el1nvpct,
131
.nv2_redirect_offset = 0x180 | NV2_REDIR_NO_NV1,
132
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].ctl),
133
.writefn = gt_phys_ctl_write, .raw_writefn = raw_write },
134
{ .name = "CNTV_CTL_EL02", .state = ARM_CP_STATE_AA64,
135
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 1,
136
.type = ARM_CP_IO | ARM_CP_ALIAS,
137
- .access = PL2_RW, .accessfn = e2h_access,
138
+ .access = PL2_RW, .accessfn = access_el1nvvct,
139
.nv2_redirect_offset = 0x170 | NV2_REDIR_NO_NV1,
140
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].ctl),
141
.writefn = gt_virt_ctl_write, .raw_writefn = raw_write },
142
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vhe_reginfo[] = {
143
.type = ARM_CP_IO | ARM_CP_ALIAS,
144
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_PHYS].cval),
145
.nv2_redirect_offset = 0x178 | NV2_REDIR_NO_NV1,
146
- .access = PL2_RW, .accessfn = e2h_access,
147
+ .access = PL2_RW, .accessfn = access_el1nvpct,
148
.writefn = gt_phys_cval_write, .raw_writefn = raw_write },
149
{ .name = "CNTV_CVAL_EL02", .state = ARM_CP_STATE_AA64,
150
.opc0 = 3, .opc1 = 5, .crn = 14, .crm = 3, .opc2 = 2,
151
.type = ARM_CP_IO | ARM_CP_ALIAS,
152
.nv2_redirect_offset = 0x168 | NV2_REDIR_NO_NV1,
153
.fieldoffset = offsetof(CPUARMState, cp15.c14_timer[GTIMER_VIRT].cval),
154
- .access = PL2_RW, .accessfn = e2h_access,
155
+ .access = PL2_RW, .accessfn = access_el1nvvct,
156
.writefn = gt_virt_cval_write, .raw_writefn = raw_write },
157
#endif
158
};
150
--
159
--
151
2.34.1
160
2.34.1
152
153
diff view generated by jsdifflib
1
In commit 442c9d682c94fc2 when we converted the ERET, ERETAA, ERETAB
1
For FEAT_ECV, new registers CNTPCTSS_EL0 and CNTVCTSS_EL0 are
2
instructions to decodetree, the conversion accidentally lost the
2
defined, which are "self-synchronized" views of the physical and
3
correct setting of the syndrome register when taking a trap because
3
virtual counts as seen in the CNTPCT_EL0 and CNTVCT_EL0 registers
4
of the FEAT_FGT HFGITR_EL1.ERET bit. Instead of reporting a correct
4
(meaning that no barriers are needed around accesses to them to
5
full syndrome value with the EC and IL bits, we only reported the low
5
ensure that reads of them do not occur speculatively and out-of-order
6
two bits of the syndrome, because the call to syn_erettrap() got
6
with other instructions).
7
dropped.
8
7
9
Fix the syndrome values for these traps by reinstating the
8
For QEMU, all our system registers are self-synchronized, so we can
10
syn_erettrap() calls.
9
simply copy the existing implementation of CNTPCT_EL0 and CNTVCT_EL0
10
to the new register encodings.
11
11
12
Fixes: 442c9d682c94fc2 ("target/arm: Convert ERET, ERETAA, ERETAB to decodetree")
12
This means we now implement all the functionality required for
13
Cc: qemu-stable@nongnu.org
13
ID_AA64MMFR0_EL1.ECV == 0b0001.
14
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20231024172438.2990945-1-peter.maydell@linaro.org
17
Message-id: 20240301183219.2424889-7-peter.maydell@linaro.org
17
---
18
---
18
target/arm/tcg/translate-a64.c | 4 ++--
19
target/arm/helper.c | 43 +++++++++++++++++++++++++++++++++++++++++++
19
1 file changed, 2 insertions(+), 2 deletions(-)
20
1 file changed, 43 insertions(+)
20
21
21
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/tcg/translate-a64.c
24
--- a/target/arm/helper.c
24
+++ b/target/arm/tcg/translate-a64.c
25
+++ b/target/arm/helper.c
25
@@ -XXX,XX +XXX,XX @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
26
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
26
return false;
27
},
28
};
29
30
+/*
31
+ * FEAT_ECV adds extra views of CNTVCT_EL0 and CNTPCT_EL0 which
32
+ * are "self-synchronizing". For QEMU all sysregs are self-synchronizing,
33
+ * so our implementations here are identical to the normal registers.
34
+ */
35
+static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
36
+ { .name = "CNTVCTSS", .cp = 15, .crm = 14, .opc1 = 9,
37
+ .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
38
+ .accessfn = gt_vct_access,
39
+ .readfn = gt_virt_cnt_read, .resetfn = arm_cp_reset_ignore,
40
+ },
41
+ { .name = "CNTVCTSS_EL0", .state = ARM_CP_STATE_AA64,
42
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 6,
43
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
44
+ .accessfn = gt_vct_access, .readfn = gt_virt_cnt_read,
45
+ },
46
+ { .name = "CNTPCTSS", .cp = 15, .crm = 14, .opc1 = 8,
47
+ .access = PL0_R, .type = ARM_CP_64BIT | ARM_CP_NO_RAW | ARM_CP_IO,
48
+ .accessfn = gt_pct_access,
49
+ .readfn = gt_cnt_read, .resetfn = arm_cp_reset_ignore,
50
+ },
51
+ { .name = "CNTPCTSS_EL0", .state = ARM_CP_STATE_AA64,
52
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 5,
53
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
54
+ .accessfn = gt_pct_access, .readfn = gt_cnt_read,
55
+ },
56
+};
57
+
58
#else
59
60
/*
61
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
62
},
63
};
64
65
+/*
66
+ * CNTVCTSS_EL0 has the same trap conditions as CNTVCT_EL0, so it also
67
+ * is exposed to userspace by Linux.
68
+ */
69
+static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
70
+ { .name = "CNTVCTSS_EL0", .state = ARM_CP_STATE_AA64,
71
+ .opc0 = 3, .opc1 = 3, .crn = 14, .crm = 0, .opc2 = 6,
72
+ .access = PL0_R, .type = ARM_CP_NO_RAW | ARM_CP_IO,
73
+ .readfn = gt_virt_cnt_read,
74
+ },
75
+};
76
+
77
#endif
78
79
static void par_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
80
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
81
if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
82
define_arm_cp_regs(cpu, generic_timer_cp_reginfo);
27
}
83
}
28
if (s->fgt_eret) {
84
+ if (cpu_isar_feature(aa64_ecv_traps, cpu)) {
29
- gen_exception_insn_el(s, 0, EXCP_UDEF, 0, 2);
85
+ define_arm_cp_regs(cpu, gen_timer_ecv_cp_reginfo);
30
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(0), 2);
86
+ }
31
return true;
87
if (arm_feature(env, ARM_FEATURE_VAPA)) {
32
}
88
ARMCPRegInfo vapa_cp_reginfo[] = {
33
dst = tcg_temp_new_i64();
89
{ .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
34
@@ -XXX,XX +XXX,XX @@ static bool trans_ERETA(DisasContext *s, arg_reta *a)
35
}
36
/* The FGT trap takes precedence over an auth trap. */
37
if (s->fgt_eret) {
38
- gen_exception_insn_el(s, 0, EXCP_UDEF, a->m ? 3 : 2, 2);
39
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(a->m ? 3 : 2), 2);
40
return true;
41
}
42
dst = tcg_temp_new_i64();
43
--
90
--
44
2.34.1
91
2.34.1
diff view generated by jsdifflib
1
Our list of isar_feature functions is not in any particular order,
1
When ID_AA64MMFR0_EL1.ECV is 0b0010, a new register CNTPOFF_EL2 is
2
but tests on fields of the same ID register tend to be grouped
2
implemented. This is similar to the existing CNTVOFF_EL2, except
3
together. A few functions that are tests of fields in ID_AA64MMFR1
3
that it controls a hypervisor-adjustable offset made to the physical
4
and ID_AA64MMFR2 are not in the same place as the rest; move them
4
counter and timer.
5
into their groups.
5
6
Implement the handling for this register, which includes control/trap
7
bits in SCR_EL3 and CNTHCTL_EL2.
6
8
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20231024163510.2972081-3-peter.maydell@linaro.org
11
Message-id: 20240301183219.2424889-8-peter.maydell@linaro.org
11
---
12
---
12
target/arm/cpu-features.h | 60 +++++++++++++++++++--------------------
13
target/arm/cpu-features.h | 5 +++
13
1 file changed, 30 insertions(+), 30 deletions(-)
14
target/arm/cpu.h | 1 +
15
target/arm/helper.c | 68 +++++++++++++++++++++++++++++++++++++--
16
target/arm/trace-events | 1 +
17
4 files changed, 73 insertions(+), 2 deletions(-)
14
18
15
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
19
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
16
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu-features.h
21
--- a/target/arm/cpu-features.h
18
+++ b/target/arm/cpu-features.h
22
+++ b/target/arm/cpu-features.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
23
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_ecv_traps(const ARMISARegisters *id)
20
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR1, TIDCP1) != 0;
24
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 0;
21
}
25
}
22
26
23
+static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
27
+static inline bool isar_feature_aa64_ecv(const ARMISARegisters *id)
24
+{
28
+{
25
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
29
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, ECV) > 1;
26
+}
30
+}
27
+
31
+
28
+static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
32
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
33
{
34
return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, VH) != 0;
35
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/cpu.h
38
+++ b/target/arm/cpu.h
39
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
40
uint64_t c14_cntkctl; /* Timer Control register */
41
uint64_t cnthctl_el2; /* Counter/Timer Hyp Control register */
42
uint64_t cntvoff_el2; /* Counter Virtual Offset register */
43
+ uint64_t cntpoff_el2; /* Counter Physical Offset register */
44
ARMGenericTimer c14_timer[NUM_GTIMERS];
45
uint32_t c15_cpar; /* XScale Coprocessor Access Register */
46
uint32_t c15_ticonfig; /* TI925T configuration byte. */
47
diff --git a/target/arm/helper.c b/target/arm/helper.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/target/arm/helper.c
50
+++ b/target/arm/helper.c
51
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
52
if (cpu_isar_feature(aa64_rme, cpu)) {
53
valid_mask |= SCR_NSE | SCR_GPF;
54
}
55
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
56
+ valid_mask |= SCR_ECVEN;
57
+ }
58
} else {
59
valid_mask &= ~(SCR_RW | SCR_ST);
60
if (cpu_isar_feature(aa32_ras, cpu)) {
61
@@ -XXX,XX +XXX,XX @@ void gt_rme_post_el_change(ARMCPU *cpu, void *ignored)
62
gt_update_irq(cpu, GTIMER_PHYS);
63
}
64
65
+static uint64_t gt_phys_raw_cnt_offset(CPUARMState *env)
29
+{
66
+{
30
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
67
+ if ((env->cp15.scr_el3 & SCR_ECVEN) &&
68
+ FIELD_EX64(env->cp15.cnthctl_el2, CNTHCTL, ECV) &&
69
+ arm_is_el2_enabled(env) &&
70
+ (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
71
+ return env->cp15.cntpoff_el2;
72
+ }
73
+ return 0;
31
+}
74
+}
32
+
75
+
33
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
76
+static uint64_t gt_phys_cnt_offset(CPUARMState *env)
34
+{
77
+{
35
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
78
+ if (arm_current_el(env) >= 2) {
79
+ return 0;
80
+ }
81
+ return gt_phys_raw_cnt_offset(env);
36
+}
82
+}
37
+
83
+
38
static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
84
static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
39
{
85
{
40
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
86
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
41
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_evt(const ARMISARegisters *id)
87
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
42
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2;
88
* reset timer to when ISTATUS next has to change
89
*/
90
uint64_t offset = timeridx == GTIMER_VIRT ?
91
- cpu->env.cp15.cntvoff_el2 : 0;
92
+ cpu->env.cp15.cntvoff_el2 : gt_phys_raw_cnt_offset(&cpu->env);
93
uint64_t count = gt_get_countervalue(&cpu->env);
94
/* Note that this must be unsigned 64 bit arithmetic: */
95
int istatus = count - offset >= gt->cval;
96
@@ -XXX,XX +XXX,XX @@ static void gt_timer_reset(CPUARMState *env, const ARMCPRegInfo *ri,
97
98
static uint64_t gt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
99
{
100
- return gt_get_countervalue(env);
101
+ return gt_get_countervalue(env) - gt_phys_cnt_offset(env);
43
}
102
}
44
103
45
+static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
104
static uint64_t gt_virt_cnt_offset(CPUARMState *env)
105
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_tval_read(CPUARMState *env, const ARMCPRegInfo *ri,
106
case GTIMER_HYPVIRT:
107
offset = gt_virt_cnt_offset(env);
108
break;
109
+ case GTIMER_PHYS:
110
+ offset = gt_phys_cnt_offset(env);
111
+ break;
112
}
113
114
return (uint32_t)(env->cp15.c14_timer[timeridx].cval -
115
@@ -XXX,XX +XXX,XX @@ static void gt_tval_write(CPUARMState *env, const ARMCPRegInfo *ri,
116
case GTIMER_HYPVIRT:
117
offset = gt_virt_cnt_offset(env);
118
break;
119
+ case GTIMER_PHYS:
120
+ offset = gt_phys_cnt_offset(env);
121
+ break;
122
}
123
124
trace_arm_gt_tval_write(timeridx, value);
125
@@ -XXX,XX +XXX,XX @@ static void gt_cnthctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
126
R_CNTHCTL_EL1NVVCT_MASK |
127
R_CNTHCTL_EVNTIS_MASK;
128
}
129
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
130
+ valid_mask |= R_CNTHCTL_ECV_MASK;
131
+ }
132
133
/* Clear RES0 bits */
134
value &= valid_mask;
135
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo gen_timer_ecv_cp_reginfo[] = {
136
},
137
};
138
139
+static CPAccessResult gt_cntpoff_access(CPUARMState *env,
140
+ const ARMCPRegInfo *ri,
141
+ bool isread)
46
+{
142
+{
47
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
143
+ if (arm_current_el(env) == 2 && !(env->cp15.scr_el3 & SCR_ECVEN)) {
144
+ return CP_ACCESS_TRAP_EL3;
145
+ }
146
+ return CP_ACCESS_OK;
48
+}
147
+}
49
+
148
+
50
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
149
+static void gt_cntpoff_write(CPUARMState *env, const ARMCPRegInfo *ri,
150
+ uint64_t value)
51
+{
151
+{
52
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
152
+ ARMCPU *cpu = env_archcpu(env);
153
+
154
+ trace_arm_gt_cntpoff_write(value);
155
+ raw_write(env, ri, value);
156
+ gt_recalc_timer(cpu, GTIMER_PHYS);
53
+}
157
+}
54
+
158
+
55
+static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
159
+static const ARMCPRegInfo gen_timer_cntpoff_reginfo = {
56
+{
160
+ .name = "CNTPOFF_EL2", .state = ARM_CP_STATE_AA64,
57
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
161
+ .opc0 = 3, .opc1 = 4, .crn = 14, .crm = 0, .opc2 = 6,
58
+}
162
+ .access = PL2_RW, .type = ARM_CP_IO, .resetvalue = 0,
59
+
163
+ .accessfn = gt_cntpoff_access, .writefn = gt_cntpoff_write,
60
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
164
+ .nv2_redirect_offset = 0x1a8,
61
{
165
+ .fieldoffset = offsetof(CPUARMState, cp15.cntpoff_el2),
62
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
166
+};
63
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
167
#else
64
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
168
65
}
169
/*
66
170
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
67
-static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
171
if (cpu_isar_feature(aa64_ecv_traps, cpu)) {
68
-{
172
define_arm_cp_regs(cpu, gen_timer_ecv_cp_reginfo);
69
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
173
}
70
-}
174
+#ifndef CONFIG_USER_ONLY
71
-
175
+ if (cpu_isar_feature(aa64_ecv, cpu)) {
72
-static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
176
+ define_one_arm_cp_reg(cpu, &gen_timer_cntpoff_reginfo);
73
-{
177
+ }
74
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
178
+#endif
75
-}
179
if (arm_feature(env, ARM_FEATURE_VAPA)) {
76
-
180
ARMCPRegInfo vapa_cp_reginfo[] = {
77
-static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
181
{ .name = "PAR", .cp = 15, .crn = 7, .crm = 4, .opc1 = 0, .opc2 = 0,
78
-{
182
diff --git a/target/arm/trace-events b/target/arm/trace-events
79
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
183
index XXXXXXX..XXXXXXX 100644
80
-}
184
--- a/target/arm/trace-events
81
-
185
+++ b/target/arm/trace-events
82
-static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
186
@@ -XXX,XX +XXX,XX @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
83
-{
187
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
84
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
188
arm_gt_imask_toggle(int timer) "gt_ctl_write: timer %d IMASK toggle"
85
-}
189
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64
86
-
190
+arm_gt_cntpoff_write(uint64_t value) "gt_cntpoff_write: value 0x%" PRIx64
87
-static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
191
arm_gt_update_irq(int timer, int irqstate) "gt_update_irq: timer %d irqstate %d"
88
-{
192
89
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
193
# kvm.c
90
-}
91
-
92
-static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
93
-{
94
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
95
-}
96
-
97
static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
98
{
99
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
100
--
194
--
101
2.34.1
195
2.34.1
102
103
diff view generated by jsdifflib
1
Implement a model of the Neoverse N2 CPU. This is an Armv9.0-A
1
Enable all FEAT_ECV features on the 'max' CPU.
2
processor very similar to the Cortex-A710. The differences are:
3
* no FEAT_EVT
4
* FEAT_DGH (data gathering hint)
5
* FEAT_NV (not yet implemented in QEMU)
6
* Statistical Profiling Extension (not implemented in QEMU)
7
* 48 bit physical address range, not 40
8
* CTR_EL0.DIC = 1 (no explicit icache cleaning needed)
9
* PMCR_EL0.N = 6 (always 6 PMU counters, not 20)
10
11
Because it has 48-bit physical address support, we can use
12
this CPU in the sbsa-ref board as well as the virt board.
13
2
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
Tested-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20230915185453.1871167-3-peter.maydell@linaro.org
6
Message-id: 20240301183219.2424889-9-peter.maydell@linaro.org
18
---
7
---
19
docs/system/arm/virt.rst | 1 +
8
docs/system/arm/emulation.rst | 1 +
20
hw/arm/sbsa-ref.c | 1 +
9
target/arm/tcg/cpu64.c | 1 +
21
hw/arm/virt.c | 1 +
10
2 files changed, 2 insertions(+)
22
target/arm/tcg/cpu64.c | 103 +++++++++++++++++++++++++++++++++++++++
23
4 files changed, 106 insertions(+)
24
11
25
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
12
diff --git a/docs/system/arm/emulation.rst b/docs/system/arm/emulation.rst
26
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
27
--- a/docs/system/arm/virt.rst
14
--- a/docs/system/arm/emulation.rst
28
+++ b/docs/system/arm/virt.rst
15
+++ b/docs/system/arm/emulation.rst
29
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
16
@@ -XXX,XX +XXX,XX @@ the following architecture extensions:
30
- ``host`` (with KVM only)
17
- FEAT_DotProd (Advanced SIMD dot product instructions)
31
- ``neoverse-n1`` (64-bit)
18
- FEAT_DoubleFault (Double Fault Extension)
32
- ``neoverse-v1`` (64-bit)
19
- FEAT_E0PD (Preventing EL0 access to halves of address maps)
33
+- ``neoverse-n2`` (64-bit)
20
+- FEAT_ECV (Enhanced Counter Virtualization)
34
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
21
- FEAT_EPAC (Enhanced pointer authentication)
35
22
- FEAT_ETS (Enhanced Translation Synchronization)
36
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
23
- FEAT_EVT (Enhanced Virtualization Traps)
37
diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c
38
index XXXXXXX..XXXXXXX 100644
39
--- a/hw/arm/sbsa-ref.c
40
+++ b/hw/arm/sbsa-ref.c
41
@@ -XXX,XX +XXX,XX @@ static const char * const valid_cpus[] = {
42
ARM_CPU_TYPE_NAME("cortex-a72"),
43
ARM_CPU_TYPE_NAME("neoverse-n1"),
44
ARM_CPU_TYPE_NAME("neoverse-v1"),
45
+ ARM_CPU_TYPE_NAME("neoverse-n2"),
46
ARM_CPU_TYPE_NAME("max"),
47
};
48
49
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/virt.c
52
+++ b/hw/arm/virt.c
53
@@ -XXX,XX +XXX,XX @@ static const char *valid_cpus[] = {
54
ARM_CPU_TYPE_NAME("a64fx"),
55
ARM_CPU_TYPE_NAME("neoverse-n1"),
56
ARM_CPU_TYPE_NAME("neoverse-v1"),
57
+ ARM_CPU_TYPE_NAME("neoverse-n2"),
58
#endif
59
ARM_CPU_TYPE_NAME("cortex-a53"),
60
ARM_CPU_TYPE_NAME("cortex-a57"),
61
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
24
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
62
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/tcg/cpu64.c
26
--- a/target/arm/tcg/cpu64.c
64
+++ b/target/arm/tcg/cpu64.c
27
+++ b/target/arm/tcg/cpu64.c
65
@@ -XXX,XX +XXX,XX @@ static void aarch64_a710_initfn(Object *obj)
28
@@ -XXX,XX +XXX,XX @@ void aarch64_max_tcg_initfn(Object *obj)
66
aarch64_add_sve_properties(obj);
29
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2); /* 64k stage2 supported */
67
}
30
t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2); /* 4k stage2 supported */
68
31
t = FIELD_DP64(t, ID_AA64MMFR0, FGT, 1); /* FEAT_FGT */
69
+/* Extra IMPDEF regs in the N2 beyond those in the A710 */
32
+ t = FIELD_DP64(t, ID_AA64MMFR0, ECV, 2); /* FEAT_ECV */
70
+static const ARMCPRegInfo neoverse_n2_cp_reginfo[] = {
33
cpu->isar.id_aa64mmfr0 = t;
71
+ { .name = "CPURNDBR_EL3", .state = ARM_CP_STATE_AA64,
34
72
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 3, .opc2 = 0,
35
t = cpu->isar.id_aa64mmfr1;
73
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
74
+ { .name = "CPURNDPEID_EL3", .state = ARM_CP_STATE_AA64,
75
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 3, .opc2 = 1,
76
+ .access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
77
+};
78
+
79
+static void aarch64_neoverse_n2_initfn(Object *obj)
80
+{
81
+ ARMCPU *cpu = ARM_CPU(obj);
82
+
83
+ cpu->dtb_compatible = "arm,neoverse-n2";
84
+ set_feature(&cpu->env, ARM_FEATURE_V8);
85
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
86
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
87
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
88
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
89
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
90
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
91
+ set_feature(&cpu->env, ARM_FEATURE_PMU);
92
+
93
+ /* Ordered by Section B.5: AArch64 ID registers */
94
+ cpu->midr = 0x410FD493; /* r0p3 */
95
+ cpu->revidr = 0;
96
+ cpu->isar.id_pfr0 = 0x21110131;
97
+ cpu->isar.id_pfr1 = 0x00010000; /* GIC filled in later */
98
+ cpu->isar.id_dfr0 = 0x16011099;
99
+ cpu->id_afr0 = 0;
100
+ cpu->isar.id_mmfr0 = 0x10201105;
101
+ cpu->isar.id_mmfr1 = 0x40000000;
102
+ cpu->isar.id_mmfr2 = 0x01260000;
103
+ cpu->isar.id_mmfr3 = 0x02122211;
104
+ cpu->isar.id_isar0 = 0x02101110;
105
+ cpu->isar.id_isar1 = 0x13112111;
106
+ cpu->isar.id_isar2 = 0x21232042;
107
+ cpu->isar.id_isar3 = 0x01112131;
108
+ cpu->isar.id_isar4 = 0x00010142;
109
+ cpu->isar.id_isar5 = 0x11011121; /* with Crypto */
110
+ cpu->isar.id_mmfr4 = 0x01021110;
111
+ cpu->isar.id_isar6 = 0x01111111;
112
+ cpu->isar.mvfr0 = 0x10110222;
113
+ cpu->isar.mvfr1 = 0x13211111;
114
+ cpu->isar.mvfr2 = 0x00000043;
115
+ cpu->isar.id_pfr2 = 0x00000011;
116
+ cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
117
+ cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
118
+ cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
119
+ cpu->isar.id_aa64dfr0 = 0x000011f210305619ull;
120
+ cpu->isar.id_aa64dfr1 = 0;
121
+ cpu->id_aa64afr0 = 0;
122
+ cpu->id_aa64afr1 = 0;
123
+ cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */
124
+ cpu->isar.id_aa64isar1 = 0x0011111101211052ull;
125
+ cpu->isar.id_aa64mmfr0 = 0x0000022200101125ull;
126
+ cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
127
+ cpu->isar.id_aa64mmfr2 = 0x1221011112101011ull;
128
+ cpu->clidr = 0x0000001482000023ull;
129
+ cpu->gm_blocksize = 4;
130
+ cpu->ctr = 0x00000004b444c004ull;
131
+ cpu->dcz_blocksize = 4;
132
+ /* TODO FEAT_MPAM: mpamidr_el1 = 0x0000_0001_001e_01ff */
133
+
134
+ /* Section B.7.2: PMCR_EL0 */
135
+ cpu->isar.reset_pmcr_el0 = 0x3000; /* with 6 counters */
136
+
137
+ /* Section B.8.9: ICH_VTR_EL2 */
138
+ cpu->gic_num_lrs = 4;
139
+ cpu->gic_vpribits = 5;
140
+ cpu->gic_vprebits = 5;
141
+ cpu->gic_pribits = 5;
142
+
143
+ /* Section 14: Scalable Vector Extensions support */
144
+ cpu->sve_vq.supported = 1 << 0; /* 128bit */
145
+
146
+ /*
147
+ * The Neoverse N2 TRM does not list CCSIDR values. The layout of
148
+ * the caches are in text in Table 7-1, Table 8-1, and Table 9-1.
149
+ *
150
+ * L1: 4-way set associative 64-byte line size, total 64K.
151
+ * L2: 8-way set associative 64 byte line size, total either 512K or 1024K.
152
+ */
153
+ cpu->ccsidr[0] = make_ccsidr64(4, 64, 64 * KiB); /* L1 dcache */
154
+ cpu->ccsidr[1] = cpu->ccsidr[0]; /* L1 icache */
155
+ cpu->ccsidr[2] = make_ccsidr64(8, 64, 512 * KiB); /* L2 cache */
156
+
157
+ /* FIXME: Not documented -- copied from neoverse-v1 */
158
+ cpu->reset_sctlr = 0x30c50838;
159
+
160
+ /*
161
+ * The Neoverse N2 has all of the Cortex-A710 IMPDEF registers,
162
+ * and a few more RNG related ones.
163
+ */
164
+ define_arm_cp_regs(cpu, cortex_a710_cp_reginfo);
165
+ define_arm_cp_regs(cpu, neoverse_n2_cp_reginfo);
166
+
167
+ aarch64_add_pauth_properties(obj);
168
+ aarch64_add_sve_properties(obj);
169
+}
170
+
171
/*
172
* -cpu max: a CPU with as many features enabled as our emulation supports.
173
* The version of '-cpu max' for qemu-system-arm is defined in cpu32.c;
174
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
175
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
176
{ .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
177
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
178
+ { .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn },
179
};
180
181
static void aarch64_cpu_register_types(void)
182
--
36
--
183
2.34.1
37
2.34.1
184
38
185
39
diff view generated by jsdifflib
Deleted patch
1
Move the feature test functions that test ID_AA64ISAR* fields
2
together.
3
1
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20231024163510.2972081-5-peter.maydell@linaro.org
8
---
9
target/arm/cpu-features.h | 70 +++++++++++++++++++--------------------
10
1 file changed, 35 insertions(+), 35 deletions(-)
11
12
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
13
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu-features.h
15
+++ b/target/arm/cpu-features.h
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
17
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
18
}
19
20
+static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
21
+{
22
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
23
+}
24
+
25
+static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
26
+{
27
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0;
28
+}
29
+
30
static inline bool isar_feature_aa64_jscvt(const ARMISARegisters *id)
31
{
32
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
33
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
34
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0;
35
}
36
37
-static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
38
-{
39
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
40
-}
41
-
42
-static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
43
-{
44
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0;
45
-}
46
-
47
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
48
{
49
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
50
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
51
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
52
}
53
54
+static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
55
+{
56
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
57
+}
58
+
59
+static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
60
+{
61
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
62
+}
63
+
64
+static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
65
+{
66
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
67
+}
68
+
69
+static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id)
70
+{
71
+ return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0;
72
+}
73
+
74
+static inline bool isar_feature_aa64_mops(const ARMISARegisters *id)
75
+{
76
+ return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS);
77
+}
78
+
79
static inline bool isar_feature_aa64_fp_simd(const ARMISARegisters *id)
80
{
81
/* We always set the AdvSIMD and FP fields identically. */
82
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
83
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
84
}
85
86
-static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
87
-{
88
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
89
-}
90
-
91
-static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
92
-{
93
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
94
-}
95
-
96
-static inline bool isar_feature_aa64_i8mm(const ARMISARegisters *id)
97
-{
98
- return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, I8MM) != 0;
99
-}
100
-
101
-static inline bool isar_feature_aa64_hbc(const ARMISARegisters *id)
102
-{
103
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0;
104
-}
105
-
106
static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
107
{
108
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
109
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
110
return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
111
}
112
113
-static inline bool isar_feature_aa64_mops(const ARMISARegisters *id)
114
-{
115
- return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, MOPS);
116
-}
117
-
118
/*
119
* Feature tests for "does this exist in either 32-bit or 64-bit?"
120
*/
121
--
122
2.34.1
123
124
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
QOM objects shouldn't access each other internals fields
3
Features supported :
4
except using the QOM API.
4
- the 8 STM32L4x5 GPIOs are initialized with their reset values
5
(except IDR, see below)
6
- input mode : setting a pin in input mode "externally" (using input
7
irqs) results in an out irq (transmitted to SYSCFG)
8
- output mode : setting a bit in ODR sets the corresponding out irq
9
(if this line is configured in output mode)
10
- pull-up, pull-down
11
- push-pull, open-drain
5
12
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
13
Difference with the real GPIOs :
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
- Alternate Function and Analog mode aren't implemented :
8
Reviewed-by: Thomas Huth <thuth@redhat.com>
15
pins in AF/Analog behave like pins in input mode
9
Message-id: 20231020130331.50048-8-philmd@linaro.org
16
- floating pins stay at their last value
17
- register IDR reset values differ from the real one :
18
values are coherent with the other registers reset values
19
and the fact that AF/Analog modes aren't implemented
20
- setting I/O output speed isn't supported
21
- locking port bits isn't supported
22
- ADC function isn't supported
23
- GPIOH has 16 pins instead of 2 pins
24
- writing to registers LCKR, AFRL, AFRH and ASCR is ineffective
25
26
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
27
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
28
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
29
Acked-by: Alistair Francis <alistair.francis@wdc.com>
30
Message-id: 20240305210444.310665-2-ines.varhol@telecom-paris.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
31
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
32
---
12
hw/arm/pxa2xx_pic.c | 11 ++++++++++-
33
MAINTAINERS | 1 +
13
1 file changed, 10 insertions(+), 1 deletion(-)
34
docs/system/arm/b-l475e-iot01a.rst | 2 +-
35
include/hw/gpio/stm32l4x5_gpio.h | 70 +++++
36
hw/gpio/stm32l4x5_gpio.c | 477 +++++++++++++++++++++++++++++
37
hw/gpio/Kconfig | 3 +
38
hw/gpio/meson.build | 1 +
39
hw/gpio/trace-events | 6 +
40
7 files changed, 559 insertions(+), 1 deletion(-)
41
create mode 100644 include/hw/gpio/stm32l4x5_gpio.h
42
create mode 100644 hw/gpio/stm32l4x5_gpio.c
14
43
15
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
44
diff --git a/MAINTAINERS b/MAINTAINERS
16
index XXXXXXX..XXXXXXX 100644
45
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/pxa2xx_pic.c
46
--- a/MAINTAINERS
18
+++ b/hw/arm/pxa2xx_pic.c
47
+++ b/MAINTAINERS
48
@@ -XXX,XX +XXX,XX @@ F: hw/arm/stm32l4x5_soc.c
49
F: hw/misc/stm32l4x5_exti.c
50
F: hw/misc/stm32l4x5_syscfg.c
51
F: hw/misc/stm32l4x5_rcc.c
52
+F: hw/gpio/stm32l4x5_gpio.c
53
F: include/hw/*/stm32l4x5_*.h
54
55
B-L475E-IOT01A IoT Node
56
diff --git a/docs/system/arm/b-l475e-iot01a.rst b/docs/system/arm/b-l475e-iot01a.rst
57
index XXXXXXX..XXXXXXX 100644
58
--- a/docs/system/arm/b-l475e-iot01a.rst
59
+++ b/docs/system/arm/b-l475e-iot01a.rst
60
@@ -XXX,XX +XXX,XX @@ Currently B-L475E-IOT01A machine's only supports the following devices:
61
- STM32L4x5 EXTI (Extended interrupts and events controller)
62
- STM32L4x5 SYSCFG (System configuration controller)
63
- STM32L4x5 RCC (Reset and clock control)
64
+- STM32L4x5 GPIOs (General-purpose I/Os)
65
66
Missing devices
67
"""""""""""""""
68
@@ -XXX,XX +XXX,XX @@ Missing devices
69
The B-L475E-IOT01A does *not* support the following devices:
70
71
- Serial ports (UART)
72
-- General-purpose I/Os (GPIO)
73
- Analog to Digital Converter (ADC)
74
- SPI controller
75
- Timer controller (TIMER)
76
diff --git a/include/hw/gpio/stm32l4x5_gpio.h b/include/hw/gpio/stm32l4x5_gpio.h
77
new file mode 100644
78
index XXXXXXX..XXXXXXX
79
--- /dev/null
80
+++ b/include/hw/gpio/stm32l4x5_gpio.h
19
@@ -XXX,XX +XXX,XX @@
81
@@ -XXX,XX +XXX,XX @@
20
#include "cpu.h"
82
+/*
21
#include "hw/arm/pxa.h"
83
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
22
#include "hw/sysbus.h"
84
+ *
85
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
86
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
87
+ *
88
+ * SPDX-License-Identifier: GPL-2.0-or-later
89
+ *
90
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
91
+ * See the COPYING file in the top-level directory.
92
+ */
93
+
94
+/*
95
+ * The reference used is the STMicroElectronics RM0351 Reference manual
96
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
97
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
98
+ */
99
+
100
+#ifndef HW_STM32L4X5_GPIO_H
101
+#define HW_STM32L4X5_GPIO_H
102
+
103
+#include "hw/sysbus.h"
104
+#include "qom/object.h"
105
+
106
+#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
107
+OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
108
+
109
+#define GPIO_NUM_PINS 16
110
+
111
+struct Stm32l4x5GpioState {
112
+ SysBusDevice parent_obj;
113
+
114
+ MemoryRegion mmio;
115
+
116
+ /* GPIO registers */
117
+ uint32_t moder;
118
+ uint32_t otyper;
119
+ uint32_t ospeedr;
120
+ uint32_t pupdr;
121
+ uint32_t idr;
122
+ uint32_t odr;
123
+ uint32_t lckr;
124
+ uint32_t afrl;
125
+ uint32_t afrh;
126
+ uint32_t ascr;
127
+
128
+ /* GPIO registers reset values */
129
+ uint32_t moder_reset;
130
+ uint32_t ospeedr_reset;
131
+ uint32_t pupdr_reset;
132
+
133
+ /*
134
+ * External driving of pins.
135
+ * The pins can be set externally through the device
136
+ * anonymous input GPIOs lines under certain conditions.
137
+ * The pin must not be in push-pull output mode,
138
+ * and can't be set high in open-drain mode.
139
+ * Pins driven externally and configured to
140
+ * output mode will in general be "disconnected"
141
+ * (see `get_gpio_pinmask_to_disconnect()`)
142
+ */
143
+ uint16_t disconnected_pins;
144
+ uint16_t pins_connected_high;
145
+
146
+ char *name;
147
+ Clock *clk;
148
+ qemu_irq pin[GPIO_NUM_PINS];
149
+};
150
+
151
+#endif
152
diff --git a/hw/gpio/stm32l4x5_gpio.c b/hw/gpio/stm32l4x5_gpio.c
153
new file mode 100644
154
index XXXXXXX..XXXXXXX
155
--- /dev/null
156
+++ b/hw/gpio/stm32l4x5_gpio.c
157
@@ -XXX,XX +XXX,XX @@
158
+/*
159
+ * STM32L4x5 GPIO (General Purpose Input/Ouput)
160
+ *
161
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
162
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
163
+ *
164
+ * SPDX-License-Identifier: GPL-2.0-or-later
165
+ *
166
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
167
+ * See the COPYING file in the top-level directory.
168
+ */
169
+
170
+/*
171
+ * The reference used is the STMicroElectronics RM0351 Reference manual
172
+ * for STM32L4x5 and STM32L4x6 advanced Arm ® -based 32-bit MCUs.
173
+ * https://www.st.com/en/microcontrollers-microprocessors/stm32l4x5/documentation.html
174
+ */
175
+
176
+#include "qemu/osdep.h"
177
+#include "qemu/log.h"
178
+#include "hw/gpio/stm32l4x5_gpio.h"
179
+#include "hw/irq.h"
180
+#include "hw/qdev-clock.h"
23
+#include "hw/qdev-properties.h"
181
+#include "hw/qdev-properties.h"
24
#include "migration/vmstate.h"
182
+#include "qapi/visitor.h"
25
#include "qom/object.h"
183
+#include "qapi/error.h"
26
#include "target/arm/cpregs.h"
184
+#include "migration/vmstate.h"
27
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
185
+#include "trace.h"
28
DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
186
+
29
PXA2xxPICState *s = PXA2XX_PIC(dev);
187
+#define GPIO_MODER 0x00
30
188
+#define GPIO_OTYPER 0x04
31
- s->cpu = cpu;
189
+#define GPIO_OSPEEDR 0x08
32
+ object_property_set_link(OBJECT(dev), "arm-cpu",
190
+#define GPIO_PUPDR 0x0C
33
+ OBJECT(cpu), &error_abort);
191
+#define GPIO_IDR 0x10
34
192
+#define GPIO_ODR 0x14
35
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
193
+#define GPIO_BSRR 0x18
36
194
+#define GPIO_LCKR 0x1C
37
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pxa2xx_pic_regs = {
195
+#define GPIO_AFRL 0x20
38
},
196
+#define GPIO_AFRH 0x24
39
};
197
+#define GPIO_BRR 0x28
40
198
+#define GPIO_ASCR 0x2C
41
+static Property pxa2xx_pic_properties[] = {
199
+
42
+ DEFINE_PROP_LINK("arm-cpu", PXA2xxPICState, cpu,
200
+/* 0b11111111_11111111_00000000_00000000 */
43
+ TYPE_ARM_CPU, ARMCPU *),
201
+#define RESERVED_BITS_MASK 0xFFFF0000
202
+
203
+static void update_gpio_idr(Stm32l4x5GpioState *s);
204
+
205
+static bool is_pull_up(Stm32l4x5GpioState *s, unsigned pin)
206
+{
207
+ return extract32(s->pupdr, 2 * pin, 2) == 1;
208
+}
209
+
210
+static bool is_pull_down(Stm32l4x5GpioState *s, unsigned pin)
211
+{
212
+ return extract32(s->pupdr, 2 * pin, 2) == 2;
213
+}
214
+
215
+static bool is_output(Stm32l4x5GpioState *s, unsigned pin)
216
+{
217
+ return extract32(s->moder, 2 * pin, 2) == 1;
218
+}
219
+
220
+static bool is_open_drain(Stm32l4x5GpioState *s, unsigned pin)
221
+{
222
+ return extract32(s->otyper, pin, 1) == 1;
223
+}
224
+
225
+static bool is_push_pull(Stm32l4x5GpioState *s, unsigned pin)
226
+{
227
+ return extract32(s->otyper, pin, 1) == 0;
228
+}
229
+
230
+static void stm32l4x5_gpio_reset_hold(Object *obj)
231
+{
232
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
233
+
234
+ s->moder = s->moder_reset;
235
+ s->otyper = 0x00000000;
236
+ s->ospeedr = s->ospeedr_reset;
237
+ s->pupdr = s->pupdr_reset;
238
+ s->idr = 0x00000000;
239
+ s->odr = 0x00000000;
240
+ s->lckr = 0x00000000;
241
+ s->afrl = 0x00000000;
242
+ s->afrh = 0x00000000;
243
+ s->ascr = 0x00000000;
244
+
245
+ s->disconnected_pins = 0xFFFF;
246
+ s->pins_connected_high = 0x0000;
247
+ update_gpio_idr(s);
248
+}
249
+
250
+static void stm32l4x5_gpio_set(void *opaque, int line, int level)
251
+{
252
+ Stm32l4x5GpioState *s = opaque;
253
+ /*
254
+ * The pin isn't set if line is configured in output mode
255
+ * except if level is 0 and the output is open-drain.
256
+ * This way there will be no short-circuit prone situations.
257
+ */
258
+ if (is_output(s, line) && !(is_open_drain(s, line) && (level == 0))) {
259
+ qemu_log_mask(LOG_GUEST_ERROR, "Line %d can't be driven externally\n",
260
+ line);
261
+ return;
262
+ }
263
+
264
+ s->disconnected_pins &= ~(1 << line);
265
+ if (level) {
266
+ s->pins_connected_high |= (1 << line);
267
+ } else {
268
+ s->pins_connected_high &= ~(1 << line);
269
+ }
270
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
271
+ s->pins_connected_high);
272
+ update_gpio_idr(s);
273
+}
274
+
275
+
276
+static void update_gpio_idr(Stm32l4x5GpioState *s)
277
+{
278
+ uint32_t new_idr_mask = 0;
279
+ uint32_t new_idr = s->odr;
280
+ uint32_t old_idr = s->idr;
281
+ int new_pin_state, old_pin_state;
282
+
283
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
284
+ if (is_output(s, i)) {
285
+ if (is_push_pull(s, i)) {
286
+ new_idr_mask |= (1 << i);
287
+ } else if (!(s->odr & (1 << i))) {
288
+ /* open-drain ODR 0 */
289
+ new_idr_mask |= (1 << i);
290
+ /* open-drain ODR 1 */
291
+ } else if (!(s->disconnected_pins & (1 << i)) &&
292
+ !(s->pins_connected_high & (1 << i))) {
293
+ /* open-drain ODR 1 with pin connected low */
294
+ new_idr_mask |= (1 << i);
295
+ new_idr &= ~(1 << i);
296
+ /* open-drain ODR 1 with unactive pin */
297
+ } else if (is_pull_up(s, i)) {
298
+ new_idr_mask |= (1 << i);
299
+ } else if (is_pull_down(s, i)) {
300
+ new_idr_mask |= (1 << i);
301
+ new_idr &= ~(1 << i);
302
+ }
303
+ /*
304
+ * The only case left is for open-drain ODR 1
305
+ * with unactive pin without pull-up or pull-down :
306
+ * the value is floating.
307
+ */
308
+ /* input or analog mode with connected pin */
309
+ } else if (!(s->disconnected_pins & (1 << i))) {
310
+ if (s->pins_connected_high & (1 << i)) {
311
+ /* pin high */
312
+ new_idr_mask |= (1 << i);
313
+ new_idr |= (1 << i);
314
+ } else {
315
+ /* pin low */
316
+ new_idr_mask |= (1 << i);
317
+ new_idr &= ~(1 << i);
318
+ }
319
+ /* input or analog mode with disconnected pin */
320
+ } else {
321
+ if (is_pull_up(s, i)) {
322
+ /* pull-up */
323
+ new_idr_mask |= (1 << i);
324
+ new_idr |= (1 << i);
325
+ } else if (is_pull_down(s, i)) {
326
+ /* pull-down */
327
+ new_idr_mask |= (1 << i);
328
+ new_idr &= ~(1 << i);
329
+ }
330
+ /*
331
+ * The only case left is for a disconnected pin
332
+ * without pull-up or pull-down :
333
+ * the value is floating.
334
+ */
335
+ }
336
+ }
337
+
338
+ s->idr = (old_idr & ~new_idr_mask) | (new_idr & new_idr_mask);
339
+ trace_stm32l4x5_gpio_update_idr(s->name, old_idr, s->idr);
340
+
341
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
342
+ if (new_idr_mask & (1 << i)) {
343
+ new_pin_state = (new_idr & (1 << i)) > 0;
344
+ old_pin_state = (old_idr & (1 << i)) > 0;
345
+ if (new_pin_state > old_pin_state) {
346
+ qemu_irq_raise(s->pin[i]);
347
+ } else if (new_pin_state < old_pin_state) {
348
+ qemu_irq_lower(s->pin[i]);
349
+ }
350
+ }
351
+ }
352
+}
353
+
354
+/*
355
+ * Return mask of pins that are both configured in output
356
+ * mode and externally driven (except pins in open-drain
357
+ * mode externally set to 0).
358
+ */
359
+static uint32_t get_gpio_pinmask_to_disconnect(Stm32l4x5GpioState *s)
360
+{
361
+ uint32_t pins_to_disconnect = 0;
362
+ for (int i = 0; i < GPIO_NUM_PINS; i++) {
363
+ /* for each connected pin in output mode */
364
+ if (!(s->disconnected_pins & (1 << i)) && is_output(s, i)) {
365
+ /* if either push-pull or high level */
366
+ if (is_push_pull(s, i) || s->pins_connected_high & (1 << i)) {
367
+ pins_to_disconnect |= (1 << i);
368
+ qemu_log_mask(LOG_GUEST_ERROR,
369
+ "Line %d can't be driven externally\n",
370
+ i);
371
+ }
372
+ }
373
+ }
374
+ return pins_to_disconnect;
375
+}
376
+
377
+/*
378
+ * Set field `disconnected_pins` and call `update_gpio_idr()`
379
+ */
380
+static void disconnect_gpio_pins(Stm32l4x5GpioState *s, uint16_t lines)
381
+{
382
+ s->disconnected_pins |= lines;
383
+ trace_stm32l4x5_gpio_pins(s->name, s->disconnected_pins,
384
+ s->pins_connected_high);
385
+ update_gpio_idr(s);
386
+}
387
+
388
+static void disconnected_pins_set(Object *obj, Visitor *v,
389
+ const char *name, void *opaque, Error **errp)
390
+{
391
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
392
+ uint16_t value;
393
+ if (!visit_type_uint16(v, name, &value, errp)) {
394
+ return;
395
+ }
396
+ disconnect_gpio_pins(s, value);
397
+}
398
+
399
+static void disconnected_pins_get(Object *obj, Visitor *v,
400
+ const char *name, void *opaque, Error **errp)
401
+{
402
+ visit_type_uint16(v, name, (uint16_t *)opaque, errp);
403
+}
404
+
405
+static void clock_freq_get(Object *obj, Visitor *v,
406
+ const char *name, void *opaque, Error **errp)
407
+{
408
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
409
+ uint32_t clock_freq_hz = clock_get_hz(s->clk);
410
+ visit_type_uint32(v, name, &clock_freq_hz, errp);
411
+}
412
+
413
+static void stm32l4x5_gpio_write(void *opaque, hwaddr addr,
414
+ uint64_t val64, unsigned int size)
415
+{
416
+ Stm32l4x5GpioState *s = opaque;
417
+
418
+ uint32_t value = val64;
419
+ trace_stm32l4x5_gpio_write(s->name, addr, val64);
420
+
421
+ switch (addr) {
422
+ case GPIO_MODER:
423
+ s->moder = value;
424
+ disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
425
+ qemu_log_mask(LOG_UNIMP,
426
+ "%s: Analog and AF modes aren't supported\n\
427
+ Analog and AF mode behave like input mode\n",
428
+ __func__);
429
+ return;
430
+ case GPIO_OTYPER:
431
+ s->otyper = value & ~RESERVED_BITS_MASK;
432
+ disconnect_gpio_pins(s, get_gpio_pinmask_to_disconnect(s));
433
+ return;
434
+ case GPIO_OSPEEDR:
435
+ qemu_log_mask(LOG_UNIMP,
436
+ "%s: Changing I/O output speed isn't supported\n\
437
+ I/O speed is already maximal\n",
438
+ __func__);
439
+ s->ospeedr = value;
440
+ return;
441
+ case GPIO_PUPDR:
442
+ s->pupdr = value;
443
+ update_gpio_idr(s);
444
+ return;
445
+ case GPIO_IDR:
446
+ qemu_log_mask(LOG_UNIMP,
447
+ "%s: GPIO->IDR is read-only\n",
448
+ __func__);
449
+ return;
450
+ case GPIO_ODR:
451
+ s->odr = value & ~RESERVED_BITS_MASK;
452
+ update_gpio_idr(s);
453
+ return;
454
+ case GPIO_BSRR: {
455
+ uint32_t bits_to_reset = (value & RESERVED_BITS_MASK) >> GPIO_NUM_PINS;
456
+ uint32_t bits_to_set = value & ~RESERVED_BITS_MASK;
457
+ /* If both BSx and BRx are set, BSx has priority.*/
458
+ s->odr &= ~bits_to_reset;
459
+ s->odr |= bits_to_set;
460
+ update_gpio_idr(s);
461
+ return;
462
+ }
463
+ case GPIO_LCKR:
464
+ qemu_log_mask(LOG_UNIMP,
465
+ "%s: Locking port bits configuration isn't supported\n",
466
+ __func__);
467
+ s->lckr = value & ~RESERVED_BITS_MASK;
468
+ return;
469
+ case GPIO_AFRL:
470
+ qemu_log_mask(LOG_UNIMP,
471
+ "%s: Alternate functions aren't supported\n",
472
+ __func__);
473
+ s->afrl = value;
474
+ return;
475
+ case GPIO_AFRH:
476
+ qemu_log_mask(LOG_UNIMP,
477
+ "%s: Alternate functions aren't supported\n",
478
+ __func__);
479
+ s->afrh = value;
480
+ return;
481
+ case GPIO_BRR: {
482
+ uint32_t bits_to_reset = value & ~RESERVED_BITS_MASK;
483
+ s->odr &= ~bits_to_reset;
484
+ update_gpio_idr(s);
485
+ return;
486
+ }
487
+ case GPIO_ASCR:
488
+ qemu_log_mask(LOG_UNIMP,
489
+ "%s: ADC function isn't supported\n",
490
+ __func__);
491
+ s->ascr = value & ~RESERVED_BITS_MASK;
492
+ return;
493
+ default:
494
+ qemu_log_mask(LOG_GUEST_ERROR,
495
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
496
+ }
497
+}
498
+
499
+static uint64_t stm32l4x5_gpio_read(void *opaque, hwaddr addr,
500
+ unsigned int size)
501
+{
502
+ Stm32l4x5GpioState *s = opaque;
503
+
504
+ trace_stm32l4x5_gpio_read(s->name, addr);
505
+
506
+ switch (addr) {
507
+ case GPIO_MODER:
508
+ return s->moder;
509
+ case GPIO_OTYPER:
510
+ return s->otyper;
511
+ case GPIO_OSPEEDR:
512
+ return s->ospeedr;
513
+ case GPIO_PUPDR:
514
+ return s->pupdr;
515
+ case GPIO_IDR:
516
+ return s->idr;
517
+ case GPIO_ODR:
518
+ return s->odr;
519
+ case GPIO_BSRR:
520
+ return 0;
521
+ case GPIO_LCKR:
522
+ return s->lckr;
523
+ case GPIO_AFRL:
524
+ return s->afrl;
525
+ case GPIO_AFRH:
526
+ return s->afrh;
527
+ case GPIO_BRR:
528
+ return 0;
529
+ case GPIO_ASCR:
530
+ return s->ascr;
531
+ default:
532
+ qemu_log_mask(LOG_GUEST_ERROR,
533
+ "%s: Bad offset 0x%" HWADDR_PRIx "\n", __func__, addr);
534
+ return 0;
535
+ }
536
+}
537
+
538
+static const MemoryRegionOps stm32l4x5_gpio_ops = {
539
+ .read = stm32l4x5_gpio_read,
540
+ .write = stm32l4x5_gpio_write,
541
+ .endianness = DEVICE_NATIVE_ENDIAN,
542
+ .impl = {
543
+ .min_access_size = 4,
544
+ .max_access_size = 4,
545
+ .unaligned = false,
546
+ },
547
+ .valid = {
548
+ .min_access_size = 4,
549
+ .max_access_size = 4,
550
+ .unaligned = false,
551
+ },
552
+};
553
+
554
+static void stm32l4x5_gpio_init(Object *obj)
555
+{
556
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(obj);
557
+
558
+ memory_region_init_io(&s->mmio, obj, &stm32l4x5_gpio_ops, s,
559
+ TYPE_STM32L4X5_GPIO, 0x400);
560
+
561
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
562
+
563
+ qdev_init_gpio_out(DEVICE(obj), s->pin, GPIO_NUM_PINS);
564
+ qdev_init_gpio_in(DEVICE(obj), stm32l4x5_gpio_set, GPIO_NUM_PINS);
565
+
566
+ s->clk = qdev_init_clock_in(DEVICE(s), "clk", NULL, s, 0);
567
+
568
+ object_property_add(obj, "disconnected-pins", "uint16",
569
+ disconnected_pins_get, disconnected_pins_set,
570
+ NULL, &s->disconnected_pins);
571
+ object_property_add(obj, "clock-freq-hz", "uint32",
572
+ clock_freq_get, NULL, NULL, NULL);
573
+}
574
+
575
+static void stm32l4x5_gpio_realize(DeviceState *dev, Error **errp)
576
+{
577
+ Stm32l4x5GpioState *s = STM32L4X5_GPIO(dev);
578
+ if (!clock_has_source(s->clk)) {
579
+ error_setg(errp, "GPIO: clk input must be connected");
580
+ return;
581
+ }
582
+}
583
+
584
+static const VMStateDescription vmstate_stm32l4x5_gpio = {
585
+ .name = TYPE_STM32L4X5_GPIO,
586
+ .version_id = 1,
587
+ .minimum_version_id = 1,
588
+ .fields = (VMStateField[]){
589
+ VMSTATE_UINT32(moder, Stm32l4x5GpioState),
590
+ VMSTATE_UINT32(otyper, Stm32l4x5GpioState),
591
+ VMSTATE_UINT32(ospeedr, Stm32l4x5GpioState),
592
+ VMSTATE_UINT32(pupdr, Stm32l4x5GpioState),
593
+ VMSTATE_UINT32(idr, Stm32l4x5GpioState),
594
+ VMSTATE_UINT32(odr, Stm32l4x5GpioState),
595
+ VMSTATE_UINT32(lckr, Stm32l4x5GpioState),
596
+ VMSTATE_UINT32(afrl, Stm32l4x5GpioState),
597
+ VMSTATE_UINT32(afrh, Stm32l4x5GpioState),
598
+ VMSTATE_UINT32(ascr, Stm32l4x5GpioState),
599
+ VMSTATE_UINT16(disconnected_pins, Stm32l4x5GpioState),
600
+ VMSTATE_UINT16(pins_connected_high, Stm32l4x5GpioState),
601
+ VMSTATE_END_OF_LIST()
602
+ }
603
+};
604
+
605
+static Property stm32l4x5_gpio_properties[] = {
606
+ DEFINE_PROP_STRING("name", Stm32l4x5GpioState, name),
607
+ DEFINE_PROP_UINT32("mode-reset", Stm32l4x5GpioState, moder_reset, 0),
608
+ DEFINE_PROP_UINT32("ospeed-reset", Stm32l4x5GpioState, ospeedr_reset, 0),
609
+ DEFINE_PROP_UINT32("pupd-reset", Stm32l4x5GpioState, pupdr_reset, 0),
44
+ DEFINE_PROP_END_OF_LIST(),
610
+ DEFINE_PROP_END_OF_LIST(),
45
+};
611
+};
46
+
612
+
47
static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
613
+static void stm32l4x5_gpio_class_init(ObjectClass *klass, void *data)
48
{
614
+{
49
DeviceClass *dc = DEVICE_CLASS(klass);
615
+ DeviceClass *dc = DEVICE_CLASS(klass);
50
ResettableClass *rc = RESETTABLE_CLASS(klass);
616
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
51
617
+
52
+ device_class_set_props(dc, pxa2xx_pic_properties);
618
+ device_class_set_props(dc, stm32l4x5_gpio_properties);
53
dc->desc = "PXA2xx PIC";
619
+ dc->vmsd = &vmstate_stm32l4x5_gpio;
54
dc->vmsd = &vmstate_pxa2xx_pic_regs;
620
+ dc->realize = stm32l4x5_gpio_realize;
55
rc->phases.hold = pxa2xx_pic_reset_hold;
621
+ rc->phases.hold = stm32l4x5_gpio_reset_hold;
622
+}
623
+
624
+static const TypeInfo stm32l4x5_gpio_types[] = {
625
+ {
626
+ .name = TYPE_STM32L4X5_GPIO,
627
+ .parent = TYPE_SYS_BUS_DEVICE,
628
+ .instance_size = sizeof(Stm32l4x5GpioState),
629
+ .instance_init = stm32l4x5_gpio_init,
630
+ .class_init = stm32l4x5_gpio_class_init,
631
+ },
632
+};
633
+
634
+DEFINE_TYPES(stm32l4x5_gpio_types)
635
diff --git a/hw/gpio/Kconfig b/hw/gpio/Kconfig
636
index XXXXXXX..XXXXXXX 100644
637
--- a/hw/gpio/Kconfig
638
+++ b/hw/gpio/Kconfig
639
@@ -XXX,XX +XXX,XX @@ config GPIO_PWR
640
641
config SIFIVE_GPIO
642
bool
643
+
644
+config STM32L4X5_GPIO
645
+ bool
646
diff --git a/hw/gpio/meson.build b/hw/gpio/meson.build
647
index XXXXXXX..XXXXXXX 100644
648
--- a/hw/gpio/meson.build
649
+++ b/hw/gpio/meson.build
650
@@ -XXX,XX +XXX,XX @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files(
651
'bcm2835_gpio.c',
652
'bcm2838_gpio.c'
653
))
654
+system_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_gpio.c'))
655
system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_gpio.c'))
656
system_ss.add(when: 'CONFIG_SIFIVE_GPIO', if_true: files('sifive_gpio.c'))
657
diff --git a/hw/gpio/trace-events b/hw/gpio/trace-events
658
index XXXXXXX..XXXXXXX 100644
659
--- a/hw/gpio/trace-events
660
+++ b/hw/gpio/trace-events
661
@@ -XXX,XX +XXX,XX @@ sifive_gpio_update_output_irq(int64_t line, int64_t value) "line %" PRIi64 " val
662
# aspeed_gpio.c
663
aspeed_gpio_read(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64
664
aspeed_gpio_write(uint64_t offset, uint64_t value) "offset: 0x%" PRIx64 " value 0x%" PRIx64
665
+
666
+# stm32l4x5_gpio.c
667
+stm32l4x5_gpio_read(char *gpio, uint64_t addr) "GPIO%s addr: 0x%" PRIx64 " "
668
+stm32l4x5_gpio_write(char *gpio, uint64_t addr, uint64_t data) "GPIO%s addr: 0x%" PRIx64 " val: 0x%" PRIx64 ""
669
+stm32l4x5_gpio_update_idr(char *gpio, uint32_t old_idr, uint32_t new_idr) "GPIO%s from: 0x%x to: 0x%x"
670
+stm32l4x5_gpio_pins(char *gpio, uint16_t disconnected, uint16_t high) "GPIO%s disconnected pins: 0x%x levels: 0x%x"
56
--
671
--
57
2.34.1
672
2.34.1
58
673
59
674
diff view generated by jsdifflib
1
From: Glenn Miles <milesg@linux.vnet.ibm.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
Testing of the LED state showed that when the LED polarity was
3
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
4
set to GPIO_POLARITY_ACTIVE_LOW and a low logic value was set on
4
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
5
the input GPIO of the LED, the LED was being turn off when it was
6
expected to be turned on.
7
8
Fixes: ddb67f6402 ("hw/misc/led: Allow connecting from GPIO output")
9
Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Andrew Jeffery <andrew@codeconstruct.com.au>
12
Message-id: 20231024191945.4135036-1-milesg@linux.vnet.ibm.com
13
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Acked-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20240305210444.310665-3-ines.varhol@telecom-paris.fr
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
hw/misc/led.c | 2 +-
10
include/hw/arm/stm32l4x5_soc.h | 2 +
17
1 file changed, 1 insertion(+), 1 deletion(-)
11
include/hw/gpio/stm32l4x5_gpio.h | 1 +
18
12
include/hw/misc/stm32l4x5_syscfg.h | 3 +-
19
diff --git a/hw/misc/led.c b/hw/misc/led.c
13
hw/arm/stm32l4x5_soc.c | 71 +++++++++++++++++++++++-------
20
index XXXXXXX..XXXXXXX 100644
14
hw/misc/stm32l4x5_syscfg.c | 1 +
21
--- a/hw/misc/led.c
15
hw/arm/Kconfig | 3 +-
22
+++ b/hw/misc/led.c
16
6 files changed, 63 insertions(+), 18 deletions(-)
23
@@ -XXX,XX +XXX,XX @@ static void led_set_state_gpio_handler(void *opaque, int line, int new_state)
17
24
LEDState *s = LED(opaque);
18
diff --git a/include/hw/arm/stm32l4x5_soc.h b/include/hw/arm/stm32l4x5_soc.h
25
19
index XXXXXXX..XXXXXXX 100644
26
assert(line == 0);
20
--- a/include/hw/arm/stm32l4x5_soc.h
27
- led_set_state(s, !!new_state != s->gpio_active_high);
21
+++ b/include/hw/arm/stm32l4x5_soc.h
28
+ led_set_state(s, !!new_state == s->gpio_active_high);
22
@@ -XXX,XX +XXX,XX @@
23
#include "hw/misc/stm32l4x5_syscfg.h"
24
#include "hw/misc/stm32l4x5_exti.h"
25
#include "hw/misc/stm32l4x5_rcc.h"
26
+#include "hw/gpio/stm32l4x5_gpio.h"
27
#include "qom/object.h"
28
29
#define TYPE_STM32L4X5_SOC "stm32l4x5-soc"
30
@@ -XXX,XX +XXX,XX @@ struct Stm32l4x5SocState {
31
OrIRQState exti_or_gates[NUM_EXTI_OR_GATES];
32
Stm32l4x5SyscfgState syscfg;
33
Stm32l4x5RccState rcc;
34
+ Stm32l4x5GpioState gpio[NUM_GPIOS];
35
36
MemoryRegion sram1;
37
MemoryRegion sram2;
38
diff --git a/include/hw/gpio/stm32l4x5_gpio.h b/include/hw/gpio/stm32l4x5_gpio.h
39
index XXXXXXX..XXXXXXX 100644
40
--- a/include/hw/gpio/stm32l4x5_gpio.h
41
+++ b/include/hw/gpio/stm32l4x5_gpio.h
42
@@ -XXX,XX +XXX,XX @@
43
#define TYPE_STM32L4X5_GPIO "stm32l4x5-gpio"
44
OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5GpioState, STM32L4X5_GPIO)
45
46
+#define NUM_GPIOS 8
47
#define GPIO_NUM_PINS 16
48
49
struct Stm32l4x5GpioState {
50
diff --git a/include/hw/misc/stm32l4x5_syscfg.h b/include/hw/misc/stm32l4x5_syscfg.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/include/hw/misc/stm32l4x5_syscfg.h
53
+++ b/include/hw/misc/stm32l4x5_syscfg.h
54
@@ -XXX,XX +XXX,XX @@
55
56
#include "hw/sysbus.h"
57
#include "qom/object.h"
58
+#include "hw/gpio/stm32l4x5_gpio.h"
59
60
#define TYPE_STM32L4X5_SYSCFG "stm32l4x5-syscfg"
61
OBJECT_DECLARE_SIMPLE_TYPE(Stm32l4x5SyscfgState, STM32L4X5_SYSCFG)
62
63
-#define NUM_GPIOS 8
64
-#define GPIO_NUM_PINS 16
65
#define SYSCFG_NUM_EXTICR 4
66
67
struct Stm32l4x5SyscfgState {
68
diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/stm32l4x5_soc.c
71
+++ b/hw/arm/stm32l4x5_soc.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "sysemu/sysemu.h"
74
#include "hw/or-irq.h"
75
#include "hw/arm/stm32l4x5_soc.h"
76
+#include "hw/gpio/stm32l4x5_gpio.h"
77
#include "hw/qdev-clock.h"
78
#include "hw/misc/unimp.h"
79
80
@@ -XXX,XX +XXX,XX @@ static const int exti_or_gate1_lines_in[EXTI_OR_GATE1_NUM_LINES_IN] = {
81
16, 35, 36, 37, 38,
82
};
83
84
+static const struct {
85
+ uint32_t addr;
86
+ uint32_t moder_reset;
87
+ uint32_t ospeedr_reset;
88
+ uint32_t pupdr_reset;
89
+} stm32l4x5_gpio_cfg[NUM_GPIOS] = {
90
+ { 0x48000000, 0xABFFFFFF, 0x0C000000, 0x64000000 },
91
+ { 0x48000400, 0xFFFFFEBF, 0x00000000, 0x00000100 },
92
+ { 0x48000800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
93
+ { 0x48000C00, 0xFFFFFFFF, 0x00000000, 0x00000000 },
94
+ { 0x48001000, 0xFFFFFFFF, 0x00000000, 0x00000000 },
95
+ { 0x48001400, 0xFFFFFFFF, 0x00000000, 0x00000000 },
96
+ { 0x48001800, 0xFFFFFFFF, 0x00000000, 0x00000000 },
97
+ { 0x48001C00, 0x0000000F, 0x00000000, 0x00000000 },
98
+};
99
+
100
static void stm32l4x5_soc_initfn(Object *obj)
101
{
102
Stm32l4x5SocState *s = STM32L4X5_SOC(obj);
103
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_initfn(Object *obj)
104
}
105
object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_STM32L4X5_SYSCFG);
106
object_initialize_child(obj, "rcc", &s->rcc, TYPE_STM32L4X5_RCC);
107
+
108
+ for (unsigned i = 0; i < NUM_GPIOS; i++) {
109
+ g_autofree char *name = g_strdup_printf("gpio%c", 'a' + i);
110
+ object_initialize_child(obj, name, &s->gpio[i], TYPE_STM32L4X5_GPIO);
111
+ }
29
}
112
}
30
113
31
static void led_reset(DeviceState *dev)
114
static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
115
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
116
Stm32l4x5SocState *s = STM32L4X5_SOC(dev_soc);
117
const Stm32l4x5SocClass *sc = STM32L4X5_SOC_GET_CLASS(dev_soc);
118
MemoryRegion *system_memory = get_system_memory();
119
- DeviceState *armv7m;
120
+ DeviceState *armv7m, *dev;
121
SysBusDevice *busdev;
122
+ uint32_t pin_index;
123
124
if (!memory_region_init_rom(&s->flash, OBJECT(dev_soc), "flash",
125
sc->flash_size, errp)) {
126
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
127
return;
128
}
129
130
+ /* GPIOs */
131
+ for (unsigned i = 0; i < NUM_GPIOS; i++) {
132
+ g_autofree char *name = g_strdup_printf("%c", 'A' + i);
133
+ dev = DEVICE(&s->gpio[i]);
134
+ qdev_prop_set_string(dev, "name", name);
135
+ qdev_prop_set_uint32(dev, "mode-reset",
136
+ stm32l4x5_gpio_cfg[i].moder_reset);
137
+ qdev_prop_set_uint32(dev, "ospeed-reset",
138
+ stm32l4x5_gpio_cfg[i].ospeedr_reset);
139
+ qdev_prop_set_uint32(dev, "pupd-reset",
140
+ stm32l4x5_gpio_cfg[i].pupdr_reset);
141
+ busdev = SYS_BUS_DEVICE(&s->gpio[i]);
142
+ g_free(name);
143
+ name = g_strdup_printf("gpio%c-out", 'a' + i);
144
+ qdev_connect_clock_in(DEVICE(&s->gpio[i]), "clk",
145
+ qdev_get_clock_out(DEVICE(&(s->rcc)), name));
146
+ if (!sysbus_realize(busdev, errp)) {
147
+ return;
148
+ }
149
+ sysbus_mmio_map(busdev, 0, stm32l4x5_gpio_cfg[i].addr);
150
+ }
151
+
152
/* System configuration controller */
153
busdev = SYS_BUS_DEVICE(&s->syscfg);
154
if (!sysbus_realize(busdev, errp)) {
155
return;
156
}
157
sysbus_mmio_map(busdev, 0, SYSCFG_ADDR);
158
- /*
159
- * TODO: when the GPIO device is implemented, connect it
160
- * to SYCFG using `qdev_connect_gpio_out`, NUM_GPIOS and
161
- * GPIO_NUM_PINS.
162
- */
163
+
164
+ for (unsigned i = 0; i < NUM_GPIOS; i++) {
165
+ for (unsigned j = 0; j < GPIO_NUM_PINS; j++) {
166
+ pin_index = GPIO_NUM_PINS * i + j;
167
+ qdev_connect_gpio_out(DEVICE(&s->gpio[i]), j,
168
+ qdev_get_gpio_in(DEVICE(&s->syscfg),
169
+ pin_index));
170
+ }
171
+ }
172
173
/* EXTI device */
174
busdev = SYS_BUS_DEVICE(&s->exti);
175
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
176
}
177
}
178
179
- for (unsigned i = 0; i < 16; i++) {
180
+ for (unsigned i = 0; i < GPIO_NUM_PINS; i++) {
181
qdev_connect_gpio_out(DEVICE(&s->syscfg), i,
182
qdev_get_gpio_in(DEVICE(&s->exti), i));
183
}
184
@@ -XXX,XX +XXX,XX @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp)
185
/* RESERVED: 0x40024400, 0x7FDBC00 */
186
187
/* AHB2 BUS */
188
- create_unimplemented_device("GPIOA", 0x48000000, 0x400);
189
- create_unimplemented_device("GPIOB", 0x48000400, 0x400);
190
- create_unimplemented_device("GPIOC", 0x48000800, 0x400);
191
- create_unimplemented_device("GPIOD", 0x48000C00, 0x400);
192
- create_unimplemented_device("GPIOE", 0x48001000, 0x400);
193
- create_unimplemented_device("GPIOF", 0x48001400, 0x400);
194
- create_unimplemented_device("GPIOG", 0x48001800, 0x400);
195
- create_unimplemented_device("GPIOH", 0x48001C00, 0x400);
196
/* RESERVED: 0x48002000, 0x7FDBC00 */
197
create_unimplemented_device("OTG_FS", 0x50000000, 0x40000);
198
create_unimplemented_device("ADC", 0x50040000, 0x400);
199
diff --git a/hw/misc/stm32l4x5_syscfg.c b/hw/misc/stm32l4x5_syscfg.c
200
index XXXXXXX..XXXXXXX 100644
201
--- a/hw/misc/stm32l4x5_syscfg.c
202
+++ b/hw/misc/stm32l4x5_syscfg.c
203
@@ -XXX,XX +XXX,XX @@
204
#include "hw/irq.h"
205
#include "migration/vmstate.h"
206
#include "hw/misc/stm32l4x5_syscfg.h"
207
+#include "hw/gpio/stm32l4x5_gpio.h"
208
209
#define SYSCFG_MEMRMP 0x00
210
#define SYSCFG_CFGR1 0x04
211
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
212
index XXXXXXX..XXXXXXX 100644
213
--- a/hw/arm/Kconfig
214
+++ b/hw/arm/Kconfig
215
@@ -XXX,XX +XXX,XX @@ config STM32L4X5_SOC
216
bool
217
select ARM_V7M
218
select OR_IRQ
219
- select STM32L4X5_SYSCFG
220
select STM32L4X5_EXTI
221
+ select STM32L4X5_SYSCFG
222
select STM32L4X5_RCC
223
+ select STM32L4X5_GPIO
224
225
config XLNX_ZYNQMP_ARM
226
bool
32
--
227
--
33
2.34.1
228
2.34.1
34
229
35
230
diff view generated by jsdifflib
1
From: Luc Michel <luc.michel@amd.com>
1
From: Inès Varhol <ines.varhol@telecom-paris.fr>
2
2
3
The CRC was stored in an unsigned variable in gem_receive. Change it for
3
The testcase contains :
4
a uint32_t to ensure we have the correct variable size here.
4
- `test_idr_reset_value()` :
5
Checks the reset values of MODER, OTYPER, PUPDR, ODR and IDR.
6
- `test_gpio_output_mode()` :
7
Checks that writing a bit in register ODR results in the corresponding
8
pin rising or lowering, if this pin is configured in output mode.
9
- `test_gpio_input_mode()` :
10
Checks that a input pin set high or low externally results
11
in the pin rising and lowering.
12
- `test_pull_up_pull_down()` :
13
Checks that a floating pin in pull-up/down mode is actually high/down.
14
- `test_push_pull()` :
15
Checks that a pin set externally is disconnected when configured in
16
push-pull output mode, and can't be set externally while in this mode.
17
- `test_open_drain()` :
18
Checks that a pin set externally high is disconnected when configured
19
in open-drain output mode, and can't be set high while in this mode.
20
- `test_bsrr_brr()` :
21
Checks that writing to BSRR and BRR has the desired result in ODR.
22
- `test_clock_enable()` :
23
Checks that GPIO clock is at the right frequency after enabling it.
5
24
6
Signed-off-by: Luc Michel <luc.michel@amd.com>
25
Acked-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
26
Signed-off-by: Arnaud Minier <arnaud.minier@telecom-paris.fr>
8
Reviewed-by: sai.pavan.boddu@amd.com
27
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
9
Message-id: 20231017194422.4124691-12-luc.michel@amd.com
28
Message-id: 20240305210444.310665-4-ines.varhol@telecom-paris.fr
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
29
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
30
---
12
hw/net/cadence_gem.c | 2 +-
31
tests/qtest/stm32l4x5_gpio-test.c | 551 ++++++++++++++++++++++++++++++
13
1 file changed, 1 insertion(+), 1 deletion(-)
32
tests/qtest/meson.build | 3 +-
33
2 files changed, 553 insertions(+), 1 deletion(-)
34
create mode 100644 tests/qtest/stm32l4x5_gpio-test.c
14
35
15
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
36
diff --git a/tests/qtest/stm32l4x5_gpio-test.c b/tests/qtest/stm32l4x5_gpio-test.c
37
new file mode 100644
38
index XXXXXXX..XXXXXXX
39
--- /dev/null
40
+++ b/tests/qtest/stm32l4x5_gpio-test.c
41
@@ -XXX,XX +XXX,XX @@
42
+/*
43
+ * QTest testcase for STM32L4x5_GPIO
44
+ *
45
+ * Copyright (c) 2024 Arnaud Minier <arnaud.minier@telecom-paris.fr>
46
+ * Copyright (c) 2024 Inès Varhol <ines.varhol@telecom-paris.fr>
47
+ *
48
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
49
+ * See the COPYING file in the top-level directory.
50
+ */
51
+
52
+#include "qemu/osdep.h"
53
+#include "libqtest-single.h"
54
+
55
+#define GPIO_BASE_ADDR 0x48000000
56
+#define GPIO_SIZE 0x400
57
+#define NUM_GPIOS 8
58
+#define NUM_GPIO_PINS 16
59
+
60
+#define GPIO_A 0x48000000
61
+#define GPIO_B 0x48000400
62
+#define GPIO_C 0x48000800
63
+#define GPIO_D 0x48000C00
64
+#define GPIO_E 0x48001000
65
+#define GPIO_F 0x48001400
66
+#define GPIO_G 0x48001800
67
+#define GPIO_H 0x48001C00
68
+
69
+#define MODER 0x00
70
+#define OTYPER 0x04
71
+#define PUPDR 0x0C
72
+#define IDR 0x10
73
+#define ODR 0x14
74
+#define BSRR 0x18
75
+#define BRR 0x28
76
+
77
+#define MODER_INPUT 0
78
+#define MODER_OUTPUT 1
79
+
80
+#define PUPDR_NONE 0
81
+#define PUPDR_PULLUP 1
82
+#define PUPDR_PULLDOWN 2
83
+
84
+#define OTYPER_PUSH_PULL 0
85
+#define OTYPER_OPEN_DRAIN 1
86
+
87
+const uint32_t moder_reset[NUM_GPIOS] = {
88
+ 0xABFFFFFF,
89
+ 0xFFFFFEBF,
90
+ 0xFFFFFFFF,
91
+ 0xFFFFFFFF,
92
+ 0xFFFFFFFF,
93
+ 0xFFFFFFFF,
94
+ 0xFFFFFFFF,
95
+ 0x0000000F
96
+};
97
+
98
+const uint32_t pupdr_reset[NUM_GPIOS] = {
99
+ 0x64000000,
100
+ 0x00000100,
101
+ 0x00000000,
102
+ 0x00000000,
103
+ 0x00000000,
104
+ 0x00000000,
105
+ 0x00000000,
106
+ 0x00000000
107
+};
108
+
109
+const uint32_t idr_reset[NUM_GPIOS] = {
110
+ 0x0000A000,
111
+ 0x00000010,
112
+ 0x00000000,
113
+ 0x00000000,
114
+ 0x00000000,
115
+ 0x00000000,
116
+ 0x00000000,
117
+ 0x00000000
118
+};
119
+
120
+static uint32_t gpio_readl(unsigned int gpio, unsigned int offset)
121
+{
122
+ return readl(gpio + offset);
123
+}
124
+
125
+static void gpio_writel(unsigned int gpio, unsigned int offset, uint32_t value)
126
+{
127
+ writel(gpio + offset, value);
128
+}
129
+
130
+static void gpio_set_bit(unsigned int gpio, unsigned int reg,
131
+ unsigned int pin, uint32_t value)
132
+{
133
+ uint32_t mask = 0xFFFFFFFF & ~(0x1 << pin);
134
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << pin);
135
+}
136
+
137
+static void gpio_set_2bits(unsigned int gpio, unsigned int reg,
138
+ unsigned int pin, uint32_t value)
139
+{
140
+ uint32_t offset = 2 * pin;
141
+ uint32_t mask = 0xFFFFFFFF & ~(0x3 << offset);
142
+ gpio_writel(gpio, reg, (gpio_readl(gpio, reg) & mask) | value << offset);
143
+}
144
+
145
+static unsigned int get_gpio_id(uint32_t gpio_addr)
146
+{
147
+ return (gpio_addr - GPIO_BASE_ADDR) / GPIO_SIZE;
148
+}
149
+
150
+static void gpio_set_irq(unsigned int gpio, int num, int level)
151
+{
152
+ g_autofree char *name = g_strdup_printf("/machine/soc/gpio%c",
153
+ get_gpio_id(gpio) + 'a');
154
+ qtest_set_irq_in(global_qtest, name, NULL, num, level);
155
+}
156
+
157
+static void disconnect_all_pins(unsigned int gpio)
158
+{
159
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
160
+ get_gpio_id(gpio) + 'a');
161
+ QDict *r;
162
+
163
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-set', 'arguments': "
164
+ "{ 'path': %s, 'property': 'disconnected-pins', 'value': %d } }",
165
+ path, 0xFFFF);
166
+ g_assert_false(qdict_haskey(r, "error"));
167
+ qobject_unref(r);
168
+}
169
+
170
+static uint32_t get_disconnected_pins(unsigned int gpio)
171
+{
172
+ g_autofree char *path = g_strdup_printf("/machine/soc/gpio%c",
173
+ get_gpio_id(gpio) + 'a');
174
+ uint32_t disconnected_pins = 0;
175
+ QDict *r;
176
+
177
+ r = qtest_qmp(global_qtest, "{ 'execute': 'qom-get', 'arguments':"
178
+ " { 'path': %s, 'property': 'disconnected-pins'} }", path);
179
+ g_assert_false(qdict_haskey(r, "error"));
180
+ disconnected_pins = qdict_get_int(r, "return");
181
+ qobject_unref(r);
182
+ return disconnected_pins;
183
+}
184
+
185
+static uint32_t reset(uint32_t gpio, unsigned int offset)
186
+{
187
+ switch (offset) {
188
+ case MODER:
189
+ return moder_reset[get_gpio_id(gpio)];
190
+ case PUPDR:
191
+ return pupdr_reset[get_gpio_id(gpio)];
192
+ case IDR:
193
+ return idr_reset[get_gpio_id(gpio)];
194
+ }
195
+ return 0x0;
196
+}
197
+
198
+static void system_reset(void)
199
+{
200
+ QDict *r;
201
+ r = qtest_qmp(global_qtest, "{'execute': 'system_reset'}");
202
+ g_assert_false(qdict_haskey(r, "error"));
203
+ qobject_unref(r);
204
+}
205
+
206
+static void test_idr_reset_value(void)
207
+{
208
+ /*
209
+ * Checks that the values in MODER, OTYPER, PUPDR and ODR
210
+ * after reset are correct, and that the value in IDR is
211
+ * coherent.
212
+ * Since AF and analog modes aren't implemented, IDR reset
213
+ * values aren't the same as with a real board.
214
+ *
215
+ * Register IDR contains the actual values of all GPIO pins.
216
+ * Its value depends on the pins' configuration
217
+ * (intput/output/analog : register MODER, push-pull/open-drain :
218
+ * register OTYPER, pull-up/pull-down/none : register PUPDR)
219
+ * and on the values stored in register ODR
220
+ * (in case the pin is in output mode).
221
+ */
222
+
223
+ gpio_writel(GPIO_A, MODER, 0xDEADBEEF);
224
+ gpio_writel(GPIO_A, ODR, 0xDEADBEEF);
225
+ gpio_writel(GPIO_A, OTYPER, 0xDEADBEEF);
226
+ gpio_writel(GPIO_A, PUPDR, 0xDEADBEEF);
227
+
228
+ gpio_writel(GPIO_B, MODER, 0xDEADBEEF);
229
+ gpio_writel(GPIO_B, ODR, 0xDEADBEEF);
230
+ gpio_writel(GPIO_B, OTYPER, 0xDEADBEEF);
231
+ gpio_writel(GPIO_B, PUPDR, 0xDEADBEEF);
232
+
233
+ gpio_writel(GPIO_C, MODER, 0xDEADBEEF);
234
+ gpio_writel(GPIO_C, ODR, 0xDEADBEEF);
235
+ gpio_writel(GPIO_C, OTYPER, 0xDEADBEEF);
236
+ gpio_writel(GPIO_C, PUPDR, 0xDEADBEEF);
237
+
238
+ gpio_writel(GPIO_H, MODER, 0xDEADBEEF);
239
+ gpio_writel(GPIO_H, ODR, 0xDEADBEEF);
240
+ gpio_writel(GPIO_H, OTYPER, 0xDEADBEEF);
241
+ gpio_writel(GPIO_H, PUPDR, 0xDEADBEEF);
242
+
243
+ system_reset();
244
+
245
+ uint32_t moder = gpio_readl(GPIO_A, MODER);
246
+ uint32_t odr = gpio_readl(GPIO_A, ODR);
247
+ uint32_t otyper = gpio_readl(GPIO_A, OTYPER);
248
+ uint32_t pupdr = gpio_readl(GPIO_A, PUPDR);
249
+ uint32_t idr = gpio_readl(GPIO_A, IDR);
250
+ /* 15: AF, 14: AF, 13: AF, 12: Analog ... */
251
+ /* here AF is the same as Analog and Input mode */
252
+ g_assert_cmphex(moder, ==, reset(GPIO_A, MODER));
253
+ g_assert_cmphex(odr, ==, reset(GPIO_A, ODR));
254
+ g_assert_cmphex(otyper, ==, reset(GPIO_A, OTYPER));
255
+ /* 15: pull-up, 14: pull-down, 13: pull-up, 12: neither ... */
256
+ g_assert_cmphex(pupdr, ==, reset(GPIO_A, PUPDR));
257
+ /* 15 : 1, 14: 0, 13: 1, 12 : reset value ... */
258
+ g_assert_cmphex(idr, ==, reset(GPIO_A, IDR));
259
+
260
+ moder = gpio_readl(GPIO_B, MODER);
261
+ odr = gpio_readl(GPIO_B, ODR);
262
+ otyper = gpio_readl(GPIO_B, OTYPER);
263
+ pupdr = gpio_readl(GPIO_B, PUPDR);
264
+ idr = gpio_readl(GPIO_B, IDR);
265
+ /* ... 5: Analog, 4: AF, 3: AF, 2: Analog ... */
266
+ /* here AF is the same as Analog and Input mode */
267
+ g_assert_cmphex(moder, ==, reset(GPIO_B, MODER));
268
+ g_assert_cmphex(odr, ==, reset(GPIO_B, ODR));
269
+ g_assert_cmphex(otyper, ==, reset(GPIO_B, OTYPER));
270
+ /* ... 5: neither, 4: pull-up, 3: neither ... */
271
+ g_assert_cmphex(pupdr, ==, reset(GPIO_B, PUPDR));
272
+ /* ... 5 : reset value, 4 : 1, 3 : reset value ... */
273
+ g_assert_cmphex(idr, ==, reset(GPIO_B, IDR));
274
+
275
+ moder = gpio_readl(GPIO_C, MODER);
276
+ odr = gpio_readl(GPIO_C, ODR);
277
+ otyper = gpio_readl(GPIO_C, OTYPER);
278
+ pupdr = gpio_readl(GPIO_C, PUPDR);
279
+ idr = gpio_readl(GPIO_C, IDR);
280
+ /* Analog, same as Input mode*/
281
+ g_assert_cmphex(moder, ==, reset(GPIO_C, MODER));
282
+ g_assert_cmphex(odr, ==, reset(GPIO_C, ODR));
283
+ g_assert_cmphex(otyper, ==, reset(GPIO_C, OTYPER));
284
+ /* no pull-up or pull-down */
285
+ g_assert_cmphex(pupdr, ==, reset(GPIO_C, PUPDR));
286
+ /* reset value */
287
+ g_assert_cmphex(idr, ==, reset(GPIO_C, IDR));
288
+
289
+ moder = gpio_readl(GPIO_H, MODER);
290
+ odr = gpio_readl(GPIO_H, ODR);
291
+ otyper = gpio_readl(GPIO_H, OTYPER);
292
+ pupdr = gpio_readl(GPIO_H, PUPDR);
293
+ idr = gpio_readl(GPIO_H, IDR);
294
+ /* Analog, same as Input mode */
295
+ g_assert_cmphex(moder, ==, reset(GPIO_H, MODER));
296
+ g_assert_cmphex(odr, ==, reset(GPIO_H, ODR));
297
+ g_assert_cmphex(otyper, ==, reset(GPIO_H, OTYPER));
298
+ /* no pull-up or pull-down */
299
+ g_assert_cmphex(pupdr, ==, reset(GPIO_H, PUPDR));
300
+ /* reset value */
301
+ g_assert_cmphex(idr, ==, reset(GPIO_H, IDR));
302
+}
303
+
304
+static void test_gpio_output_mode(const void *data)
305
+{
306
+ /*
307
+ * Checks that setting a bit in ODR sets the corresponding
308
+ * GPIO line high : it should set the right bit in IDR
309
+ * and send an irq to syscfg.
310
+ * Additionally, it checks that values written to ODR
311
+ * when not in output mode are stored and not discarded.
312
+ */
313
+ unsigned int pin = ((uint64_t)data) & 0xF;
314
+ uint32_t gpio = ((uint64_t)data) >> 32;
315
+ unsigned int gpio_id = get_gpio_id(gpio);
316
+
317
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
318
+
319
+ /* Set a bit in ODR and check nothing happens */
320
+ gpio_set_bit(gpio, ODR, pin, 1);
321
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
322
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
323
+
324
+ /* Configure the relevant line as output and check the pin is high */
325
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
326
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
327
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
328
+
329
+ /* Reset the bit in ODR and check the pin is low */
330
+ gpio_set_bit(gpio, ODR, pin, 0);
331
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
332
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
333
+
334
+ /* Clean the test */
335
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
336
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
337
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
338
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
339
+}
340
+
341
+static void test_gpio_input_mode(const void *data)
342
+{
343
+ /*
344
+ * Test that setting a line high/low externally sets the
345
+ * corresponding GPIO line high/low : it should set the
346
+ * right bit in IDR and send an irq to syscfg.
347
+ */
348
+ unsigned int pin = ((uint64_t)data) & 0xF;
349
+ uint32_t gpio = ((uint64_t)data) >> 32;
350
+ unsigned int gpio_id = get_gpio_id(gpio);
351
+
352
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
353
+
354
+ /* Configure a line as input, raise it, and check that the pin is high */
355
+ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
356
+ gpio_set_irq(gpio, pin, 1);
357
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
358
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
359
+
360
+ /* Lower the line and check that the pin is low */
361
+ gpio_set_irq(gpio, pin, 0);
362
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
363
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
364
+
365
+ /* Clean the test */
366
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
367
+ disconnect_all_pins(gpio);
368
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
369
+}
370
+
371
+static void test_pull_up_pull_down(const void *data)
372
+{
373
+ /*
374
+ * Test that a floating pin with pull-up sets the pin
375
+ * high and vice-versa.
376
+ */
377
+ unsigned int pin = ((uint64_t)data) & 0xF;
378
+ uint32_t gpio = ((uint64_t)data) >> 32;
379
+ unsigned int gpio_id = get_gpio_id(gpio);
380
+
381
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
382
+
383
+ /* Configure a line as input with pull-up, check the line is set high */
384
+ gpio_set_2bits(gpio, MODER, pin, MODER_INPUT);
385
+ gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLUP);
386
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) | (1 << pin));
387
+ g_assert_true(get_irq(gpio_id * NUM_GPIO_PINS + pin));
388
+
389
+ /* Configure the line with pull-down, check the line is low */
390
+ gpio_set_2bits(gpio, PUPDR, pin, PUPDR_PULLDOWN);
391
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
392
+ g_assert_false(get_irq(gpio_id * NUM_GPIO_PINS + pin));
393
+
394
+ /* Clean the test */
395
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
396
+ gpio_writel(gpio, PUPDR, reset(gpio, PUPDR));
397
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
398
+}
399
+
400
+static void test_push_pull(const void *data)
401
+{
402
+ /*
403
+ * Test that configuring a line in push-pull output mode
404
+ * disconnects the pin, that the pin can't be set or reset
405
+ * externally afterwards.
406
+ */
407
+ unsigned int pin = ((uint64_t)data) & 0xF;
408
+ uint32_t gpio = ((uint64_t)data) >> 32;
409
+ uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
410
+
411
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
412
+
413
+ /* Setting a line high externally, configuring it in push-pull output */
414
+ /* And checking the pin was disconnected */
415
+ gpio_set_irq(gpio, pin, 1);
416
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
417
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
418
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
419
+
420
+ /* Setting a line low externally, configuring it in push-pull output */
421
+ /* And checking the pin was disconnected */
422
+ gpio_set_irq(gpio2, pin, 0);
423
+ gpio_set_bit(gpio2, ODR, pin, 1);
424
+ gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT);
425
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF);
426
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin));
427
+
428
+ /* Trying to set a push-pull output pin, checking it doesn't work */
429
+ gpio_set_irq(gpio, pin, 1);
430
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
431
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
432
+
433
+ /* Trying to reset a push-pull output pin, checking it doesn't work */
434
+ gpio_set_irq(gpio2, pin, 0);
435
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF);
436
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR) | (1 << pin));
437
+
438
+ /* Clean the test */
439
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
440
+ gpio_writel(gpio2, ODR, reset(gpio2, ODR));
441
+ gpio_writel(gpio2, MODER, reset(gpio2, MODER));
442
+}
443
+
444
+static void test_open_drain(const void *data)
445
+{
446
+ /*
447
+ * Test that configuring a line in open-drain output mode
448
+ * disconnects a pin set high externally and that the pin
449
+ * can't be set high externally while configured in open-drain.
450
+ *
451
+ * However a pin set low externally shouldn't be disconnected,
452
+ * and it can be set low externally when in open-drain mode.
453
+ */
454
+ unsigned int pin = ((uint64_t)data) & 0xF;
455
+ uint32_t gpio = ((uint64_t)data) >> 32;
456
+ uint32_t gpio2 = GPIO_BASE_ADDR + (GPIO_H - gpio);
457
+
458
+ qtest_irq_intercept_in(global_qtest, "/machine/soc/syscfg");
459
+
460
+ /* Setting a line high externally, configuring it in open-drain output */
461
+ /* And checking the pin was disconnected */
462
+ gpio_set_irq(gpio, pin, 1);
463
+ gpio_set_bit(gpio, OTYPER, pin, OTYPER_OPEN_DRAIN);
464
+ gpio_set_2bits(gpio, MODER, pin, MODER_OUTPUT);
465
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
466
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
467
+
468
+ /* Setting a line low externally, configuring it in open-drain output */
469
+ /* And checking the pin wasn't disconnected */
470
+ gpio_set_irq(gpio2, pin, 0);
471
+ gpio_set_bit(gpio2, ODR, pin, 1);
472
+ gpio_set_bit(gpio2, OTYPER, pin, OTYPER_OPEN_DRAIN);
473
+ gpio_set_2bits(gpio2, MODER, pin, MODER_OUTPUT);
474
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin));
475
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==,
476
+ reset(gpio2, IDR) & ~(1 << pin));
477
+
478
+ /* Trying to set a open-drain output pin, checking it doesn't work */
479
+ gpio_set_irq(gpio, pin, 1);
480
+ g_assert_cmphex(get_disconnected_pins(gpio), ==, 0xFFFF);
481
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR) & ~(1 << pin));
482
+
483
+ /* Trying to reset a open-drain output pin, checking it works */
484
+ gpio_set_bit(gpio, ODR, pin, 1);
485
+ gpio_set_irq(gpio, pin, 0);
486
+ g_assert_cmphex(get_disconnected_pins(gpio2), ==, 0xFFFF & ~(1 << pin));
487
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==,
488
+ reset(gpio2, IDR) & ~(1 << pin));
489
+
490
+ /* Clean the test */
491
+ disconnect_all_pins(gpio2);
492
+ gpio_writel(gpio2, OTYPER, reset(gpio2, OTYPER));
493
+ gpio_writel(gpio2, ODR, reset(gpio2, ODR));
494
+ gpio_writel(gpio2, MODER, reset(gpio2, MODER));
495
+ g_assert_cmphex(gpio_readl(gpio2, IDR), ==, reset(gpio2, IDR));
496
+ disconnect_all_pins(gpio);
497
+ gpio_writel(gpio, OTYPER, reset(gpio, OTYPER));
498
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
499
+ gpio_writel(gpio, MODER, reset(gpio, MODER));
500
+ g_assert_cmphex(gpio_readl(gpio, IDR), ==, reset(gpio, IDR));
501
+}
502
+
503
+static void test_bsrr_brr(const void *data)
504
+{
505
+ /*
506
+ * Test that writing a '1' in BSS and BSRR
507
+ * has the desired effect on ODR.
508
+ * In BSRR, BSx has priority over BRx.
509
+ */
510
+ unsigned int pin = ((uint64_t)data) & 0xF;
511
+ uint32_t gpio = ((uint64_t)data) >> 32;
512
+
513
+ gpio_writel(gpio, BSRR, (1 << pin));
514
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
515
+
516
+ gpio_writel(gpio, BSRR, (1 << (pin + NUM_GPIO_PINS)));
517
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
518
+
519
+ gpio_writel(gpio, BSRR, (1 << pin));
520
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
521
+
522
+ gpio_writel(gpio, BRR, (1 << pin));
523
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
524
+
525
+ /* BSx should have priority over BRx */
526
+ gpio_writel(gpio, BSRR, (1 << pin) | (1 << (pin + NUM_GPIO_PINS)));
527
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR) | (1 << pin));
528
+
529
+ gpio_writel(gpio, BRR, (1 << pin));
530
+ g_assert_cmphex(gpio_readl(gpio, ODR), ==, reset(gpio, ODR));
531
+
532
+ gpio_writel(gpio, ODR, reset(gpio, ODR));
533
+}
534
+
535
+int main(int argc, char **argv)
536
+{
537
+ int ret;
538
+
539
+ g_test_init(&argc, &argv, NULL);
540
+ g_test_set_nonfatal_assertions();
541
+ qtest_add_func("stm32l4x5/gpio/test_idr_reset_value",
542
+ test_idr_reset_value);
543
+ /*
544
+ * The inputs for the tests (gpio and pin) can be changed,
545
+ * but the tests don't work for pins that are high at reset
546
+ * (GPIOA15, GPIO13 and GPIOB5).
547
+ * Specifically, rising the pin then checking `get_irq()`
548
+ * is problematic since the pin was already high.
549
+ */
550
+ qtest_add_data_func("stm32l4x5/gpio/test_gpioc5_output_mode",
551
+ (void *)((uint64_t)GPIO_C << 32 | 5),
552
+ test_gpio_output_mode);
553
+ qtest_add_data_func("stm32l4x5/gpio/test_gpioh3_output_mode",
554
+ (void *)((uint64_t)GPIO_H << 32 | 3),
555
+ test_gpio_output_mode);
556
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode1",
557
+ (void *)((uint64_t)GPIO_D << 32 | 6),
558
+ test_gpio_input_mode);
559
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_input_mode2",
560
+ (void *)((uint64_t)GPIO_C << 32 | 10),
561
+ test_gpio_input_mode);
562
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down1",
563
+ (void *)((uint64_t)GPIO_B << 32 | 5),
564
+ test_pull_up_pull_down);
565
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_pull_up_pull_down2",
566
+ (void *)((uint64_t)GPIO_F << 32 | 1),
567
+ test_pull_up_pull_down);
568
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull1",
569
+ (void *)((uint64_t)GPIO_G << 32 | 6),
570
+ test_push_pull);
571
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_push_pull2",
572
+ (void *)((uint64_t)GPIO_H << 32 | 3),
573
+ test_push_pull);
574
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain1",
575
+ (void *)((uint64_t)GPIO_C << 32 | 4),
576
+ test_open_drain);
577
+ qtest_add_data_func("stm32l4x5/gpio/test_gpio_open_drain2",
578
+ (void *)((uint64_t)GPIO_E << 32 | 11),
579
+ test_open_drain);
580
+ qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr1",
581
+ (void *)((uint64_t)GPIO_A << 32 | 12),
582
+ test_bsrr_brr);
583
+ qtest_add_data_func("stm32l4x5/gpio/test_bsrr_brr2",
584
+ (void *)((uint64_t)GPIO_D << 32 | 0),
585
+ test_bsrr_brr);
586
+
587
+ qtest_start("-machine b-l475e-iot01a");
588
+ ret = g_test_run();
589
+ qtest_end();
590
+
591
+ return ret;
592
+}
593
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
16
index XXXXXXX..XXXXXXX 100644
594
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/net/cadence_gem.c
595
--- a/tests/qtest/meson.build
18
+++ b/hw/net/cadence_gem.c
596
+++ b/tests/qtest/meson.build
19
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
597
@@ -XXX,XX +XXX,XX @@ qtests_aspeed = \
20
if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, FCS_REMOVE)) {
598
qtests_stm32l4x5 = \
21
rxbuf_ptr = (void *)buf;
599
['stm32l4x5_exti-test',
22
} else {
600
'stm32l4x5_syscfg-test',
23
- unsigned crc_val;
601
- 'stm32l4x5_rcc-test']
24
+ uint32_t crc_val;
602
+ 'stm32l4x5_rcc-test',
25
603
+ 'stm32l4x5_gpio-test']
26
if (size > MAX_FRAME_SIZE - sizeof(crc_val)) {
604
27
size = MAX_FRAME_SIZE - sizeof(crc_val);
605
qtests_arm = \
606
(config_all_devices.has_key('CONFIG_MPS2') ? ['sse-timer-test'] : []) + \
28
--
607
--
29
2.34.1
608
2.34.1
30
609
31
610
diff view generated by jsdifflib
1
Move all the ID_AA64DFR* feature test functions together.
1
From: Richard Henderson <richard.henderson@linaro.org>
2
2
3
While the 8-bit input elements are sequential in the input vector,
4
the 32-bit output elements are not sequential in the output matrix.
5
Do not attempt to compute 2 32-bit outputs at the same time.
6
7
Cc: qemu-stable@nongnu.org
8
Fixes: 23a5e3859f5 ("target/arm: Implement SME integer outer product")
9
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2083
10
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
11
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
12
Message-id: 20240305163931.242795-1-richard.henderson@linaro.org
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20231024163510.2972081-7-peter.maydell@linaro.org
7
---
14
---
8
target/arm/cpu-features.h | 10 +++++-----
15
target/arm/tcg/sme_helper.c | 77 ++++++++++++++++++-------------
9
1 file changed, 5 insertions(+), 5 deletions(-)
16
tests/tcg/aarch64/sme-smopa-1.c | 47 +++++++++++++++++++
10
17
tests/tcg/aarch64/sme-smopa-2.c | 54 ++++++++++++++++++++++
11
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
18
tests/tcg/aarch64/Makefile.target | 2 +-
19
4 files changed, 147 insertions(+), 33 deletions(-)
20
create mode 100644 tests/tcg/aarch64/sme-smopa-1.c
21
create mode 100644 tests/tcg/aarch64/sme-smopa-2.c
22
23
diff --git a/target/arm/tcg/sme_helper.c b/target/arm/tcg/sme_helper.c
12
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu-features.h
25
--- a/target/arm/tcg/sme_helper.c
14
+++ b/target/arm/cpu-features.h
26
+++ b/target/arm/tcg/sme_helper.c
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
27
@@ -XXX,XX +XXX,XX @@ void HELPER(sme_bfmopa)(void *vza, void *vzn, void *vzm, void *vpn,
16
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
28
}
17
}
29
}
18
30
19
+static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
31
-typedef uint64_t IMOPFn(uint64_t, uint64_t, uint64_t, uint8_t, bool);
32
+typedef uint32_t IMOPFn32(uint32_t, uint32_t, uint32_t, uint8_t, bool);
33
+static inline void do_imopa_s(uint32_t *za, uint32_t *zn, uint32_t *zm,
34
+ uint8_t *pn, uint8_t *pm,
35
+ uint32_t desc, IMOPFn32 *fn)
20
+{
36
+{
21
+ return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
37
+ intptr_t row, col, oprsz = simd_oprsz(desc) / 4;
38
+ bool neg = simd_data(desc);
39
40
-static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
41
- uint8_t *pn, uint8_t *pm,
42
- uint32_t desc, IMOPFn *fn)
43
+ for (row = 0; row < oprsz; ++row) {
44
+ uint8_t pa = (pn[H1(row >> 1)] >> ((row & 1) * 4)) & 0xf;
45
+ uint32_t *za_row = &za[tile_vslice_index(row)];
46
+ uint32_t n = zn[H4(row)];
47
+
48
+ for (col = 0; col < oprsz; ++col) {
49
+ uint8_t pb = pm[H1(col >> 1)] >> ((col & 1) * 4);
50
+ uint32_t *a = &za_row[H4(col)];
51
+
52
+ *a = fn(n, zm[H4(col)], *a, pa & pb, neg);
53
+ }
54
+ }
22
+}
55
+}
23
+
56
+
24
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
57
+typedef uint64_t IMOPFn64(uint64_t, uint64_t, uint64_t, uint8_t, bool);
58
+static inline void do_imopa_d(uint64_t *za, uint64_t *zn, uint64_t *zm,
59
+ uint8_t *pn, uint8_t *pm,
60
+ uint32_t desc, IMOPFn64 *fn)
25
{
61
{
26
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
62
intptr_t row, col, oprsz = simd_oprsz(desc) / 8;
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id)
63
bool neg = simd_data(desc);
28
return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64);
64
@@ -XXX,XX +XXX,XX @@ static inline void do_imopa(uint64_t *za, uint64_t *zn, uint64_t *zm,
29
}
65
}
30
66
31
-static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
67
#define DEF_IMOP_32(NAME, NTYPE, MTYPE) \
32
-{
68
-static uint64_t NAME(uint64_t n, uint64_t m, uint64_t a, uint8_t p, bool neg) \
33
- return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
69
+static uint32_t NAME(uint32_t n, uint32_t m, uint32_t a, uint8_t p, bool neg) \
34
-}
70
{ \
35
-
71
- uint32_t sum0 = 0, sum1 = 0; \
36
/*
72
+ uint32_t sum = 0; \
37
* Feature tests for "does this exist in either 32-bit or 64-bit?"
73
/* Apply P to N as a mask, making the inactive elements 0. */ \
38
*/
74
n &= expand_pred_b(p); \
75
- sum0 += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
76
- sum0 += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
77
- sum0 += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
78
- sum0 += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
79
- sum1 += (NTYPE)(n >> 32) * (MTYPE)(m >> 32); \
80
- sum1 += (NTYPE)(n >> 40) * (MTYPE)(m >> 40); \
81
- sum1 += (NTYPE)(n >> 48) * (MTYPE)(m >> 48); \
82
- sum1 += (NTYPE)(n >> 56) * (MTYPE)(m >> 56); \
83
- if (neg) { \
84
- sum0 = (uint32_t)a - sum0, sum1 = (uint32_t)(a >> 32) - sum1; \
85
- } else { \
86
- sum0 = (uint32_t)a + sum0, sum1 = (uint32_t)(a >> 32) + sum1; \
87
- } \
88
- return ((uint64_t)sum1 << 32) | sum0; \
89
+ sum += (NTYPE)(n >> 0) * (MTYPE)(m >> 0); \
90
+ sum += (NTYPE)(n >> 8) * (MTYPE)(m >> 8); \
91
+ sum += (NTYPE)(n >> 16) * (MTYPE)(m >> 16); \
92
+ sum += (NTYPE)(n >> 24) * (MTYPE)(m >> 24); \
93
+ return neg ? a - sum : a + sum; \
94
}
95
96
#define DEF_IMOP_64(NAME, NTYPE, MTYPE) \
97
@@ -XXX,XX +XXX,XX @@ DEF_IMOP_64(umopa_d, uint16_t, uint16_t)
98
DEF_IMOP_64(sumopa_d, int16_t, uint16_t)
99
DEF_IMOP_64(usmopa_d, uint16_t, int16_t)
100
101
-#define DEF_IMOPH(NAME) \
102
- void HELPER(sme_##NAME)(void *vza, void *vzn, void *vzm, void *vpn, \
103
- void *vpm, uint32_t desc) \
104
- { do_imopa(vza, vzn, vzm, vpn, vpm, desc, NAME); }
105
+#define DEF_IMOPH(NAME, S) \
106
+ void HELPER(sme_##NAME##_##S)(void *vza, void *vzn, void *vzm, \
107
+ void *vpn, void *vpm, uint32_t desc) \
108
+ { do_imopa_##S(vza, vzn, vzm, vpn, vpm, desc, NAME##_##S); }
109
110
-DEF_IMOPH(smopa_s)
111
-DEF_IMOPH(umopa_s)
112
-DEF_IMOPH(sumopa_s)
113
-DEF_IMOPH(usmopa_s)
114
-DEF_IMOPH(smopa_d)
115
-DEF_IMOPH(umopa_d)
116
-DEF_IMOPH(sumopa_d)
117
-DEF_IMOPH(usmopa_d)
118
+DEF_IMOPH(smopa, s)
119
+DEF_IMOPH(umopa, s)
120
+DEF_IMOPH(sumopa, s)
121
+DEF_IMOPH(usmopa, s)
122
+
123
+DEF_IMOPH(smopa, d)
124
+DEF_IMOPH(umopa, d)
125
+DEF_IMOPH(sumopa, d)
126
+DEF_IMOPH(usmopa, d)
127
diff --git a/tests/tcg/aarch64/sme-smopa-1.c b/tests/tcg/aarch64/sme-smopa-1.c
128
new file mode 100644
129
index XXXXXXX..XXXXXXX
130
--- /dev/null
131
+++ b/tests/tcg/aarch64/sme-smopa-1.c
132
@@ -XXX,XX +XXX,XX @@
133
+#include <stdio.h>
134
+#include <string.h>
135
+
136
+int main()
137
+{
138
+ static const int cmp[4][4] = {
139
+ { 110, 134, 158, 182 },
140
+ { 390, 478, 566, 654 },
141
+ { 670, 822, 974, 1126 },
142
+ { 950, 1166, 1382, 1598 }
143
+ };
144
+ int dst[4][4];
145
+ int *tmp = &dst[0][0];
146
+
147
+ asm volatile(
148
+ ".arch armv8-r+sme\n\t"
149
+ "smstart\n\t"
150
+ "index z0.b, #0, #1\n\t"
151
+ "movprfx z1, z0\n\t"
152
+ "add z1.b, z1.b, #16\n\t"
153
+ "ptrue p0.b\n\t"
154
+ "smopa za0.s, p0/m, p0/m, z0.b, z1.b\n\t"
155
+ "ptrue p0.s, vl4\n\t"
156
+ "mov w12, #0\n\t"
157
+ "st1w { za0h.s[w12, #0] }, p0, [%0]\n\t"
158
+ "add %0, %0, #16\n\t"
159
+ "st1w { za0h.s[w12, #1] }, p0, [%0]\n\t"
160
+ "add %0, %0, #16\n\t"
161
+ "st1w { za0h.s[w12, #2] }, p0, [%0]\n\t"
162
+ "add %0, %0, #16\n\t"
163
+ "st1w { za0h.s[w12, #3] }, p0, [%0]\n\t"
164
+ "smstop"
165
+ : "+r"(tmp) : : "memory");
166
+
167
+ if (memcmp(cmp, dst, sizeof(dst)) == 0) {
168
+ return 0;
169
+ }
170
+
171
+ /* See above for correct results. */
172
+ for (int i = 0; i < 4; ++i) {
173
+ for (int j = 0; j < 4; ++j) {
174
+ printf("%6d", dst[i][j]);
175
+ }
176
+ printf("\n");
177
+ }
178
+ return 1;
179
+}
180
diff --git a/tests/tcg/aarch64/sme-smopa-2.c b/tests/tcg/aarch64/sme-smopa-2.c
181
new file mode 100644
182
index XXXXXXX..XXXXXXX
183
--- /dev/null
184
+++ b/tests/tcg/aarch64/sme-smopa-2.c
185
@@ -XXX,XX +XXX,XX @@
186
+#include <stdio.h>
187
+#include <string.h>
188
+
189
+int main()
190
+{
191
+ static const long cmp[4][4] = {
192
+ { 110, 134, 158, 182 },
193
+ { 390, 478, 566, 654 },
194
+ { 670, 822, 974, 1126 },
195
+ { 950, 1166, 1382, 1598 }
196
+ };
197
+ long dst[4][4];
198
+ long *tmp = &dst[0][0];
199
+ long svl;
200
+
201
+ /* Validate that we have a wide enough vector for 4 elements. */
202
+ asm(".arch armv8-r+sme-i64\n\trdsvl %0, #1" : "=r"(svl));
203
+ if (svl < 32) {
204
+ return 0;
205
+ }
206
+
207
+ asm volatile(
208
+ "smstart\n\t"
209
+ "index z0.h, #0, #1\n\t"
210
+ "movprfx z1, z0\n\t"
211
+ "add z1.h, z1.h, #16\n\t"
212
+ "ptrue p0.b\n\t"
213
+ "smopa za0.d, p0/m, p0/m, z0.h, z1.h\n\t"
214
+ "ptrue p0.d, vl4\n\t"
215
+ "mov w12, #0\n\t"
216
+ "st1d { za0h.d[w12, #0] }, p0, [%0]\n\t"
217
+ "add %0, %0, #32\n\t"
218
+ "st1d { za0h.d[w12, #1] }, p0, [%0]\n\t"
219
+ "mov w12, #2\n\t"
220
+ "add %0, %0, #32\n\t"
221
+ "st1d { za0h.d[w12, #0] }, p0, [%0]\n\t"
222
+ "add %0, %0, #32\n\t"
223
+ "st1d { za0h.d[w12, #1] }, p0, [%0]\n\t"
224
+ "smstop"
225
+ : "+r"(tmp) : : "memory");
226
+
227
+ if (memcmp(cmp, dst, sizeof(dst)) == 0) {
228
+ return 0;
229
+ }
230
+
231
+ /* See above for correct results. */
232
+ for (int i = 0; i < 4; ++i) {
233
+ for (int j = 0; j < 4; ++j) {
234
+ printf("%6ld", dst[i][j]);
235
+ }
236
+ printf("\n");
237
+ }
238
+ return 1;
239
+}
240
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
241
index XXXXXXX..XXXXXXX 100644
242
--- a/tests/tcg/aarch64/Makefile.target
243
+++ b/tests/tcg/aarch64/Makefile.target
244
@@ -XXX,XX +XXX,XX @@ endif
245
246
# SME Tests
247
ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
248
-AARCH64_TESTS += sme-outprod1
249
+AARCH64_TESTS += sme-outprod1 sme-smopa-1 sme-smopa-2
250
endif
251
252
# System Registers Tests
39
--
253
--
40
2.34.1
254
2.34.1
41
255
42
256
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-2-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/allwinner-a10.h | 1 -
12
hw/arm/cubieboard.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/allwinner-a10.h
18
+++ b/include/hw/arm/allwinner-a10.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef HW_ARM_ALLWINNER_A10_H
21
#define HW_ARM_ALLWINNER_A10_H
22
23
-#include "hw/arm/boot.h"
24
#include "hw/timer/allwinner-a10-pit.h"
25
#include "hw/intc/allwinner-a10-pic.h"
26
#include "hw/net/allwinner_emac.h"
27
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/cubieboard.c
30
+++ b/hw/arm/cubieboard.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/boards.h"
33
#include "hw/qdev-properties.h"
34
#include "hw/arm/allwinner-a10.h"
35
+#include "hw/arm/boot.h"
36
#include "hw/i2c/i2c.h"
37
38
static struct arm_boot_info cubieboard_binfo = {
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-3-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/allwinner-h3.h | 1 -
12
hw/arm/orangepi.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/allwinner-h3.h
18
+++ b/include/hw/arm/allwinner-h3.h
19
@@ -XXX,XX +XXX,XX @@
20
#define HW_ARM_ALLWINNER_H3_H
21
22
#include "qom/object.h"
23
-#include "hw/arm/boot.h"
24
#include "hw/timer/allwinner-a10-pit.h"
25
#include "hw/intc/arm_gic.h"
26
#include "hw/misc/allwinner-h3-ccu.h"
27
diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/orangepi.c
30
+++ b/hw/arm/orangepi.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/boards.h"
33
#include "hw/qdev-properties.h"
34
#include "hw/arm/allwinner-h3.h"
35
+#include "hw/arm/boot.h"
36
37
static struct arm_boot_info orangepi_binfo;
38
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-4-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/allwinner-r40.h | 1 -
12
hw/arm/bananapi_m2u.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/allwinner-r40.h b/include/hw/arm/allwinner-r40.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/allwinner-r40.h
18
+++ b/include/hw/arm/allwinner-r40.h
19
@@ -XXX,XX +XXX,XX @@
20
#define HW_ARM_ALLWINNER_R40_H
21
22
#include "qom/object.h"
23
-#include "hw/arm/boot.h"
24
#include "hw/timer/allwinner-a10-pit.h"
25
#include "hw/intc/arm_gic.h"
26
#include "hw/sd/allwinner-sdhost.h"
27
diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/bananapi_m2u.c
30
+++ b/hw/arm/bananapi_m2u.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "hw/i2c/i2c.h"
33
#include "hw/qdev-properties.h"
34
#include "hw/arm/allwinner-r40.h"
35
+#include "hw/arm/boot.h"
36
37
static struct arm_boot_info bpim2u_binfo;
38
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-5-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx25.h | 1 -
12
hw/arm/imx25_pdk.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx25.h
18
+++ b/include/hw/arm/fsl-imx25.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef FSL_IMX25_H
21
#define FSL_IMX25_H
22
23
-#include "hw/arm/boot.h"
24
#include "hw/intc/imx_avic.h"
25
#include "hw/misc/imx25_ccm.h"
26
#include "hw/char/imx_serial.h"
27
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/imx25_pdk.c
30
+++ b/hw/arm/imx25_pdk.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qapi/error.h"
33
#include "hw/qdev-properties.h"
34
#include "hw/arm/fsl-imx25.h"
35
+#include "hw/arm/boot.h"
36
#include "hw/boards.h"
37
#include "qemu/error-report.h"
38
#include "sysemu/qtest.h"
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-6-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx31.h | 1 -
12
hw/arm/kzm.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx31.h
18
+++ b/include/hw/arm/fsl-imx31.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef FSL_IMX31_H
21
#define FSL_IMX31_H
22
23
-#include "hw/arm/boot.h"
24
#include "hw/intc/imx_avic.h"
25
#include "hw/misc/imx31_ccm.h"
26
#include "hw/char/imx_serial.h"
27
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/kzm.c
30
+++ b/hw/arm/kzm.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qemu/osdep.h"
33
#include "qapi/error.h"
34
#include "hw/arm/fsl-imx31.h"
35
+#include "hw/arm/boot.h"
36
#include "hw/boards.h"
37
#include "qemu/error-report.h"
38
#include "exec/address-spaces.h"
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-7-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx6.h | 1 -
12
hw/arm/sabrelite.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx6.h
18
+++ b/include/hw/arm/fsl-imx6.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef FSL_IMX6_H
21
#define FSL_IMX6_H
22
23
-#include "hw/arm/boot.h"
24
#include "hw/cpu/a9mpcore.h"
25
#include "hw/misc/imx6_ccm.h"
26
#include "hw/misc/imx6_src.h"
27
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/sabrelite.c
30
+++ b/hw/arm/sabrelite.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qemu/osdep.h"
33
#include "qapi/error.h"
34
#include "hw/arm/fsl-imx6.h"
35
+#include "hw/arm/boot.h"
36
#include "hw/boards.h"
37
#include "hw/qdev-properties.h"
38
#include "qemu/error-report.h"
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-8-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx6ul.h | 1 -
12
hw/arm/mcimx6ul-evk.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx6ul.h
18
+++ b/include/hw/arm/fsl-imx6ul.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef FSL_IMX6UL_H
21
#define FSL_IMX6UL_H
22
23
-#include "hw/arm/boot.h"
24
#include "hw/cpu/a15mpcore.h"
25
#include "hw/misc/imx6ul_ccm.h"
26
#include "hw/misc/imx6_src.h"
27
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/mcimx6ul-evk.c
30
+++ b/hw/arm/mcimx6ul-evk.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qemu/osdep.h"
33
#include "qapi/error.h"
34
#include "hw/arm/fsl-imx6ul.h"
35
+#include "hw/arm/boot.h"
36
#include "hw/boards.h"
37
#include "hw/qdev-properties.h"
38
#include "qemu/error-report.h"
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-9-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/fsl-imx7.h | 1 -
12
hw/arm/mcimx7d-sabre.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/fsl-imx7.h
18
+++ b/include/hw/arm/fsl-imx7.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef FSL_IMX7_H
21
#define FSL_IMX7_H
22
23
-#include "hw/arm/boot.h"
24
#include "hw/cpu/a15mpcore.h"
25
#include "hw/intc/imx_gpcv2.h"
26
#include "hw/misc/imx7_ccm.h"
27
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/mcimx7d-sabre.c
30
+++ b/hw/arm/mcimx7d-sabre.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qemu/osdep.h"
33
#include "qapi/error.h"
34
#include "hw/arm/fsl-imx7.h"
35
+#include "hw/arm/boot.h"
36
#include "hw/boards.h"
37
#include "hw/qdev-properties.h"
38
#include "qemu/error-report.h"
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-10-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/xlnx-versal.h | 1 -
12
hw/arm/xlnx-versal-virt.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-versal.h
18
+++ b/include/hw/arm/xlnx-versal.h
19
@@ -XXX,XX +XXX,XX @@
20
#define XLNX_VERSAL_H
21
22
#include "hw/sysbus.h"
23
-#include "hw/arm/boot.h"
24
#include "hw/cpu/cluster.h"
25
#include "hw/or-irq.h"
26
#include "hw/sd/sdhci.h"
27
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/xlnx-versal-virt.c
30
+++ b/hw/arm/xlnx-versal-virt.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "cpu.h"
33
#include "hw/qdev-properties.h"
34
#include "hw/arm/xlnx-versal.h"
35
+#include "hw/arm/boot.h"
36
#include "qom/object.h"
37
38
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
"hw/arm/boot.h" is only required on the source file.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-11-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
include/hw/arm/xlnx-zynqmp.h | 1 -
12
hw/arm/xlnx-zcu102.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
15
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/include/hw/arm/xlnx-zynqmp.h
18
+++ b/include/hw/arm/xlnx-zynqmp.h
19
@@ -XXX,XX +XXX,XX @@
20
#ifndef XLNX_ZYNQMP_H
21
#define XLNX_ZYNQMP_H
22
23
-#include "hw/arm/boot.h"
24
#include "hw/intc/arm_gic.h"
25
#include "hw/net/cadence_gem.h"
26
#include "hw/char/cadence_uart.h"
27
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/xlnx-zcu102.c
30
+++ b/hw/arm/xlnx-zcu102.c
31
@@ -XXX,XX +XXX,XX @@
32
#include "qemu/osdep.h"
33
#include "qapi/error.h"
34
#include "hw/arm/xlnx-zynqmp.h"
35
+#include "hw/arm/boot.h"
36
#include "hw/boards.h"
37
#include "qemu/error-report.h"
38
#include "qemu/log.h"
39
--
40
2.34.1
41
42
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20231020130331.50048-3-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/sd/pxa2xx_mmci.c | 7 +------
10
1 file changed, 1 insertion(+), 6 deletions(-)
11
12
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/sd/pxa2xx_mmci.c
15
+++ b/hw/sd/pxa2xx_mmci.c
16
@@ -XXX,XX +XXX,XX @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
17
qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma)
18
{
19
DeviceState *dev;
20
- SysBusDevice *sbd;
21
22
- dev = qdev_new(TYPE_PXA2XX_MMCI);
23
- sbd = SYS_BUS_DEVICE(dev);
24
- sysbus_realize_and_unref(sbd, &error_fatal);
25
- sysbus_mmio_map(sbd, 0, base);
26
- sysbus_connect_irq(sbd, 0, irq);
27
+ dev = sysbus_create_simple(TYPE_PXA2XX_MMCI, base, irq);
28
qdev_connect_gpio_out_named(dev, "rx-dma", 0, rx_dma);
29
qdev_connect_gpio_out_named(dev, "tx-dma", 0, tx_dma);
30
31
--
32
2.34.1
33
34
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
sysbus_mmio_map() should not be called on unrealized device.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Thomas Huth <thuth@redhat.com>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20231020130331.50048-4-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/pcmcia/pxa2xx.c | 7 ++-----
12
1 file changed, 2 insertions(+), 5 deletions(-)
13
14
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/pcmcia/pxa2xx.c
17
+++ b/hw/pcmcia/pxa2xx.c
18
@@ -XXX,XX +XXX,XX @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
19
hwaddr base)
20
{
21
DeviceState *dev;
22
- PXA2xxPCMCIAState *s;
23
24
dev = qdev_new(TYPE_PXA2XX_PCMCIA);
25
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
26
- s = PXA2XX_PCMCIA(dev);
27
-
28
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
29
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
30
31
- return s;
32
+ return PXA2XX_PCMCIA(dev);
33
}
34
35
static void pxa2xx_pcmcia_initfn(Object *obj)
36
--
37
2.34.1
38
39
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20231020130331.50048-5-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/pcmcia/pxa2xx.c | 4 +---
10
1 file changed, 1 insertion(+), 3 deletions(-)
11
12
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/pcmcia/pxa2xx.c
15
+++ b/hw/pcmcia/pxa2xx.c
16
@@ -XXX,XX +XXX,XX @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
17
{
18
DeviceState *dev;
19
20
- dev = qdev_new(TYPE_PXA2XX_PCMCIA);
21
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
22
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
23
+ dev = sysbus_create_simple(TYPE_PXA2XX_PCMCIA, base, NULL);
24
25
return PXA2XX_PCMCIA(dev);
26
}
27
--
28
2.34.1
29
30
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20231020130331.50048-6-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
include/hw/arm/pxa.h | 2 --
10
hw/arm/pxa2xx.c | 12 ++++++++----
11
hw/pcmcia/pxa2xx.c | 10 ----------
12
3 files changed, 8 insertions(+), 16 deletions(-)
13
14
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/arm/pxa.h
17
+++ b/include/hw/arm/pxa.h
18
@@ -XXX,XX +XXX,XX @@ void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
19
#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia"
20
OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA)
21
22
-PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
23
- hwaddr base);
24
int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card);
25
int pxa2xx_pcmcia_detach(void *opaque);
26
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
27
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/pxa2xx.c
30
+++ b/hw/arm/pxa2xx.c
31
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *cpu_type)
32
sysbus_create_simple("sysbus-ohci", 0x4c000000,
33
qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
34
35
- s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
36
- s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
37
+ s->pcmcia[0] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
38
+ 0x20000000, NULL));
39
+ s->pcmcia[1] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
40
+ 0x30000000, NULL));
41
42
sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
43
qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
44
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
45
s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
46
}
47
48
- s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
49
- s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
50
+ s->pcmcia[0] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
51
+ 0x20000000, NULL));
52
+ s->pcmcia[1] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
53
+ 0x30000000, NULL));
54
55
sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
56
qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
57
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/pcmcia/pxa2xx.c
60
+++ b/hw/pcmcia/pxa2xx.c
61
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
62
qemu_set_irq(s->irq, level);
63
}
64
65
-PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
66
- hwaddr base)
67
-{
68
- DeviceState *dev;
69
-
70
- dev = sysbus_create_simple(TYPE_PXA2XX_PCMCIA, base, NULL);
71
-
72
- return PXA2XX_PCMCIA(dev);
73
-}
74
-
75
static void pxa2xx_pcmcia_initfn(Object *obj)
76
{
77
SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
78
--
79
2.34.1
80
81
diff view generated by jsdifflib
1
From: Luc Michel <luc.michel@amd.com>
1
The sun4v RTC device model added under commit a0e893039cf2ce0 in 2016
2
was unfortunately added with a license of GPL-v3-or-later, which is
3
not compatible with other QEMU code which has a GPL-v2-only license.
2
4
3
Use the FIELD macro to describe the DESCONF6 register fields.
5
Relicense the code in the .c and the .h file to GPL-v2-or-later,
6
to make it compatible with the rest of QEMU.
4
7
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
Cc: qemu-stable@nongnu.org
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20231017194422.4124691-9-luc.michel@amd.com
10
Signed-off-by: Paolo Bonzini (for Red Hat) <pbonzini@redhat.com>
11
Signed-off-by: Artyom Tarasenko <atar4qemu@gmail.com>
12
Signed-off-by: Markus Armbruster <armbru@redhat.com>
13
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
14
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
15
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
16
Acked-by: Alex Bennée <alex.bennee@linaro.org>
17
Message-id: 20240223161300.938542-1-peter.maydell@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
19
---
10
hw/net/cadence_gem.c | 4 ++--
20
include/hw/rtc/sun4v-rtc.h | 2 +-
11
1 file changed, 2 insertions(+), 2 deletions(-)
21
hw/rtc/sun4v-rtc.c | 2 +-
22
2 files changed, 2 insertions(+), 2 deletions(-)
12
23
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
24
diff --git a/include/hw/rtc/sun4v-rtc.h b/include/hw/rtc/sun4v-rtc.h
14
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/cadence_gem.c
26
--- a/include/hw/rtc/sun4v-rtc.h
16
+++ b/hw/net/cadence_gem.c
27
+++ b/include/hw/rtc/sun4v-rtc.h
17
@@ -XXX,XX +XXX,XX @@ REG32(DESCONF3, 0x288)
28
@@ -XXX,XX +XXX,XX @@
18
REG32(DESCONF4, 0x28c)
29
*
19
REG32(DESCONF5, 0x290)
30
* Copyright (c) 2016 Artyom Tarasenko
20
REG32(DESCONF6, 0x294)
31
*
21
-#define GEM_DESCONF6_64B_MASK (1U << 23)
32
- * This code is licensed under the GNU GPL v3 or (at your option) any later
22
+ FIELD(DESCONF6, DMA_ADDR_64B, 23, 1)
33
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
23
REG32(DESCONF7, 0x298)
34
* version.
24
35
*/
25
REG32(INT_Q1_STATUS, 0x400)
36
26
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
37
diff --git a/hw/rtc/sun4v-rtc.c b/hw/rtc/sun4v-rtc.c
27
s->regs[R_DESCONF] = 0x02D00111;
38
index XXXXXXX..XXXXXXX 100644
28
s->regs[R_DESCONF2] = 0x2ab10000 | s->jumbo_max_len;
39
--- a/hw/rtc/sun4v-rtc.c
29
s->regs[R_DESCONF5] = 0x002f2045;
40
+++ b/hw/rtc/sun4v-rtc.c
30
- s->regs[R_DESCONF6] = GEM_DESCONF6_64B_MASK;
41
@@ -XXX,XX +XXX,XX @@
31
+ s->regs[R_DESCONF6] = R_DESCONF6_DMA_ADDR_64B_MASK;
42
*
32
s->regs[R_INT_Q1_MASK] = 0x00000CE6;
43
* Copyright (c) 2016 Artyom Tarasenko
33
s->regs[R_JUMBO_MAX_LEN] = s->jumbo_max_len;
44
*
45
- * This code is licensed under the GNU GPL v3 or (at your option) any later
46
+ * This code is licensed under the GNU GPL v2 or (at your option) any later
47
* version.
48
*/
34
49
35
--
50
--
36
2.34.1
51
2.34.1
37
52
38
53
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
1
From: Thomas Huth <thuth@redhat.com>
2
2
3
Factor reset code out of the DeviceRealize() handler.
3
Move the code to a separate file so that we do not have to compile
4
it anymore if CONFIG_ARM_V7M is not set.
4
5
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Thomas Huth <thuth@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20240308141051.536599-2-thuth@redhat.com
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20231020130331.50048-7-philmd@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
hw/arm/pxa2xx_pic.c | 17 ++++++++++++-----
11
target/arm/tcg/cpu-v7m.c | 290 +++++++++++++++++++++++++++++++++++++
12
1 file changed, 12 insertions(+), 5 deletions(-)
12
target/arm/tcg/cpu32.c | 261 ---------------------------------
13
target/arm/meson.build | 3 +
14
target/arm/tcg/meson.build | 3 +
15
4 files changed, 296 insertions(+), 261 deletions(-)
16
create mode 100644 target/arm/tcg/cpu-v7m.c
13
17
14
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
18
diff --git a/target/arm/tcg/cpu-v7m.c b/target/arm/tcg/cpu-v7m.c
19
new file mode 100644
20
index XXXXXXX..XXXXXXX
21
--- /dev/null
22
+++ b/target/arm/tcg/cpu-v7m.c
23
@@ -XXX,XX +XXX,XX @@
24
+/*
25
+ * QEMU ARMv7-M TCG-only CPUs.
26
+ *
27
+ * Copyright (c) 2012 SUSE LINUX Products GmbH
28
+ *
29
+ * This code is licensed under the GNU GPL v2 or later.
30
+ *
31
+ * SPDX-License-Identifier: GPL-2.0-or-later
32
+ */
33
+
34
+#include "qemu/osdep.h"
35
+#include "cpu.h"
36
+#include "hw/core/tcg-cpu-ops.h"
37
+#include "internals.h"
38
+
39
+#if !defined(CONFIG_USER_ONLY)
40
+
41
+#include "hw/intc/armv7m_nvic.h"
42
+
43
+static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
44
+{
45
+ CPUClass *cc = CPU_GET_CLASS(cs);
46
+ ARMCPU *cpu = ARM_CPU(cs);
47
+ CPUARMState *env = &cpu->env;
48
+ bool ret = false;
49
+
50
+ /*
51
+ * ARMv7-M interrupt masking works differently than -A or -R.
52
+ * There is no FIQ/IRQ distinction. Instead of I and F bits
53
+ * masking FIQ and IRQ interrupts, an exception is taken only
54
+ * if it is higher priority than the current execution priority
55
+ * (which depends on state like BASEPRI, FAULTMASK and the
56
+ * currently active exception).
57
+ */
58
+ if (interrupt_request & CPU_INTERRUPT_HARD
59
+ && (armv7m_nvic_can_take_pending_exception(env->nvic))) {
60
+ cs->exception_index = EXCP_IRQ;
61
+ cc->tcg_ops->do_interrupt(cs);
62
+ ret = true;
63
+ }
64
+ return ret;
65
+}
66
+
67
+#endif /* !CONFIG_USER_ONLY */
68
+
69
+static void cortex_m0_initfn(Object *obj)
70
+{
71
+ ARMCPU *cpu = ARM_CPU(obj);
72
+ set_feature(&cpu->env, ARM_FEATURE_V6);
73
+ set_feature(&cpu->env, ARM_FEATURE_M);
74
+
75
+ cpu->midr = 0x410cc200;
76
+
77
+ /*
78
+ * These ID register values are not guest visible, because
79
+ * we do not implement the Main Extension. They must be set
80
+ * to values corresponding to the Cortex-M0's implemented
81
+ * features, because QEMU generally controls its emulation
82
+ * by looking at ID register fields. We use the same values as
83
+ * for the M3.
84
+ */
85
+ cpu->isar.id_pfr0 = 0x00000030;
86
+ cpu->isar.id_pfr1 = 0x00000200;
87
+ cpu->isar.id_dfr0 = 0x00100000;
88
+ cpu->id_afr0 = 0x00000000;
89
+ cpu->isar.id_mmfr0 = 0x00000030;
90
+ cpu->isar.id_mmfr1 = 0x00000000;
91
+ cpu->isar.id_mmfr2 = 0x00000000;
92
+ cpu->isar.id_mmfr3 = 0x00000000;
93
+ cpu->isar.id_isar0 = 0x01141110;
94
+ cpu->isar.id_isar1 = 0x02111000;
95
+ cpu->isar.id_isar2 = 0x21112231;
96
+ cpu->isar.id_isar3 = 0x01111110;
97
+ cpu->isar.id_isar4 = 0x01310102;
98
+ cpu->isar.id_isar5 = 0x00000000;
99
+ cpu->isar.id_isar6 = 0x00000000;
100
+}
101
+
102
+static void cortex_m3_initfn(Object *obj)
103
+{
104
+ ARMCPU *cpu = ARM_CPU(obj);
105
+ set_feature(&cpu->env, ARM_FEATURE_V7);
106
+ set_feature(&cpu->env, ARM_FEATURE_M);
107
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
108
+ cpu->midr = 0x410fc231;
109
+ cpu->pmsav7_dregion = 8;
110
+ cpu->isar.id_pfr0 = 0x00000030;
111
+ cpu->isar.id_pfr1 = 0x00000200;
112
+ cpu->isar.id_dfr0 = 0x00100000;
113
+ cpu->id_afr0 = 0x00000000;
114
+ cpu->isar.id_mmfr0 = 0x00000030;
115
+ cpu->isar.id_mmfr1 = 0x00000000;
116
+ cpu->isar.id_mmfr2 = 0x00000000;
117
+ cpu->isar.id_mmfr3 = 0x00000000;
118
+ cpu->isar.id_isar0 = 0x01141110;
119
+ cpu->isar.id_isar1 = 0x02111000;
120
+ cpu->isar.id_isar2 = 0x21112231;
121
+ cpu->isar.id_isar3 = 0x01111110;
122
+ cpu->isar.id_isar4 = 0x01310102;
123
+ cpu->isar.id_isar5 = 0x00000000;
124
+ cpu->isar.id_isar6 = 0x00000000;
125
+}
126
+
127
+static void cortex_m4_initfn(Object *obj)
128
+{
129
+ ARMCPU *cpu = ARM_CPU(obj);
130
+
131
+ set_feature(&cpu->env, ARM_FEATURE_V7);
132
+ set_feature(&cpu->env, ARM_FEATURE_M);
133
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
134
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
135
+ cpu->midr = 0x410fc240; /* r0p0 */
136
+ cpu->pmsav7_dregion = 8;
137
+ cpu->isar.mvfr0 = 0x10110021;
138
+ cpu->isar.mvfr1 = 0x11000011;
139
+ cpu->isar.mvfr2 = 0x00000000;
140
+ cpu->isar.id_pfr0 = 0x00000030;
141
+ cpu->isar.id_pfr1 = 0x00000200;
142
+ cpu->isar.id_dfr0 = 0x00100000;
143
+ cpu->id_afr0 = 0x00000000;
144
+ cpu->isar.id_mmfr0 = 0x00000030;
145
+ cpu->isar.id_mmfr1 = 0x00000000;
146
+ cpu->isar.id_mmfr2 = 0x00000000;
147
+ cpu->isar.id_mmfr3 = 0x00000000;
148
+ cpu->isar.id_isar0 = 0x01141110;
149
+ cpu->isar.id_isar1 = 0x02111000;
150
+ cpu->isar.id_isar2 = 0x21112231;
151
+ cpu->isar.id_isar3 = 0x01111110;
152
+ cpu->isar.id_isar4 = 0x01310102;
153
+ cpu->isar.id_isar5 = 0x00000000;
154
+ cpu->isar.id_isar6 = 0x00000000;
155
+}
156
+
157
+static void cortex_m7_initfn(Object *obj)
158
+{
159
+ ARMCPU *cpu = ARM_CPU(obj);
160
+
161
+ set_feature(&cpu->env, ARM_FEATURE_V7);
162
+ set_feature(&cpu->env, ARM_FEATURE_M);
163
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
164
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
165
+ cpu->midr = 0x411fc272; /* r1p2 */
166
+ cpu->pmsav7_dregion = 8;
167
+ cpu->isar.mvfr0 = 0x10110221;
168
+ cpu->isar.mvfr1 = 0x12000011;
169
+ cpu->isar.mvfr2 = 0x00000040;
170
+ cpu->isar.id_pfr0 = 0x00000030;
171
+ cpu->isar.id_pfr1 = 0x00000200;
172
+ cpu->isar.id_dfr0 = 0x00100000;
173
+ cpu->id_afr0 = 0x00000000;
174
+ cpu->isar.id_mmfr0 = 0x00100030;
175
+ cpu->isar.id_mmfr1 = 0x00000000;
176
+ cpu->isar.id_mmfr2 = 0x01000000;
177
+ cpu->isar.id_mmfr3 = 0x00000000;
178
+ cpu->isar.id_isar0 = 0x01101110;
179
+ cpu->isar.id_isar1 = 0x02112000;
180
+ cpu->isar.id_isar2 = 0x20232231;
181
+ cpu->isar.id_isar3 = 0x01111131;
182
+ cpu->isar.id_isar4 = 0x01310132;
183
+ cpu->isar.id_isar5 = 0x00000000;
184
+ cpu->isar.id_isar6 = 0x00000000;
185
+}
186
+
187
+static void cortex_m33_initfn(Object *obj)
188
+{
189
+ ARMCPU *cpu = ARM_CPU(obj);
190
+
191
+ set_feature(&cpu->env, ARM_FEATURE_V8);
192
+ set_feature(&cpu->env, ARM_FEATURE_M);
193
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
194
+ set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
195
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
196
+ cpu->midr = 0x410fd213; /* r0p3 */
197
+ cpu->pmsav7_dregion = 16;
198
+ cpu->sau_sregion = 8;
199
+ cpu->isar.mvfr0 = 0x10110021;
200
+ cpu->isar.mvfr1 = 0x11000011;
201
+ cpu->isar.mvfr2 = 0x00000040;
202
+ cpu->isar.id_pfr0 = 0x00000030;
203
+ cpu->isar.id_pfr1 = 0x00000210;
204
+ cpu->isar.id_dfr0 = 0x00200000;
205
+ cpu->id_afr0 = 0x00000000;
206
+ cpu->isar.id_mmfr0 = 0x00101F40;
207
+ cpu->isar.id_mmfr1 = 0x00000000;
208
+ cpu->isar.id_mmfr2 = 0x01000000;
209
+ cpu->isar.id_mmfr3 = 0x00000000;
210
+ cpu->isar.id_isar0 = 0x01101110;
211
+ cpu->isar.id_isar1 = 0x02212000;
212
+ cpu->isar.id_isar2 = 0x20232232;
213
+ cpu->isar.id_isar3 = 0x01111131;
214
+ cpu->isar.id_isar4 = 0x01310132;
215
+ cpu->isar.id_isar5 = 0x00000000;
216
+ cpu->isar.id_isar6 = 0x00000000;
217
+ cpu->clidr = 0x00000000;
218
+ cpu->ctr = 0x8000c000;
219
+}
220
+
221
+static void cortex_m55_initfn(Object *obj)
222
+{
223
+ ARMCPU *cpu = ARM_CPU(obj);
224
+
225
+ set_feature(&cpu->env, ARM_FEATURE_V8);
226
+ set_feature(&cpu->env, ARM_FEATURE_V8_1M);
227
+ set_feature(&cpu->env, ARM_FEATURE_M);
228
+ set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
229
+ set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
230
+ set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
231
+ cpu->midr = 0x410fd221; /* r0p1 */
232
+ cpu->revidr = 0;
233
+ cpu->pmsav7_dregion = 16;
234
+ cpu->sau_sregion = 8;
235
+ /* These are the MVFR* values for the FPU + full MVE configuration */
236
+ cpu->isar.mvfr0 = 0x10110221;
237
+ cpu->isar.mvfr1 = 0x12100211;
238
+ cpu->isar.mvfr2 = 0x00000040;
239
+ cpu->isar.id_pfr0 = 0x20000030;
240
+ cpu->isar.id_pfr1 = 0x00000230;
241
+ cpu->isar.id_dfr0 = 0x10200000;
242
+ cpu->id_afr0 = 0x00000000;
243
+ cpu->isar.id_mmfr0 = 0x00111040;
244
+ cpu->isar.id_mmfr1 = 0x00000000;
245
+ cpu->isar.id_mmfr2 = 0x01000000;
246
+ cpu->isar.id_mmfr3 = 0x00000011;
247
+ cpu->isar.id_isar0 = 0x01103110;
248
+ cpu->isar.id_isar1 = 0x02212000;
249
+ cpu->isar.id_isar2 = 0x20232232;
250
+ cpu->isar.id_isar3 = 0x01111131;
251
+ cpu->isar.id_isar4 = 0x01310132;
252
+ cpu->isar.id_isar5 = 0x00000000;
253
+ cpu->isar.id_isar6 = 0x00000000;
254
+ cpu->clidr = 0x00000000; /* caches not implemented */
255
+ cpu->ctr = 0x8303c003;
256
+}
257
+
258
+static const TCGCPUOps arm_v7m_tcg_ops = {
259
+ .initialize = arm_translate_init,
260
+ .synchronize_from_tb = arm_cpu_synchronize_from_tb,
261
+ .debug_excp_handler = arm_debug_excp_handler,
262
+ .restore_state_to_opc = arm_restore_state_to_opc,
263
+
264
+#ifdef CONFIG_USER_ONLY
265
+ .record_sigsegv = arm_cpu_record_sigsegv,
266
+ .record_sigbus = arm_cpu_record_sigbus,
267
+#else
268
+ .tlb_fill = arm_cpu_tlb_fill,
269
+ .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
270
+ .do_interrupt = arm_v7m_cpu_do_interrupt,
271
+ .do_transaction_failed = arm_cpu_do_transaction_failed,
272
+ .do_unaligned_access = arm_cpu_do_unaligned_access,
273
+ .adjust_watchpoint_address = arm_adjust_watchpoint_address,
274
+ .debug_check_watchpoint = arm_debug_check_watchpoint,
275
+ .debug_check_breakpoint = arm_debug_check_breakpoint,
276
+#endif /* !CONFIG_USER_ONLY */
277
+};
278
+
279
+static void arm_v7m_class_init(ObjectClass *oc, void *data)
280
+{
281
+ ARMCPUClass *acc = ARM_CPU_CLASS(oc);
282
+ CPUClass *cc = CPU_CLASS(oc);
283
+
284
+ acc->info = data;
285
+ cc->tcg_ops = &arm_v7m_tcg_ops;
286
+ cc->gdb_core_xml_file = "arm-m-profile.xml";
287
+}
288
+
289
+static const ARMCPUInfo arm_v7m_cpus[] = {
290
+ { .name = "cortex-m0", .initfn = cortex_m0_initfn,
291
+ .class_init = arm_v7m_class_init },
292
+ { .name = "cortex-m3", .initfn = cortex_m3_initfn,
293
+ .class_init = arm_v7m_class_init },
294
+ { .name = "cortex-m4", .initfn = cortex_m4_initfn,
295
+ .class_init = arm_v7m_class_init },
296
+ { .name = "cortex-m7", .initfn = cortex_m7_initfn,
297
+ .class_init = arm_v7m_class_init },
298
+ { .name = "cortex-m33", .initfn = cortex_m33_initfn,
299
+ .class_init = arm_v7m_class_init },
300
+ { .name = "cortex-m55", .initfn = cortex_m55_initfn,
301
+ .class_init = arm_v7m_class_init },
302
+};
303
+
304
+static void arm_v7m_cpu_register_types(void)
305
+{
306
+ size_t i;
307
+
308
+ for (i = 0; i < ARRAY_SIZE(arm_v7m_cpus); ++i) {
309
+ arm_cpu_register(&arm_v7m_cpus[i]);
310
+ }
311
+}
312
+
313
+type_init(arm_v7m_cpu_register_types)
314
diff --git a/target/arm/tcg/cpu32.c b/target/arm/tcg/cpu32.c
15
index XXXXXXX..XXXXXXX 100644
315
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/arm/pxa2xx_pic.c
316
--- a/target/arm/tcg/cpu32.c
17
+++ b/hw/arm/pxa2xx_pic.c
317
+++ b/target/arm/tcg/cpu32.c
18
@@ -XXX,XX +XXX,XX @@ static int pxa2xx_pic_post_load(void *opaque, int version_id)
318
@@ -XXX,XX +XXX,XX @@
19
return 0;
319
#include "hw/boards.h"
320
#endif
321
#include "cpregs.h"
322
-#if !defined(CONFIG_USER_ONLY) && defined(CONFIG_TCG)
323
-#include "hw/intc/armv7m_nvic.h"
324
-#endif
325
326
327
/* Share AArch32 -cpu max features with AArch64. */
328
@@ -XXX,XX +XXX,XX @@ void aa32_max_features(ARMCPU *cpu)
329
/* CPU models. These are not needed for the AArch64 linux-user build. */
330
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
331
332
-#if !defined(CONFIG_USER_ONLY)
333
-static bool arm_v7m_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
334
-{
335
- CPUClass *cc = CPU_GET_CLASS(cs);
336
- ARMCPU *cpu = ARM_CPU(cs);
337
- CPUARMState *env = &cpu->env;
338
- bool ret = false;
339
-
340
- /*
341
- * ARMv7-M interrupt masking works differently than -A or -R.
342
- * There is no FIQ/IRQ distinction. Instead of I and F bits
343
- * masking FIQ and IRQ interrupts, an exception is taken only
344
- * if it is higher priority than the current execution priority
345
- * (which depends on state like BASEPRI, FAULTMASK and the
346
- * currently active exception).
347
- */
348
- if (interrupt_request & CPU_INTERRUPT_HARD
349
- && (armv7m_nvic_can_take_pending_exception(env->nvic))) {
350
- cs->exception_index = EXCP_IRQ;
351
- cc->tcg_ops->do_interrupt(cs);
352
- ret = true;
353
- }
354
- return ret;
355
-}
356
-#endif /* !CONFIG_USER_ONLY */
357
-
358
static void arm926_initfn(Object *obj)
359
{
360
ARMCPU *cpu = ARM_CPU(obj);
361
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
362
define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
20
}
363
}
21
364
22
-DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
365
-static void cortex_m0_initfn(Object *obj)
23
+static void pxa2xx_pic_reset_hold(Object *obj)
366
-{
24
{
367
- ARMCPU *cpu = ARM_CPU(obj);
25
- DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
368
- set_feature(&cpu->env, ARM_FEATURE_V6);
26
- PXA2xxPICState *s = PXA2XX_PIC(dev);
369
- set_feature(&cpu->env, ARM_FEATURE_M);
27
-
370
-
28
- s->cpu = cpu;
371
- cpu->midr = 0x410cc200;
29
+ PXA2xxPICState *s = PXA2XX_PIC(obj);
372
-
30
373
- /*
31
s->int_pending[0] = 0;
374
- * These ID register values are not guest visible, because
32
s->int_pending[1] = 0;
375
- * we do not implement the Main Extension. They must be set
33
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
376
- * to values corresponding to the Cortex-M0's implemented
34
s->int_enabled[1] = 0;
377
- * features, because QEMU generally controls its emulation
35
s->is_fiq[0] = 0;
378
- * by looking at ID register fields. We use the same values as
36
s->is_fiq[1] = 0;
379
- * for the M3.
37
+}
380
- */
38
+
381
- cpu->isar.id_pfr0 = 0x00000030;
39
+DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
382
- cpu->isar.id_pfr1 = 0x00000200;
40
+{
383
- cpu->isar.id_dfr0 = 0x00100000;
41
+ DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
384
- cpu->id_afr0 = 0x00000000;
42
+ PXA2xxPICState *s = PXA2XX_PIC(dev);
385
- cpu->isar.id_mmfr0 = 0x00000030;
43
+
386
- cpu->isar.id_mmfr1 = 0x00000000;
44
+ s->cpu = cpu;
387
- cpu->isar.id_mmfr2 = 0x00000000;
45
388
- cpu->isar.id_mmfr3 = 0x00000000;
46
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
389
- cpu->isar.id_isar0 = 0x01141110;
47
390
- cpu->isar.id_isar1 = 0x02111000;
48
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pxa2xx_pic_regs = {
391
- cpu->isar.id_isar2 = 0x21112231;
49
static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
392
- cpu->isar.id_isar3 = 0x01111110;
50
{
393
- cpu->isar.id_isar4 = 0x01310102;
51
DeviceClass *dc = DEVICE_CLASS(klass);
394
- cpu->isar.id_isar5 = 0x00000000;
52
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
395
- cpu->isar.id_isar6 = 0x00000000;
53
396
-}
54
dc->desc = "PXA2xx PIC";
397
-
55
dc->vmsd = &vmstate_pxa2xx_pic_regs;
398
-static void cortex_m3_initfn(Object *obj)
56
+ rc->phases.hold = pxa2xx_pic_reset_hold;
399
-{
400
- ARMCPU *cpu = ARM_CPU(obj);
401
- set_feature(&cpu->env, ARM_FEATURE_V7);
402
- set_feature(&cpu->env, ARM_FEATURE_M);
403
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
404
- cpu->midr = 0x410fc231;
405
- cpu->pmsav7_dregion = 8;
406
- cpu->isar.id_pfr0 = 0x00000030;
407
- cpu->isar.id_pfr1 = 0x00000200;
408
- cpu->isar.id_dfr0 = 0x00100000;
409
- cpu->id_afr0 = 0x00000000;
410
- cpu->isar.id_mmfr0 = 0x00000030;
411
- cpu->isar.id_mmfr1 = 0x00000000;
412
- cpu->isar.id_mmfr2 = 0x00000000;
413
- cpu->isar.id_mmfr3 = 0x00000000;
414
- cpu->isar.id_isar0 = 0x01141110;
415
- cpu->isar.id_isar1 = 0x02111000;
416
- cpu->isar.id_isar2 = 0x21112231;
417
- cpu->isar.id_isar3 = 0x01111110;
418
- cpu->isar.id_isar4 = 0x01310102;
419
- cpu->isar.id_isar5 = 0x00000000;
420
- cpu->isar.id_isar6 = 0x00000000;
421
-}
422
-
423
-static void cortex_m4_initfn(Object *obj)
424
-{
425
- ARMCPU *cpu = ARM_CPU(obj);
426
-
427
- set_feature(&cpu->env, ARM_FEATURE_V7);
428
- set_feature(&cpu->env, ARM_FEATURE_M);
429
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
430
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
431
- cpu->midr = 0x410fc240; /* r0p0 */
432
- cpu->pmsav7_dregion = 8;
433
- cpu->isar.mvfr0 = 0x10110021;
434
- cpu->isar.mvfr1 = 0x11000011;
435
- cpu->isar.mvfr2 = 0x00000000;
436
- cpu->isar.id_pfr0 = 0x00000030;
437
- cpu->isar.id_pfr1 = 0x00000200;
438
- cpu->isar.id_dfr0 = 0x00100000;
439
- cpu->id_afr0 = 0x00000000;
440
- cpu->isar.id_mmfr0 = 0x00000030;
441
- cpu->isar.id_mmfr1 = 0x00000000;
442
- cpu->isar.id_mmfr2 = 0x00000000;
443
- cpu->isar.id_mmfr3 = 0x00000000;
444
- cpu->isar.id_isar0 = 0x01141110;
445
- cpu->isar.id_isar1 = 0x02111000;
446
- cpu->isar.id_isar2 = 0x21112231;
447
- cpu->isar.id_isar3 = 0x01111110;
448
- cpu->isar.id_isar4 = 0x01310102;
449
- cpu->isar.id_isar5 = 0x00000000;
450
- cpu->isar.id_isar6 = 0x00000000;
451
-}
452
-
453
-static void cortex_m7_initfn(Object *obj)
454
-{
455
- ARMCPU *cpu = ARM_CPU(obj);
456
-
457
- set_feature(&cpu->env, ARM_FEATURE_V7);
458
- set_feature(&cpu->env, ARM_FEATURE_M);
459
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
460
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
461
- cpu->midr = 0x411fc272; /* r1p2 */
462
- cpu->pmsav7_dregion = 8;
463
- cpu->isar.mvfr0 = 0x10110221;
464
- cpu->isar.mvfr1 = 0x12000011;
465
- cpu->isar.mvfr2 = 0x00000040;
466
- cpu->isar.id_pfr0 = 0x00000030;
467
- cpu->isar.id_pfr1 = 0x00000200;
468
- cpu->isar.id_dfr0 = 0x00100000;
469
- cpu->id_afr0 = 0x00000000;
470
- cpu->isar.id_mmfr0 = 0x00100030;
471
- cpu->isar.id_mmfr1 = 0x00000000;
472
- cpu->isar.id_mmfr2 = 0x01000000;
473
- cpu->isar.id_mmfr3 = 0x00000000;
474
- cpu->isar.id_isar0 = 0x01101110;
475
- cpu->isar.id_isar1 = 0x02112000;
476
- cpu->isar.id_isar2 = 0x20232231;
477
- cpu->isar.id_isar3 = 0x01111131;
478
- cpu->isar.id_isar4 = 0x01310132;
479
- cpu->isar.id_isar5 = 0x00000000;
480
- cpu->isar.id_isar6 = 0x00000000;
481
-}
482
-
483
-static void cortex_m33_initfn(Object *obj)
484
-{
485
- ARMCPU *cpu = ARM_CPU(obj);
486
-
487
- set_feature(&cpu->env, ARM_FEATURE_V8);
488
- set_feature(&cpu->env, ARM_FEATURE_M);
489
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
490
- set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
491
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
492
- cpu->midr = 0x410fd213; /* r0p3 */
493
- cpu->pmsav7_dregion = 16;
494
- cpu->sau_sregion = 8;
495
- cpu->isar.mvfr0 = 0x10110021;
496
- cpu->isar.mvfr1 = 0x11000011;
497
- cpu->isar.mvfr2 = 0x00000040;
498
- cpu->isar.id_pfr0 = 0x00000030;
499
- cpu->isar.id_pfr1 = 0x00000210;
500
- cpu->isar.id_dfr0 = 0x00200000;
501
- cpu->id_afr0 = 0x00000000;
502
- cpu->isar.id_mmfr0 = 0x00101F40;
503
- cpu->isar.id_mmfr1 = 0x00000000;
504
- cpu->isar.id_mmfr2 = 0x01000000;
505
- cpu->isar.id_mmfr3 = 0x00000000;
506
- cpu->isar.id_isar0 = 0x01101110;
507
- cpu->isar.id_isar1 = 0x02212000;
508
- cpu->isar.id_isar2 = 0x20232232;
509
- cpu->isar.id_isar3 = 0x01111131;
510
- cpu->isar.id_isar4 = 0x01310132;
511
- cpu->isar.id_isar5 = 0x00000000;
512
- cpu->isar.id_isar6 = 0x00000000;
513
- cpu->clidr = 0x00000000;
514
- cpu->ctr = 0x8000c000;
515
-}
516
-
517
-static void cortex_m55_initfn(Object *obj)
518
-{
519
- ARMCPU *cpu = ARM_CPU(obj);
520
-
521
- set_feature(&cpu->env, ARM_FEATURE_V8);
522
- set_feature(&cpu->env, ARM_FEATURE_V8_1M);
523
- set_feature(&cpu->env, ARM_FEATURE_M);
524
- set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
525
- set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
526
- set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
527
- cpu->midr = 0x410fd221; /* r0p1 */
528
- cpu->revidr = 0;
529
- cpu->pmsav7_dregion = 16;
530
- cpu->sau_sregion = 8;
531
- /* These are the MVFR* values for the FPU + full MVE configuration */
532
- cpu->isar.mvfr0 = 0x10110221;
533
- cpu->isar.mvfr1 = 0x12100211;
534
- cpu->isar.mvfr2 = 0x00000040;
535
- cpu->isar.id_pfr0 = 0x20000030;
536
- cpu->isar.id_pfr1 = 0x00000230;
537
- cpu->isar.id_dfr0 = 0x10200000;
538
- cpu->id_afr0 = 0x00000000;
539
- cpu->isar.id_mmfr0 = 0x00111040;
540
- cpu->isar.id_mmfr1 = 0x00000000;
541
- cpu->isar.id_mmfr2 = 0x01000000;
542
- cpu->isar.id_mmfr3 = 0x00000011;
543
- cpu->isar.id_isar0 = 0x01103110;
544
- cpu->isar.id_isar1 = 0x02212000;
545
- cpu->isar.id_isar2 = 0x20232232;
546
- cpu->isar.id_isar3 = 0x01111131;
547
- cpu->isar.id_isar4 = 0x01310132;
548
- cpu->isar.id_isar5 = 0x00000000;
549
- cpu->isar.id_isar6 = 0x00000000;
550
- cpu->clidr = 0x00000000; /* caches not implemented */
551
- cpu->ctr = 0x8303c003;
552
-}
553
-
554
static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
555
/* Dummy the TCM region regs for the moment */
556
{ .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
557
@@ -XXX,XX +XXX,XX @@ static void pxa270c5_initfn(Object *obj)
558
cpu->reset_sctlr = 0x00000078;
57
}
559
}
58
560
59
static const TypeInfo pxa2xx_pic_info = {
561
-static const TCGCPUOps arm_v7m_tcg_ops = {
562
- .initialize = arm_translate_init,
563
- .synchronize_from_tb = arm_cpu_synchronize_from_tb,
564
- .debug_excp_handler = arm_debug_excp_handler,
565
- .restore_state_to_opc = arm_restore_state_to_opc,
566
-
567
-#ifdef CONFIG_USER_ONLY
568
- .record_sigsegv = arm_cpu_record_sigsegv,
569
- .record_sigbus = arm_cpu_record_sigbus,
570
-#else
571
- .tlb_fill = arm_cpu_tlb_fill,
572
- .cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt,
573
- .do_interrupt = arm_v7m_cpu_do_interrupt,
574
- .do_transaction_failed = arm_cpu_do_transaction_failed,
575
- .do_unaligned_access = arm_cpu_do_unaligned_access,
576
- .adjust_watchpoint_address = arm_adjust_watchpoint_address,
577
- .debug_check_watchpoint = arm_debug_check_watchpoint,
578
- .debug_check_breakpoint = arm_debug_check_breakpoint,
579
-#endif /* !CONFIG_USER_ONLY */
580
-};
581
-
582
-static void arm_v7m_class_init(ObjectClass *oc, void *data)
583
-{
584
- ARMCPUClass *acc = ARM_CPU_CLASS(oc);
585
- CPUClass *cc = CPU_CLASS(oc);
586
-
587
- acc->info = data;
588
- cc->tcg_ops = &arm_v7m_tcg_ops;
589
- cc->gdb_core_xml_file = "arm-m-profile.xml";
590
-}
591
-
592
#ifndef TARGET_AARCH64
593
/*
594
* -cpu max: a CPU with as many features enabled as our emulation supports.
595
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
596
{ .name = "cortex-a8", .initfn = cortex_a8_initfn },
597
{ .name = "cortex-a9", .initfn = cortex_a9_initfn },
598
{ .name = "cortex-a15", .initfn = cortex_a15_initfn },
599
- { .name = "cortex-m0", .initfn = cortex_m0_initfn,
600
- .class_init = arm_v7m_class_init },
601
- { .name = "cortex-m3", .initfn = cortex_m3_initfn,
602
- .class_init = arm_v7m_class_init },
603
- { .name = "cortex-m4", .initfn = cortex_m4_initfn,
604
- .class_init = arm_v7m_class_init },
605
- { .name = "cortex-m7", .initfn = cortex_m7_initfn,
606
- .class_init = arm_v7m_class_init },
607
- { .name = "cortex-m33", .initfn = cortex_m33_initfn,
608
- .class_init = arm_v7m_class_init },
609
- { .name = "cortex-m55", .initfn = cortex_m55_initfn,
610
- .class_init = arm_v7m_class_init },
611
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
612
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
613
{ .name = "cortex-r52", .initfn = cortex_r52_initfn },
614
diff --git a/target/arm/meson.build b/target/arm/meson.build
615
index XXXXXXX..XXXXXXX 100644
616
--- a/target/arm/meson.build
617
+++ b/target/arm/meson.build
618
@@ -XXX,XX +XXX,XX @@ arm_system_ss.add(files(
619
'ptw.c',
620
))
621
622
+arm_user_ss = ss.source_set()
623
+
624
subdir('hvf')
625
626
if 'CONFIG_TCG' in config_all_accel
627
@@ -XXX,XX +XXX,XX @@ endif
628
629
target_arch += {'arm': arm_ss}
630
target_system_arch += {'arm': arm_system_ss}
631
+target_user_arch += {'arm': arm_user_ss}
632
diff --git a/target/arm/tcg/meson.build b/target/arm/tcg/meson.build
633
index XXXXXXX..XXXXXXX 100644
634
--- a/target/arm/tcg/meson.build
635
+++ b/target/arm/tcg/meson.build
636
@@ -XXX,XX +XXX,XX @@ arm_ss.add(when: 'TARGET_AARCH64', if_true: files(
637
arm_system_ss.add(files(
638
'psci.c',
639
))
640
+
641
+arm_system_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('cpu-v7m.c'))
642
+arm_user_ss.add(when: 'TARGET_AARCH64', if_false: files('cpu-v7m.c'))
60
--
643
--
61
2.34.1
644
2.34.1
62
63
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
6
Message-id: 20231020130331.50048-9-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
9
hw/arm/pxa2xx_pic.c | 16 ++++++++++------
10
1 file changed, 10 insertions(+), 6 deletions(-)
11
12
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/pxa2xx_pic.c
15
+++ b/hw/arm/pxa2xx_pic.c
16
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_pic_reset_hold(Object *obj)
17
DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
18
{
19
DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
20
- PXA2xxPICState *s = PXA2XX_PIC(dev);
21
22
object_property_set_link(OBJECT(dev), "arm-cpu",
23
OBJECT(cpu), &error_abort);
24
-
25
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
26
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
27
+
28
+ return dev;
29
+}
30
+
31
+static void pxa2xx_pic_realize(DeviceState *dev, Error **errp)
32
+{
33
+ PXA2xxPICState *s = PXA2XX_PIC(dev);
34
35
qdev_init_gpio_in(dev, pxa2xx_pic_set_irq, PXA2XX_PIC_SRCS);
36
37
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
38
memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_pic_ops, s,
39
"pxa2xx-pic", 0x00100000);
40
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
41
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
42
43
/* Enable IC coprocessor access. */
44
- define_arm_cp_regs_with_opaque(cpu, pxa_pic_cp_reginfo, s);
45
-
46
- return dev;
47
+ define_arm_cp_regs_with_opaque(s->cpu, pxa_pic_cp_reginfo, s);
48
}
49
50
static const VMStateDescription vmstate_pxa2xx_pic_regs = {
51
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
52
ResettableClass *rc = RESETTABLE_CLASS(klass);
53
54
device_class_set_props(dc, pxa2xx_pic_properties);
55
+ dc->realize = pxa2xx_pic_realize;
56
dc->desc = "PXA2xx PIC";
57
dc->vmsd = &vmstate_pxa2xx_pic_regs;
58
rc->phases.hold = pxa2xx_pic_reset_hold;
59
--
60
2.34.1
61
62
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
qbus_new(), called in i2c_init_bus(), should not be called
4
on unrealized device.
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Thomas Huth <thuth@redhat.com>
9
Message-id: 20231020130331.50048-10-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
hw/arm/pxa2xx.c | 5 +++--
13
1 file changed, 3 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/arm/pxa2xx.c
18
+++ b/hw/arm/pxa2xx.c
19
@@ -XXX,XX +XXX,XX @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
20
qdev_prop_set_uint32(dev, "size", region_size + 1);
21
qdev_prop_set_uint32(dev, "offset", base & region_size);
22
23
+ /* FIXME: Should the slave device really be on a separate bus? */
24
+ i2cbus = i2c_init_bus(dev, "dummy");
25
+
26
i2c_dev = SYS_BUS_DEVICE(dev);
27
sysbus_realize_and_unref(i2c_dev, &error_fatal);
28
sysbus_mmio_map(i2c_dev, 0, base & ~region_size);
29
sysbus_connect_irq(i2c_dev, 0, irq);
30
31
s = PXA2XX_I2C(i2c_dev);
32
- /* FIXME: Should the slave device really be on a separate bus? */
33
- i2cbus = i2c_init_bus(dev, "dummy");
34
s->slave = PXA2XX_I2C_SLAVE(i2c_slave_create_simple(i2cbus,
35
TYPE_PXA2XX_I2C_SLAVE,
36
0));
37
--
38
2.34.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
1
3
Prefer using a well known local first CPU rather than a global one.
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20231025065909.57344-1-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/arm/bananapi_m2u.c | 2 +-
11
hw/arm/exynos4_boards.c | 7 ++++---
12
hw/arm/orangepi.c | 2 +-
13
hw/arm/realview.c | 2 +-
14
hw/arm/xilinx_zynq.c | 2 +-
15
5 files changed, 8 insertions(+), 7 deletions(-)
16
17
diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c
18
index XXXXXXX..XXXXXXX 100644
19
--- a/hw/arm/bananapi_m2u.c
20
+++ b/hw/arm/bananapi_m2u.c
21
@@ -XXX,XX +XXX,XX @@ static void bpim2u_init(MachineState *machine)
22
bpim2u_binfo.loader_start = r40->memmap[AW_R40_DEV_SDRAM];
23
bpim2u_binfo.ram_size = machine->ram_size;
24
bpim2u_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
25
- arm_load_kernel(ARM_CPU(first_cpu), machine, &bpim2u_binfo);
26
+ arm_load_kernel(&r40->cpus[0], machine, &bpim2u_binfo);
27
}
28
29
static void bpim2u_machine_init(MachineClass *mc)
30
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
31
index XXXXXXX..XXXXXXX 100644
32
--- a/hw/arm/exynos4_boards.c
33
+++ b/hw/arm/exynos4_boards.c
34
@@ -XXX,XX +XXX,XX @@ exynos4_boards_init_common(MachineState *machine,
35
36
static void nuri_init(MachineState *machine)
37
{
38
- exynos4_boards_init_common(machine, EXYNOS4_BOARD_NURI);
39
+ Exynos4BoardState *s = exynos4_boards_init_common(machine,
40
+ EXYNOS4_BOARD_NURI);
41
42
- arm_load_kernel(ARM_CPU(first_cpu), machine, &exynos4_board_binfo);
43
+ arm_load_kernel(s->soc.cpu[0], machine, &exynos4_board_binfo);
44
}
45
46
static void smdkc210_init(MachineState *machine)
47
@@ -XXX,XX +XXX,XX @@ static void smdkc210_init(MachineState *machine)
48
49
lan9215_init(SMDK_LAN9118_BASE_ADDR,
50
qemu_irq_invert(s->soc.irq_table[exynos4210_get_irq(37, 1)]));
51
- arm_load_kernel(ARM_CPU(first_cpu), machine, &exynos4_board_binfo);
52
+ arm_load_kernel(s->soc.cpu[0], machine, &exynos4_board_binfo);
53
}
54
55
static void nuri_class_init(ObjectClass *oc, void *data)
56
diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c
57
index XXXXXXX..XXXXXXX 100644
58
--- a/hw/arm/orangepi.c
59
+++ b/hw/arm/orangepi.c
60
@@ -XXX,XX +XXX,XX @@ static void orangepi_init(MachineState *machine)
61
orangepi_binfo.loader_start = h3->memmap[AW_H3_DEV_SDRAM];
62
orangepi_binfo.ram_size = machine->ram_size;
63
orangepi_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
64
- arm_load_kernel(ARM_CPU(first_cpu), machine, &orangepi_binfo);
65
+ arm_load_kernel(&h3->cpus[0], machine, &orangepi_binfo);
66
}
67
68
static void orangepi_machine_init(MachineClass *mc)
69
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/arm/realview.c
72
+++ b/hw/arm/realview.c
73
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
74
realview_binfo.ram_size = ram_size;
75
realview_binfo.board_id = realview_board_id[board_type];
76
realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
77
- arm_load_kernel(ARM_CPU(first_cpu), machine, &realview_binfo);
78
+ arm_load_kernel(cpu, machine, &realview_binfo);
79
}
80
81
static void realview_eb_init(MachineState *machine)
82
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
83
index XXXXXXX..XXXXXXX 100644
84
--- a/hw/arm/xilinx_zynq.c
85
+++ b/hw/arm/xilinx_zynq.c
86
@@ -XXX,XX +XXX,XX @@ static void zynq_init(MachineState *machine)
87
zynq_binfo.board_setup_addr = BOARD_SETUP_ADDR;
88
zynq_binfo.write_board_setup = zynq_write_board_setup;
89
90
- arm_load_kernel(ARM_CPU(first_cpu), machine, &zynq_binfo);
91
+ arm_load_kernel(cpu, machine, &zynq_binfo);
92
}
93
94
static void zynq_machine_class_init(ObjectClass *oc, void *data)
95
--
96
2.34.1
97
98
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Replace register defines with the REG32 macro from registerfields.h in
4
the Cadence GEM device.
5
6
Signed-off-by: Luc Michel <luc.michel@amd.com>
7
Reviewed-by: sai.pavan.boddu@amd.com
8
Message-id: 20231017194422.4124691-2-luc.michel@amd.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/net/cadence_gem.c | 527 +++++++++++++++++++++----------------------
12
1 file changed, 261 insertions(+), 266 deletions(-)
13
14
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/cadence_gem.c
17
+++ b/hw/net/cadence_gem.c
18
@@ -XXX,XX +XXX,XX @@
19
#include "hw/irq.h"
20
#include "hw/net/cadence_gem.h"
21
#include "hw/qdev-properties.h"
22
+#include "hw/registerfields.h"
23
#include "migration/vmstate.h"
24
#include "qapi/error.h"
25
#include "qemu/log.h"
26
@@ -XXX,XX +XXX,XX @@
27
} \
28
} while (0)
29
30
-#define GEM_NWCTRL (0x00000000 / 4) /* Network Control reg */
31
-#define GEM_NWCFG (0x00000004 / 4) /* Network Config reg */
32
-#define GEM_NWSTATUS (0x00000008 / 4) /* Network Status reg */
33
-#define GEM_USERIO (0x0000000C / 4) /* User IO reg */
34
-#define GEM_DMACFG (0x00000010 / 4) /* DMA Control reg */
35
-#define GEM_TXSTATUS (0x00000014 / 4) /* TX Status reg */
36
-#define GEM_RXQBASE (0x00000018 / 4) /* RX Q Base address reg */
37
-#define GEM_TXQBASE (0x0000001C / 4) /* TX Q Base address reg */
38
-#define GEM_RXSTATUS (0x00000020 / 4) /* RX Status reg */
39
-#define GEM_ISR (0x00000024 / 4) /* Interrupt Status reg */
40
-#define GEM_IER (0x00000028 / 4) /* Interrupt Enable reg */
41
-#define GEM_IDR (0x0000002C / 4) /* Interrupt Disable reg */
42
-#define GEM_IMR (0x00000030 / 4) /* Interrupt Mask reg */
43
-#define GEM_PHYMNTNC (0x00000034 / 4) /* Phy Maintenance reg */
44
-#define GEM_RXPAUSE (0x00000038 / 4) /* RX Pause Time reg */
45
-#define GEM_TXPAUSE (0x0000003C / 4) /* TX Pause Time reg */
46
-#define GEM_TXPARTIALSF (0x00000040 / 4) /* TX Partial Store and Forward */
47
-#define GEM_RXPARTIALSF (0x00000044 / 4) /* RX Partial Store and Forward */
48
-#define GEM_JUMBO_MAX_LEN (0x00000048 / 4) /* Max Jumbo Frame Size */
49
-#define GEM_HASHLO (0x00000080 / 4) /* Hash Low address reg */
50
-#define GEM_HASHHI (0x00000084 / 4) /* Hash High address reg */
51
-#define GEM_SPADDR1LO (0x00000088 / 4) /* Specific addr 1 low reg */
52
-#define GEM_SPADDR1HI (0x0000008C / 4) /* Specific addr 1 high reg */
53
-#define GEM_SPADDR2LO (0x00000090 / 4) /* Specific addr 2 low reg */
54
-#define GEM_SPADDR2HI (0x00000094 / 4) /* Specific addr 2 high reg */
55
-#define GEM_SPADDR3LO (0x00000098 / 4) /* Specific addr 3 low reg */
56
-#define GEM_SPADDR3HI (0x0000009C / 4) /* Specific addr 3 high reg */
57
-#define GEM_SPADDR4LO (0x000000A0 / 4) /* Specific addr 4 low reg */
58
-#define GEM_SPADDR4HI (0x000000A4 / 4) /* Specific addr 4 high reg */
59
-#define GEM_TIDMATCH1 (0x000000A8 / 4) /* Type ID1 Match reg */
60
-#define GEM_TIDMATCH2 (0x000000AC / 4) /* Type ID2 Match reg */
61
-#define GEM_TIDMATCH3 (0x000000B0 / 4) /* Type ID3 Match reg */
62
-#define GEM_TIDMATCH4 (0x000000B4 / 4) /* Type ID4 Match reg */
63
-#define GEM_WOLAN (0x000000B8 / 4) /* Wake on LAN reg */
64
-#define GEM_IPGSTRETCH (0x000000BC / 4) /* IPG Stretch reg */
65
-#define GEM_SVLAN (0x000000C0 / 4) /* Stacked VLAN reg */
66
-#define GEM_MODID (0x000000FC / 4) /* Module ID reg */
67
-#define GEM_OCTTXLO (0x00000100 / 4) /* Octets transmitted Low reg */
68
-#define GEM_OCTTXHI (0x00000104 / 4) /* Octets transmitted High reg */
69
-#define GEM_TXCNT (0x00000108 / 4) /* Error-free Frames transmitted */
70
-#define GEM_TXBCNT (0x0000010C / 4) /* Error-free Broadcast Frames */
71
-#define GEM_TXMCNT (0x00000110 / 4) /* Error-free Multicast Frame */
72
-#define GEM_TXPAUSECNT (0x00000114 / 4) /* Pause Frames Transmitted */
73
-#define GEM_TX64CNT (0x00000118 / 4) /* Error-free 64 TX */
74
-#define GEM_TX65CNT (0x0000011C / 4) /* Error-free 65-127 TX */
75
-#define GEM_TX128CNT (0x00000120 / 4) /* Error-free 128-255 TX */
76
-#define GEM_TX256CNT (0x00000124 / 4) /* Error-free 256-511 */
77
-#define GEM_TX512CNT (0x00000128 / 4) /* Error-free 512-1023 TX */
78
-#define GEM_TX1024CNT (0x0000012C / 4) /* Error-free 1024-1518 TX */
79
-#define GEM_TX1519CNT (0x00000130 / 4) /* Error-free larger than 1519 TX */
80
-#define GEM_TXURUNCNT (0x00000134 / 4) /* TX under run error counter */
81
-#define GEM_SINGLECOLLCNT (0x00000138 / 4) /* Single Collision Frames */
82
-#define GEM_MULTCOLLCNT (0x0000013C / 4) /* Multiple Collision Frames */
83
-#define GEM_EXCESSCOLLCNT (0x00000140 / 4) /* Excessive Collision Frames */
84
-#define GEM_LATECOLLCNT (0x00000144 / 4) /* Late Collision Frames */
85
-#define GEM_DEFERTXCNT (0x00000148 / 4) /* Deferred Transmission Frames */
86
-#define GEM_CSENSECNT (0x0000014C / 4) /* Carrier Sense Error Counter */
87
-#define GEM_OCTRXLO (0x00000150 / 4) /* Octets Received register Low */
88
-#define GEM_OCTRXHI (0x00000154 / 4) /* Octets Received register High */
89
-#define GEM_RXCNT (0x00000158 / 4) /* Error-free Frames Received */
90
-#define GEM_RXBROADCNT (0x0000015C / 4) /* Error-free Broadcast Frames RX */
91
-#define GEM_RXMULTICNT (0x00000160 / 4) /* Error-free Multicast Frames RX */
92
-#define GEM_RXPAUSECNT (0x00000164 / 4) /* Pause Frames Received Counter */
93
-#define GEM_RX64CNT (0x00000168 / 4) /* Error-free 64 byte Frames RX */
94
-#define GEM_RX65CNT (0x0000016C / 4) /* Error-free 65-127B Frames RX */
95
-#define GEM_RX128CNT (0x00000170 / 4) /* Error-free 128-255B Frames RX */
96
-#define GEM_RX256CNT (0x00000174 / 4) /* Error-free 256-512B Frames RX */
97
-#define GEM_RX512CNT (0x00000178 / 4) /* Error-free 512-1023B Frames RX */
98
-#define GEM_RX1024CNT (0x0000017C / 4) /* Error-free 1024-1518B Frames RX */
99
-#define GEM_RX1519CNT (0x00000180 / 4) /* Error-free 1519-max Frames RX */
100
-#define GEM_RXUNDERCNT (0x00000184 / 4) /* Undersize Frames Received */
101
-#define GEM_RXOVERCNT (0x00000188 / 4) /* Oversize Frames Received */
102
-#define GEM_RXJABCNT (0x0000018C / 4) /* Jabbers Received Counter */
103
-#define GEM_RXFCSCNT (0x00000190 / 4) /* Frame Check seq. Error Counter */
104
-#define GEM_RXLENERRCNT (0x00000194 / 4) /* Length Field Error Counter */
105
-#define GEM_RXSYMERRCNT (0x00000198 / 4) /* Symbol Error Counter */
106
-#define GEM_RXALIGNERRCNT (0x0000019C / 4) /* Alignment Error Counter */
107
-#define GEM_RXRSCERRCNT (0x000001A0 / 4) /* Receive Resource Error Counter */
108
-#define GEM_RXORUNCNT (0x000001A4 / 4) /* Receive Overrun Counter */
109
-#define GEM_RXIPCSERRCNT (0x000001A8 / 4) /* IP header Checksum Err Counter */
110
-#define GEM_RXTCPCCNT (0x000001AC / 4) /* TCP Checksum Error Counter */
111
-#define GEM_RXUDPCCNT (0x000001B0 / 4) /* UDP Checksum Error Counter */
112
+REG32(NWCTRL, 0x0) /* Network Control reg */
113
+REG32(NWCFG, 0x4) /* Network Config reg */
114
+REG32(NWSTATUS, 0x8) /* Network Status reg */
115
+REG32(USERIO, 0xc) /* User IO reg */
116
+REG32(DMACFG, 0x10) /* DMA Control reg */
117
+REG32(TXSTATUS, 0x14) /* TX Status reg */
118
+REG32(RXQBASE, 0x18) /* RX Q Base address reg */
119
+REG32(TXQBASE, 0x1c) /* TX Q Base address reg */
120
+REG32(RXSTATUS, 0x20) /* RX Status reg */
121
+REG32(ISR, 0x24) /* Interrupt Status reg */
122
+REG32(IER, 0x28) /* Interrupt Enable reg */
123
+REG32(IDR, 0x2c) /* Interrupt Disable reg */
124
+REG32(IMR, 0x30) /* Interrupt Mask reg */
125
+REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
126
+REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
127
+REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
128
+REG32(TXPARTIALSF, 0x40) /* TX Partial Store and Forward */
129
+REG32(RXPARTIALSF, 0x44) /* RX Partial Store and Forward */
130
+REG32(JUMBO_MAX_LEN, 0x48) /* Max Jumbo Frame Size */
131
+REG32(HASHLO, 0x80) /* Hash Low address reg */
132
+REG32(HASHHI, 0x84) /* Hash High address reg */
133
+REG32(SPADDR1LO, 0x88) /* Specific addr 1 low reg */
134
+REG32(SPADDR1HI, 0x8c) /* Specific addr 1 high reg */
135
+REG32(SPADDR2LO, 0x90) /* Specific addr 2 low reg */
136
+REG32(SPADDR2HI, 0x94) /* Specific addr 2 high reg */
137
+REG32(SPADDR3LO, 0x98) /* Specific addr 3 low reg */
138
+REG32(SPADDR3HI, 0x9c) /* Specific addr 3 high reg */
139
+REG32(SPADDR4LO, 0xa0) /* Specific addr 4 low reg */
140
+REG32(SPADDR4HI, 0xa4) /* Specific addr 4 high reg */
141
+REG32(TIDMATCH1, 0xa8) /* Type ID1 Match reg */
142
+REG32(TIDMATCH2, 0xac) /* Type ID2 Match reg */
143
+REG32(TIDMATCH3, 0xb0) /* Type ID3 Match reg */
144
+REG32(TIDMATCH4, 0xb4) /* Type ID4 Match reg */
145
+REG32(WOLAN, 0xb8) /* Wake on LAN reg */
146
+REG32(IPGSTRETCH, 0xbc) /* IPG Stretch reg */
147
+REG32(SVLAN, 0xc0) /* Stacked VLAN reg */
148
+REG32(MODID, 0xfc) /* Module ID reg */
149
+REG32(OCTTXLO, 0x100) /* Octects transmitted Low reg */
150
+REG32(OCTTXHI, 0x104) /* Octects transmitted High reg */
151
+REG32(TXCNT, 0x108) /* Error-free Frames transmitted */
152
+REG32(TXBCNT, 0x10c) /* Error-free Broadcast Frames */
153
+REG32(TXMCNT, 0x110) /* Error-free Multicast Frame */
154
+REG32(TXPAUSECNT, 0x114) /* Pause Frames Transmitted */
155
+REG32(TX64CNT, 0x118) /* Error-free 64 TX */
156
+REG32(TX65CNT, 0x11c) /* Error-free 65-127 TX */
157
+REG32(TX128CNT, 0x120) /* Error-free 128-255 TX */
158
+REG32(TX256CNT, 0x124) /* Error-free 256-511 */
159
+REG32(TX512CNT, 0x128) /* Error-free 512-1023 TX */
160
+REG32(TX1024CNT, 0x12c) /* Error-free 1024-1518 TX */
161
+REG32(TX1519CNT, 0x130) /* Error-free larger than 1519 TX */
162
+REG32(TXURUNCNT, 0x134) /* TX under run error counter */
163
+REG32(SINGLECOLLCNT, 0x138) /* Single Collision Frames */
164
+REG32(MULTCOLLCNT, 0x13c) /* Multiple Collision Frames */
165
+REG32(EXCESSCOLLCNT, 0x140) /* Excessive Collision Frames */
166
+REG32(LATECOLLCNT, 0x144) /* Late Collision Frames */
167
+REG32(DEFERTXCNT, 0x148) /* Deferred Transmission Frames */
168
+REG32(CSENSECNT, 0x14c) /* Carrier Sense Error Counter */
169
+REG32(OCTRXLO, 0x150) /* Octects Received register Low */
170
+REG32(OCTRXHI, 0x154) /* Octects Received register High */
171
+REG32(RXCNT, 0x158) /* Error-free Frames Received */
172
+REG32(RXBROADCNT, 0x15c) /* Error-free Broadcast Frames RX */
173
+REG32(RXMULTICNT, 0x160) /* Error-free Multicast Frames RX */
174
+REG32(RXPAUSECNT, 0x164) /* Pause Frames Received Counter */
175
+REG32(RX64CNT, 0x168) /* Error-free 64 byte Frames RX */
176
+REG32(RX65CNT, 0x16c) /* Error-free 65-127B Frames RX */
177
+REG32(RX128CNT, 0x170) /* Error-free 128-255B Frames RX */
178
+REG32(RX256CNT, 0x174) /* Error-free 256-512B Frames RX */
179
+REG32(RX512CNT, 0x178) /* Error-free 512-1023B Frames RX */
180
+REG32(RX1024CNT, 0x17c) /* Error-free 1024-1518B Frames RX */
181
+REG32(RX1519CNT, 0x180) /* Error-free 1519-max Frames RX */
182
+REG32(RXUNDERCNT, 0x184) /* Undersize Frames Received */
183
+REG32(RXOVERCNT, 0x188) /* Oversize Frames Received */
184
+REG32(RXJABCNT, 0x18c) /* Jabbers Received Counter */
185
+REG32(RXFCSCNT, 0x190) /* Frame Check seq. Error Counter */
186
+REG32(RXLENERRCNT, 0x194) /* Length Field Error Counter */
187
+REG32(RXSYMERRCNT, 0x198) /* Symbol Error Counter */
188
+REG32(RXALIGNERRCNT, 0x19c) /* Alignment Error Counter */
189
+REG32(RXRSCERRCNT, 0x1a0) /* Receive Resource Error Counter */
190
+REG32(RXORUNCNT, 0x1a4) /* Receive Overrun Counter */
191
+REG32(RXIPCSERRCNT, 0x1a8) /* IP header Checksum Err Counter */
192
+REG32(RXTCPCCNT, 0x1ac) /* TCP Checksum Error Counter */
193
+REG32(RXUDPCCNT, 0x1b0) /* UDP Checksum Error Counter */
194
195
-#define GEM_1588S (0x000001D0 / 4) /* 1588 Timer Seconds */
196
-#define GEM_1588NS (0x000001D4 / 4) /* 1588 Timer Nanoseconds */
197
-#define GEM_1588ADJ (0x000001D8 / 4) /* 1588 Timer Adjust */
198
-#define GEM_1588INC (0x000001DC / 4) /* 1588 Timer Increment */
199
-#define GEM_PTPETXS (0x000001E0 / 4) /* PTP Event Frame Transmitted (s) */
200
-#define GEM_PTPETXNS (0x000001E4 / 4) /*
201
- * PTP Event Frame Transmitted (ns)
202
- */
203
-#define GEM_PTPERXS (0x000001E8 / 4) /* PTP Event Frame Received (s) */
204
-#define GEM_PTPERXNS (0x000001EC / 4) /* PTP Event Frame Received (ns) */
205
-#define GEM_PTPPTXS (0x000001E0 / 4) /* PTP Peer Frame Transmitted (s) */
206
-#define GEM_PTPPTXNS (0x000001E4 / 4) /* PTP Peer Frame Transmitted (ns) */
207
-#define GEM_PTPPRXS (0x000001E8 / 4) /* PTP Peer Frame Received (s) */
208
-#define GEM_PTPPRXNS (0x000001EC / 4) /* PTP Peer Frame Received (ns) */
209
+REG32(1588S, 0x1d0) /* 1588 Timer Seconds */
210
+REG32(1588NS, 0x1d4) /* 1588 Timer Nanoseconds */
211
+REG32(1588ADJ, 0x1d8) /* 1588 Timer Adjust */
212
+REG32(1588INC, 0x1dc) /* 1588 Timer Increment */
213
+REG32(PTPETXS, 0x1e0) /* PTP Event Frame Transmitted (s) */
214
+REG32(PTPETXNS, 0x1e4) /* PTP Event Frame Transmitted (ns) */
215
+REG32(PTPERXS, 0x1e8) /* PTP Event Frame Received (s) */
216
+REG32(PTPERXNS, 0x1ec) /* PTP Event Frame Received (ns) */
217
+REG32(PTPPTXS, 0x1e0) /* PTP Peer Frame Transmitted (s) */
218
+REG32(PTPPTXNS, 0x1e4) /* PTP Peer Frame Transmitted (ns) */
219
+REG32(PTPPRXS, 0x1e8) /* PTP Peer Frame Received (s) */
220
+REG32(PTPPRXNS, 0x1ec) /* PTP Peer Frame Received (ns) */
221
222
/* Design Configuration Registers */
223
-#define GEM_DESCONF (0x00000280 / 4)
224
-#define GEM_DESCONF2 (0x00000284 / 4)
225
-#define GEM_DESCONF3 (0x00000288 / 4)
226
-#define GEM_DESCONF4 (0x0000028C / 4)
227
-#define GEM_DESCONF5 (0x00000290 / 4)
228
-#define GEM_DESCONF6 (0x00000294 / 4)
229
+REG32(DESCONF, 0x280)
230
+REG32(DESCONF2, 0x284)
231
+REG32(DESCONF3, 0x288)
232
+REG32(DESCONF4, 0x28c)
233
+REG32(DESCONF5, 0x290)
234
+REG32(DESCONF6, 0x294)
235
#define GEM_DESCONF6_64B_MASK (1U << 23)
236
-#define GEM_DESCONF7 (0x00000298 / 4)
237
+REG32(DESCONF7, 0x298)
238
239
-#define GEM_INT_Q1_STATUS (0x00000400 / 4)
240
-#define GEM_INT_Q1_MASK (0x00000640 / 4)
241
+REG32(INT_Q1_STATUS, 0x400)
242
+REG32(INT_Q1_MASK, 0x640)
243
244
-#define GEM_TRANSMIT_Q1_PTR (0x00000440 / 4)
245
-#define GEM_TRANSMIT_Q7_PTR (GEM_TRANSMIT_Q1_PTR + 6)
246
+REG32(TRANSMIT_Q1_PTR, 0x440)
247
+REG32(TRANSMIT_Q7_PTR, 0x458)
248
249
-#define GEM_RECEIVE_Q1_PTR (0x00000480 / 4)
250
-#define GEM_RECEIVE_Q7_PTR (GEM_RECEIVE_Q1_PTR + 6)
251
+REG32(RECEIVE_Q1_PTR, 0x480)
252
+REG32(RECEIVE_Q7_PTR, 0x498)
253
254
-#define GEM_TBQPH (0x000004C8 / 4)
255
-#define GEM_RBQPH (0x000004D4 / 4)
256
+REG32(TBQPH, 0x4c8)
257
+REG32(RBQPH, 0x4d4)
258
259
-#define GEM_INT_Q1_ENABLE (0x00000600 / 4)
260
-#define GEM_INT_Q7_ENABLE (GEM_INT_Q1_ENABLE + 6)
261
+REG32(INT_Q1_ENABLE, 0x600)
262
+REG32(INT_Q7_ENABLE, 0x618)
263
264
-#define GEM_INT_Q1_DISABLE (0x00000620 / 4)
265
-#define GEM_INT_Q7_DISABLE (GEM_INT_Q1_DISABLE + 6)
266
+REG32(INT_Q1_DISABLE, 0x620)
267
+REG32(INT_Q7_DISABLE, 0x638)
268
269
-#define GEM_INT_Q1_MASK (0x00000640 / 4)
270
-#define GEM_INT_Q7_MASK (GEM_INT_Q1_MASK + 6)
271
-
272
-#define GEM_SCREENING_TYPE1_REGISTER_0 (0x00000500 / 4)
273
+REG32(SCREENING_TYPE1_REG0, 0x500)
274
275
#define GEM_ST1R_UDP_PORT_MATCH_ENABLE (1 << 29)
276
#define GEM_ST1R_DSTC_ENABLE (1 << 28)
277
@@ -XXX,XX +XXX,XX @@
278
#define GEM_ST1R_QUEUE_SHIFT (0)
279
#define GEM_ST1R_QUEUE_WIDTH (3 - GEM_ST1R_QUEUE_SHIFT + 1)
280
281
-#define GEM_SCREENING_TYPE2_REGISTER_0 (0x00000540 / 4)
282
+REG32(SCREENING_TYPE2_REG0, 0x540)
283
284
#define GEM_ST2R_COMPARE_A_ENABLE (1 << 18)
285
#define GEM_ST2R_COMPARE_A_SHIFT (13)
286
@@ -XXX,XX +XXX,XX @@
287
#define GEM_ST2R_QUEUE_SHIFT (0)
288
#define GEM_ST2R_QUEUE_WIDTH (3 - GEM_ST2R_QUEUE_SHIFT + 1)
289
290
-#define GEM_SCREENING_TYPE2_ETHERTYPE_REG_0 (0x000006e0 / 4)
291
-#define GEM_TYPE2_COMPARE_0_WORD_0 (0x00000700 / 4)
292
+REG32(SCREENING_TYPE2_ETHERTYPE_REG0, 0x6e0)
293
+REG32(TYPE2_COMPARE_0_WORD_0, 0x700)
294
295
#define GEM_T2CW1_COMPARE_OFFSET_SHIFT (7)
296
#define GEM_T2CW1_COMPARE_OFFSET_WIDTH (8 - GEM_T2CW1_COMPARE_OFFSET_SHIFT + 1)
297
@@ -XXX,XX +XXX,XX @@ static inline uint64_t tx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
298
{
299
uint64_t ret = desc[0];
300
301
- if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
302
+ if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
303
ret |= (uint64_t)desc[2] << 32;
304
}
305
return ret;
306
@@ -XXX,XX +XXX,XX @@ static inline uint64_t rx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
307
{
308
uint64_t ret = desc[0] & ~0x3UL;
309
310
- if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
311
+ if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
312
ret |= (uint64_t)desc[2] << 32;
313
}
314
return ret;
315
@@ -XXX,XX +XXX,XX @@ static inline int gem_get_desc_len(CadenceGEMState *s, bool rx_n_tx)
316
{
317
int ret = 2;
318
319
- if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
320
+ if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
321
ret += 2;
322
}
323
- if (s->regs[GEM_DMACFG] & (rx_n_tx ? GEM_DMACFG_RX_BD_EXT
324
+ if (s->regs[R_DMACFG] & (rx_n_tx ? GEM_DMACFG_RX_BD_EXT
325
: GEM_DMACFG_TX_BD_EXT)) {
326
ret += 2;
327
}
328
@@ -XXX,XX +XXX,XX @@ static const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
329
static uint32_t gem_get_max_buf_len(CadenceGEMState *s, bool tx)
330
{
331
uint32_t size;
332
- if (s->regs[GEM_NWCFG] & GEM_NWCFG_JUMBO_FRAME) {
333
- size = s->regs[GEM_JUMBO_MAX_LEN];
334
+ if (s->regs[R_NWCFG] & GEM_NWCFG_JUMBO_FRAME) {
335
+ size = s->regs[R_JUMBO_MAX_LEN];
336
if (size > s->jumbo_max_len) {
337
size = s->jumbo_max_len;
338
qemu_log_mask(LOG_GUEST_ERROR, "GEM_JUMBO_MAX_LEN reg cannot be"
339
@@ -XXX,XX +XXX,XX @@ static uint32_t gem_get_max_buf_len(CadenceGEMState *s, bool tx)
340
} else if (tx) {
341
size = 1518;
342
} else {
343
- size = s->regs[GEM_NWCFG] & GEM_NWCFG_RCV_1538 ? 1538 : 1518;
344
+ size = s->regs[R_NWCFG] & GEM_NWCFG_RCV_1538 ? 1538 : 1518;
345
}
346
return size;
347
}
348
@@ -XXX,XX +XXX,XX @@ static uint32_t gem_get_max_buf_len(CadenceGEMState *s, bool tx)
349
static void gem_set_isr(CadenceGEMState *s, int q, uint32_t flag)
350
{
351
if (q == 0) {
352
- s->regs[GEM_ISR] |= flag & ~(s->regs[GEM_IMR]);
353
+ s->regs[R_ISR] |= flag & ~(s->regs[R_IMR]);
354
} else {
355
- s->regs[GEM_INT_Q1_STATUS + q - 1] |= flag &
356
- ~(s->regs[GEM_INT_Q1_MASK + q - 1]);
357
+ s->regs[R_INT_Q1_STATUS + q - 1] |= flag &
358
+ ~(s->regs[R_INT_Q1_MASK + q - 1]);
359
}
360
}
361
362
@@ -XXX,XX +XXX,XX @@ static void gem_init_register_masks(CadenceGEMState *s)
363
unsigned int i;
364
/* Mask of register bits which are read only */
365
memset(&s->regs_ro[0], 0, sizeof(s->regs_ro));
366
- s->regs_ro[GEM_NWCTRL] = 0xFFF80000;
367
- s->regs_ro[GEM_NWSTATUS] = 0xFFFFFFFF;
368
- s->regs_ro[GEM_DMACFG] = 0x8E00F000;
369
- s->regs_ro[GEM_TXSTATUS] = 0xFFFFFE08;
370
- s->regs_ro[GEM_RXQBASE] = 0x00000003;
371
- s->regs_ro[GEM_TXQBASE] = 0x00000003;
372
- s->regs_ro[GEM_RXSTATUS] = 0xFFFFFFF0;
373
- s->regs_ro[GEM_ISR] = 0xFFFFFFFF;
374
- s->regs_ro[GEM_IMR] = 0xFFFFFFFF;
375
- s->regs_ro[GEM_MODID] = 0xFFFFFFFF;
376
+ s->regs_ro[R_NWCTRL] = 0xFFF80000;
377
+ s->regs_ro[R_NWSTATUS] = 0xFFFFFFFF;
378
+ s->regs_ro[R_DMACFG] = 0x8E00F000;
379
+ s->regs_ro[R_TXSTATUS] = 0xFFFFFE08;
380
+ s->regs_ro[R_RXQBASE] = 0x00000003;
381
+ s->regs_ro[R_TXQBASE] = 0x00000003;
382
+ s->regs_ro[R_RXSTATUS] = 0xFFFFFFF0;
383
+ s->regs_ro[R_ISR] = 0xFFFFFFFF;
384
+ s->regs_ro[R_IMR] = 0xFFFFFFFF;
385
+ s->regs_ro[R_MODID] = 0xFFFFFFFF;
386
for (i = 0; i < s->num_priority_queues; i++) {
387
- s->regs_ro[GEM_INT_Q1_STATUS + i] = 0xFFFFFFFF;
388
- s->regs_ro[GEM_INT_Q1_ENABLE + i] = 0xFFFFF319;
389
- s->regs_ro[GEM_INT_Q1_DISABLE + i] = 0xFFFFF319;
390
- s->regs_ro[GEM_INT_Q1_MASK + i] = 0xFFFFFFFF;
391
+ s->regs_ro[R_INT_Q1_STATUS + i] = 0xFFFFFFFF;
392
+ s->regs_ro[R_INT_Q1_ENABLE + i] = 0xFFFFF319;
393
+ s->regs_ro[R_INT_Q1_DISABLE + i] = 0xFFFFF319;
394
+ s->regs_ro[R_INT_Q1_MASK + i] = 0xFFFFFFFF;
395
}
396
397
/* Mask of register bits which are clear on read */
398
memset(&s->regs_rtc[0], 0, sizeof(s->regs_rtc));
399
- s->regs_rtc[GEM_ISR] = 0xFFFFFFFF;
400
+ s->regs_rtc[R_ISR] = 0xFFFFFFFF;
401
for (i = 0; i < s->num_priority_queues; i++) {
402
- s->regs_rtc[GEM_INT_Q1_STATUS + i] = 0x00000CE6;
403
+ s->regs_rtc[R_INT_Q1_STATUS + i] = 0x00000CE6;
404
}
405
406
/* Mask of register bits which are write 1 to clear */
407
memset(&s->regs_w1c[0], 0, sizeof(s->regs_w1c));
408
- s->regs_w1c[GEM_TXSTATUS] = 0x000001F7;
409
- s->regs_w1c[GEM_RXSTATUS] = 0x0000000F;
410
+ s->regs_w1c[R_TXSTATUS] = 0x000001F7;
411
+ s->regs_w1c[R_RXSTATUS] = 0x0000000F;
412
413
/* Mask of register bits which are write only */
414
memset(&s->regs_wo[0], 0, sizeof(s->regs_wo));
415
- s->regs_wo[GEM_NWCTRL] = 0x00073E60;
416
- s->regs_wo[GEM_IER] = 0x07FFFFFF;
417
- s->regs_wo[GEM_IDR] = 0x07FFFFFF;
418
+ s->regs_wo[R_NWCTRL] = 0x00073E60;
419
+ s->regs_wo[R_IER] = 0x07FFFFFF;
420
+ s->regs_wo[R_IDR] = 0x07FFFFFF;
421
for (i = 0; i < s->num_priority_queues; i++) {
422
- s->regs_wo[GEM_INT_Q1_ENABLE + i] = 0x00000CE6;
423
- s->regs_wo[GEM_INT_Q1_DISABLE + i] = 0x00000CE6;
424
+ s->regs_wo[R_INT_Q1_ENABLE + i] = 0x00000CE6;
425
+ s->regs_wo[R_INT_Q1_DISABLE + i] = 0x00000CE6;
426
}
427
}
428
429
@@ -XXX,XX +XXX,XX @@ static bool gem_can_receive(NetClientState *nc)
430
s = qemu_get_nic_opaque(nc);
431
432
/* Do nothing if receive is not enabled. */
433
- if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_RXENA)) {
434
+ if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_RXENA)) {
435
if (s->can_rx_state != 1) {
436
s->can_rx_state = 1;
437
DB_PRINT("can't receive - no enable\n");
438
@@ -XXX,XX +XXX,XX @@ static void gem_update_int_status(CadenceGEMState *s)
439
{
440
int i;
441
442
- qemu_set_irq(s->irq[0], !!s->regs[GEM_ISR]);
443
+ qemu_set_irq(s->irq[0], !!s->regs[R_ISR]);
444
445
for (i = 1; i < s->num_priority_queues; ++i) {
446
- qemu_set_irq(s->irq[i], !!s->regs[GEM_INT_Q1_STATUS + i - 1]);
447
+ qemu_set_irq(s->irq[i], !!s->regs[R_INT_Q1_STATUS + i - 1]);
448
}
449
}
450
451
@@ -XXX,XX +XXX,XX @@ static void gem_receive_updatestats(CadenceGEMState *s, const uint8_t *packet,
452
uint64_t octets;
453
454
/* Total octets (bytes) received */
455
- octets = ((uint64_t)(s->regs[GEM_OCTRXLO]) << 32) |
456
- s->regs[GEM_OCTRXHI];
457
+ octets = ((uint64_t)(s->regs[R_OCTRXLO]) << 32) |
458
+ s->regs[R_OCTRXHI];
459
octets += bytes;
460
- s->regs[GEM_OCTRXLO] = octets >> 32;
461
- s->regs[GEM_OCTRXHI] = octets;
462
+ s->regs[R_OCTRXLO] = octets >> 32;
463
+ s->regs[R_OCTRXHI] = octets;
464
465
/* Error-free Frames received */
466
- s->regs[GEM_RXCNT]++;
467
+ s->regs[R_RXCNT]++;
468
469
/* Error-free Broadcast Frames counter */
470
if (!memcmp(packet, broadcast_addr, 6)) {
471
- s->regs[GEM_RXBROADCNT]++;
472
+ s->regs[R_RXBROADCNT]++;
473
}
474
475
/* Error-free Multicast Frames counter */
476
if (packet[0] == 0x01) {
477
- s->regs[GEM_RXMULTICNT]++;
478
+ s->regs[R_RXMULTICNT]++;
479
}
480
481
if (bytes <= 64) {
482
- s->regs[GEM_RX64CNT]++;
483
+ s->regs[R_RX64CNT]++;
484
} else if (bytes <= 127) {
485
- s->regs[GEM_RX65CNT]++;
486
+ s->regs[R_RX65CNT]++;
487
} else if (bytes <= 255) {
488
- s->regs[GEM_RX128CNT]++;
489
+ s->regs[R_RX128CNT]++;
490
} else if (bytes <= 511) {
491
- s->regs[GEM_RX256CNT]++;
492
+ s->regs[R_RX256CNT]++;
493
} else if (bytes <= 1023) {
494
- s->regs[GEM_RX512CNT]++;
495
+ s->regs[R_RX512CNT]++;
496
} else if (bytes <= 1518) {
497
- s->regs[GEM_RX1024CNT]++;
498
+ s->regs[R_RX1024CNT]++;
499
} else {
500
- s->regs[GEM_RX1519CNT]++;
501
+ s->regs[R_RX1519CNT]++;
502
}
503
}
504
505
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
506
int i, is_mc;
507
508
/* Promiscuous mode? */
509
- if (s->regs[GEM_NWCFG] & GEM_NWCFG_PROMISC) {
510
+ if (s->regs[R_NWCFG] & GEM_NWCFG_PROMISC) {
511
return GEM_RX_PROMISCUOUS_ACCEPT;
512
}
513
514
if (!memcmp(packet, broadcast_addr, 6)) {
515
/* Reject broadcast packets? */
516
- if (s->regs[GEM_NWCFG] & GEM_NWCFG_BCAST_REJ) {
517
+ if (s->regs[R_NWCFG] & GEM_NWCFG_BCAST_REJ) {
518
return GEM_RX_REJECT;
519
}
520
return GEM_RX_BROADCAST_ACCEPT;
521
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
522
523
/* Accept packets -w- hash match? */
524
is_mc = is_multicast_ether_addr(packet);
525
- if ((is_mc && (s->regs[GEM_NWCFG] & GEM_NWCFG_MCAST_HASH)) ||
526
- (!is_mc && (s->regs[GEM_NWCFG] & GEM_NWCFG_UCAST_HASH))) {
527
+ if ((is_mc && (s->regs[R_NWCFG] & GEM_NWCFG_MCAST_HASH)) ||
528
+ (!is_mc && (s->regs[R_NWCFG] & GEM_NWCFG_UCAST_HASH))) {
529
uint64_t buckets;
530
unsigned hash_index;
531
532
hash_index = calc_mac_hash(packet);
533
- buckets = ((uint64_t)s->regs[GEM_HASHHI] << 32) | s->regs[GEM_HASHLO];
534
+ buckets = ((uint64_t)s->regs[R_HASHHI] << 32) | s->regs[R_HASHLO];
535
if ((buckets >> hash_index) & 1) {
536
return is_mc ? GEM_RX_MULTICAST_HASH_ACCEPT
537
: GEM_RX_UNICAST_HASH_ACCEPT;
538
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
539
}
540
541
/* Check all 4 specific addresses */
542
- gem_spaddr = (uint8_t *)&(s->regs[GEM_SPADDR1LO]);
543
+ gem_spaddr = (uint8_t *)&(s->regs[R_SPADDR1LO]);
544
for (i = 3; i >= 0; i--) {
545
if (s->sar_active[i] && !memcmp(packet, gem_spaddr + 8 * i, 6)) {
546
return GEM_RX_SAR_ACCEPT + i;
547
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
548
int i, j;
549
550
for (i = 0; i < s->num_type1_screeners; i++) {
551
- reg = s->regs[GEM_SCREENING_TYPE1_REGISTER_0 + i];
552
+ reg = s->regs[R_SCREENING_TYPE1_REG0 + i];
553
matched = false;
554
mismatched = false;
555
556
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
557
}
558
559
for (i = 0; i < s->num_type2_screeners; i++) {
560
- reg = s->regs[GEM_SCREENING_TYPE2_REGISTER_0 + i];
561
+ reg = s->regs[R_SCREENING_TYPE2_REG0 + i];
562
matched = false;
563
mismatched = false;
564
565
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
566
qemu_log_mask(LOG_GUEST_ERROR, "Out of range ethertype "
567
"register index: %d\n", et_idx);
568
}
569
- if (type == s->regs[GEM_SCREENING_TYPE2_ETHERTYPE_REG_0 +
570
+ if (type == s->regs[R_SCREENING_TYPE2_ETHERTYPE_REG0 +
571
et_idx]) {
572
matched = true;
573
} else {
574
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
575
"register index: %d\n", cr_idx);
576
}
577
578
- cr0 = s->regs[GEM_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2];
579
- cr1 = s->regs[GEM_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2 + 1];
580
+ cr0 = s->regs[R_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2];
581
+ cr1 = s->regs[R_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2 + 1];
582
offset = extract32(cr1, GEM_T2CW1_OFFSET_VALUE_SHIFT,
583
GEM_T2CW1_OFFSET_VALUE_WIDTH);
584
585
@@ -XXX,XX +XXX,XX @@ static uint32_t gem_get_queue_base_addr(CadenceGEMState *s, bool tx, int q)
586
587
switch (q) {
588
case 0:
589
- base_addr = s->regs[tx ? GEM_TXQBASE : GEM_RXQBASE];
590
+ base_addr = s->regs[tx ? R_TXQBASE : R_RXQBASE];
591
break;
592
case 1 ... (MAX_PRIORITY_QUEUES - 1):
593
- base_addr = s->regs[(tx ? GEM_TRANSMIT_Q1_PTR :
594
- GEM_RECEIVE_Q1_PTR) + q - 1];
595
+ base_addr = s->regs[(tx ? R_TRANSMIT_Q1_PTR :
596
+ R_RECEIVE_Q1_PTR) + q - 1];
597
break;
598
default:
599
g_assert_not_reached();
600
@@ -XXX,XX +XXX,XX @@ static hwaddr gem_get_desc_addr(CadenceGEMState *s, bool tx, int q)
601
{
602
hwaddr desc_addr = 0;
603
604
- if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
605
- desc_addr = s->regs[tx ? GEM_TBQPH : GEM_RBQPH];
606
+ if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
607
+ desc_addr = s->regs[tx ? R_TBQPH : R_RBQPH];
608
}
609
desc_addr <<= 32;
610
desc_addr |= tx ? s->tx_desc_addr[q] : s->rx_desc_addr[q];
611
@@ -XXX,XX +XXX,XX @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
612
/* Descriptor owned by software ? */
613
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
614
DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
615
- s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
616
+ s->regs[R_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
617
gem_set_isr(s, q, GEM_INT_RXUSED);
618
/* Handle interrupt consequences */
619
gem_update_int_status(s);
620
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
621
}
622
623
/* Discard packets with receive length error enabled ? */
624
- if (s->regs[GEM_NWCFG] & GEM_NWCFG_LERR_DISC) {
625
+ if (s->regs[R_NWCFG] & GEM_NWCFG_LERR_DISC) {
626
unsigned type_len;
627
628
/* Fish the ethertype / length field out of the RX packet */
629
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
630
/*
631
* Determine configured receive buffer offset (probably 0)
632
*/
633
- rxbuf_offset = (s->regs[GEM_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>
634
+ rxbuf_offset = (s->regs[R_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>
635
GEM_NWCFG_BUFF_OFST_S;
636
637
/* The configure size of each receive buffer. Determines how many
638
* buffers needed to hold this packet.
639
*/
640
- rxbufsize = ((s->regs[GEM_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>
641
+ rxbufsize = ((s->regs[R_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>
642
GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
643
bytes_to_copy = size;
644
645
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
646
}
647
648
/* Strip of FCS field ? (usually yes) */
649
- if (s->regs[GEM_NWCFG] & GEM_NWCFG_STRIP_FCS) {
650
+ if (s->regs[R_NWCFG] & GEM_NWCFG_STRIP_FCS) {
651
rxbuf_ptr = (void *)buf;
652
} else {
653
unsigned crc_val;
654
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
655
/* Count it */
656
gem_receive_updatestats(s, buf, size);
657
658
- s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;
659
+ s->regs[R_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;
660
gem_set_isr(s, q, GEM_INT_RXCMPL);
661
662
/* Handle interrupt consequences */
663
@@ -XXX,XX +XXX,XX @@ static void gem_transmit_updatestats(CadenceGEMState *s, const uint8_t *packet,
664
uint64_t octets;
665
666
/* Total octets (bytes) transmitted */
667
- octets = ((uint64_t)(s->regs[GEM_OCTTXLO]) << 32) |
668
- s->regs[GEM_OCTTXHI];
669
+ octets = ((uint64_t)(s->regs[R_OCTTXLO]) << 32) |
670
+ s->regs[R_OCTTXHI];
671
octets += bytes;
672
- s->regs[GEM_OCTTXLO] = octets >> 32;
673
- s->regs[GEM_OCTTXHI] = octets;
674
+ s->regs[R_OCTTXLO] = octets >> 32;
675
+ s->regs[R_OCTTXHI] = octets;
676
677
/* Error-free Frames transmitted */
678
- s->regs[GEM_TXCNT]++;
679
+ s->regs[R_TXCNT]++;
680
681
/* Error-free Broadcast Frames counter */
682
if (!memcmp(packet, broadcast_addr, 6)) {
683
- s->regs[GEM_TXBCNT]++;
684
+ s->regs[R_TXBCNT]++;
685
}
686
687
/* Error-free Multicast Frames counter */
688
if (packet[0] == 0x01) {
689
- s->regs[GEM_TXMCNT]++;
690
+ s->regs[R_TXMCNT]++;
691
}
692
693
if (bytes <= 64) {
694
- s->regs[GEM_TX64CNT]++;
695
+ s->regs[R_TX64CNT]++;
696
} else if (bytes <= 127) {
697
- s->regs[GEM_TX65CNT]++;
698
+ s->regs[R_TX65CNT]++;
699
} else if (bytes <= 255) {
700
- s->regs[GEM_TX128CNT]++;
701
+ s->regs[R_TX128CNT]++;
702
} else if (bytes <= 511) {
703
- s->regs[GEM_TX256CNT]++;
704
+ s->regs[R_TX256CNT]++;
705
} else if (bytes <= 1023) {
706
- s->regs[GEM_TX512CNT]++;
707
+ s->regs[R_TX512CNT]++;
708
} else if (bytes <= 1518) {
709
- s->regs[GEM_TX1024CNT]++;
710
+ s->regs[R_TX1024CNT]++;
711
} else {
712
- s->regs[GEM_TX1519CNT]++;
713
+ s->regs[R_TX1519CNT]++;
714
}
715
}
716
717
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
718
int q = 0;
719
720
/* Do nothing if transmit is not enabled. */
721
- if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_TXENA)) {
722
+ if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_TXENA)) {
723
return;
724
}
725
726
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
727
while (tx_desc_get_used(desc) == 0) {
728
729
/* Do nothing if transmit is not enabled. */
730
- if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_TXENA)) {
731
+ if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_TXENA)) {
732
return;
733
}
734
print_gem_tx_desc(desc, q);
735
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
736
}
737
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
738
739
- s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
740
+ s->regs[R_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
741
gem_set_isr(s, q, GEM_INT_TXCMPL);
742
743
/* Handle interrupt consequences */
744
gem_update_int_status(s);
745
746
/* Is checksum offload enabled? */
747
- if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
748
+ if (s->regs[R_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
749
net_checksum_calculate(s->tx_packet, total_bytes, CSUM_ALL);
750
}
751
752
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
753
gem_transmit_updatestats(s, s->tx_packet, total_bytes);
754
755
/* Send the packet somewhere */
756
- if (s->phy_loop || (s->regs[GEM_NWCTRL] &
757
+ if (s->phy_loop || (s->regs[R_NWCTRL] &
758
GEM_NWCTRL_LOCALLOOP)) {
759
qemu_receive_packet(qemu_get_queue(s->nic), s->tx_packet,
760
total_bytes);
761
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
762
763
/* read next descriptor */
764
if (tx_desc_get_wrap(desc)) {
765
-
766
- if (s->regs[GEM_DMACFG] & GEM_DMACFG_ADDR_64B) {
767
- packet_desc_addr = s->regs[GEM_TBQPH];
768
+ if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
769
+ packet_desc_addr = s->regs[R_TBQPH];
770
packet_desc_addr <<= 32;
771
} else {
772
packet_desc_addr = 0;
773
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
774
}
775
776
if (tx_desc_get_used(desc)) {
777
- s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_USED;
778
+ s->regs[R_TXSTATUS] |= GEM_TXSTATUS_USED;
779
/* IRQ TXUSED is defined only for queue 0 */
780
if (q == 0) {
781
gem_set_isr(s, 0, GEM_INT_TXUSED);
782
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
783
784
/* Set post reset register values */
785
memset(&s->regs[0], 0, sizeof(s->regs));
786
- s->regs[GEM_NWCFG] = 0x00080000;
787
- s->regs[GEM_NWSTATUS] = 0x00000006;
788
- s->regs[GEM_DMACFG] = 0x00020784;
789
- s->regs[GEM_IMR] = 0x07ffffff;
790
- s->regs[GEM_TXPAUSE] = 0x0000ffff;
791
- s->regs[GEM_TXPARTIALSF] = 0x000003ff;
792
- s->regs[GEM_RXPARTIALSF] = 0x000003ff;
793
- s->regs[GEM_MODID] = s->revision;
794
- s->regs[GEM_DESCONF] = 0x02D00111;
795
- s->regs[GEM_DESCONF2] = 0x2ab10000 | s->jumbo_max_len;
796
- s->regs[GEM_DESCONF5] = 0x002f2045;
797
- s->regs[GEM_DESCONF6] = GEM_DESCONF6_64B_MASK;
798
- s->regs[GEM_INT_Q1_MASK] = 0x00000CE6;
799
- s->regs[GEM_JUMBO_MAX_LEN] = s->jumbo_max_len;
800
+ s->regs[R_NWCFG] = 0x00080000;
801
+ s->regs[R_NWSTATUS] = 0x00000006;
802
+ s->regs[R_DMACFG] = 0x00020784;
803
+ s->regs[R_IMR] = 0x07ffffff;
804
+ s->regs[R_TXPAUSE] = 0x0000ffff;
805
+ s->regs[R_TXPARTIALSF] = 0x000003ff;
806
+ s->regs[R_RXPARTIALSF] = 0x000003ff;
807
+ s->regs[R_MODID] = s->revision;
808
+ s->regs[R_DESCONF] = 0x02D00111;
809
+ s->regs[R_DESCONF2] = 0x2ab10000 | s->jumbo_max_len;
810
+ s->regs[R_DESCONF5] = 0x002f2045;
811
+ s->regs[R_DESCONF6] = GEM_DESCONF6_64B_MASK;
812
+ s->regs[R_INT_Q1_MASK] = 0x00000CE6;
813
+ s->regs[R_JUMBO_MAX_LEN] = s->jumbo_max_len;
814
815
if (s->num_priority_queues > 1) {
816
queues_mask = MAKE_64BIT_MASK(1, s->num_priority_queues - 1);
817
- s->regs[GEM_DESCONF6] |= queues_mask;
818
+ s->regs[R_DESCONF6] |= queues_mask;
819
}
820
821
/* Set MAC address */
822
a = &s->conf.macaddr.a[0];
823
- s->regs[GEM_SPADDR1LO] = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24);
824
- s->regs[GEM_SPADDR1HI] = a[4] | (a[5] << 8);
825
+ s->regs[R_SPADDR1LO] = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24);
826
+ s->regs[R_SPADDR1HI] = a[4] | (a[5] << 8);
827
828
for (i = 0; i < 4; i++) {
829
s->sar_active[i] = false;
830
@@ -XXX,XX +XXX,XX @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
831
DB_PRINT("offset: 0x%04x read: 0x%08x\n", (unsigned)offset*4, retval);
832
833
switch (offset) {
834
- case GEM_ISR:
835
+ case R_ISR:
836
DB_PRINT("lowering irqs on ISR read\n");
837
/* The interrupts get updated at the end of the function. */
838
break;
839
- case GEM_PHYMNTNC:
840
+ case R_PHYMNTNC:
841
if (retval & GEM_PHYMNTNC_OP_R) {
842
uint32_t phy_addr, reg_num;
843
844
@@ -XXX,XX +XXX,XX @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
845
846
/* Handle register write side effects */
847
switch (offset) {
848
- case GEM_NWCTRL:
849
+ case R_NWCTRL:
850
if (val & GEM_NWCTRL_RXENA) {
851
for (i = 0; i < s->num_priority_queues; ++i) {
852
gem_get_rx_desc(s, i);
853
@@ -XXX,XX +XXX,XX @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
854
}
855
break;
856
857
- case GEM_TXSTATUS:
858
+ case R_TXSTATUS:
859
gem_update_int_status(s);
860
break;
861
- case GEM_RXQBASE:
862
+ case R_RXQBASE:
863
s->rx_desc_addr[0] = val;
864
break;
865
- case GEM_RECEIVE_Q1_PTR ... GEM_RECEIVE_Q7_PTR:
866
- s->rx_desc_addr[offset - GEM_RECEIVE_Q1_PTR + 1] = val;
867
+ case R_RECEIVE_Q1_PTR ... R_RECEIVE_Q7_PTR:
868
+ s->rx_desc_addr[offset - R_RECEIVE_Q1_PTR + 1] = val;
869
break;
870
- case GEM_TXQBASE:
871
+ case R_TXQBASE:
872
s->tx_desc_addr[0] = val;
873
break;
874
- case GEM_TRANSMIT_Q1_PTR ... GEM_TRANSMIT_Q7_PTR:
875
- s->tx_desc_addr[offset - GEM_TRANSMIT_Q1_PTR + 1] = val;
876
+ case R_TRANSMIT_Q1_PTR ... R_TRANSMIT_Q7_PTR:
877
+ s->tx_desc_addr[offset - R_TRANSMIT_Q1_PTR + 1] = val;
878
break;
879
- case GEM_RXSTATUS:
880
+ case R_RXSTATUS:
881
gem_update_int_status(s);
882
break;
883
- case GEM_IER:
884
- s->regs[GEM_IMR] &= ~val;
885
+ case R_IER:
886
+ s->regs[R_IMR] &= ~val;
887
gem_update_int_status(s);
888
break;
889
- case GEM_JUMBO_MAX_LEN:
890
- s->regs[GEM_JUMBO_MAX_LEN] = val & MAX_JUMBO_FRAME_SIZE_MASK;
891
+ case R_JUMBO_MAX_LEN:
892
+ s->regs[R_JUMBO_MAX_LEN] = val & MAX_JUMBO_FRAME_SIZE_MASK;
893
break;
894
- case GEM_INT_Q1_ENABLE ... GEM_INT_Q7_ENABLE:
895
- s->regs[GEM_INT_Q1_MASK + offset - GEM_INT_Q1_ENABLE] &= ~val;
896
+ case R_INT_Q1_ENABLE ... R_INT_Q7_ENABLE:
897
+ s->regs[R_INT_Q1_MASK + offset - R_INT_Q1_ENABLE] &= ~val;
898
gem_update_int_status(s);
899
break;
900
- case GEM_IDR:
901
- s->regs[GEM_IMR] |= val;
902
+ case R_IDR:
903
+ s->regs[R_IMR] |= val;
904
gem_update_int_status(s);
905
break;
906
- case GEM_INT_Q1_DISABLE ... GEM_INT_Q7_DISABLE:
907
- s->regs[GEM_INT_Q1_MASK + offset - GEM_INT_Q1_DISABLE] |= val;
908
+ case R_INT_Q1_DISABLE ... R_INT_Q7_DISABLE:
909
+ s->regs[R_INT_Q1_MASK + offset - R_INT_Q1_DISABLE] |= val;
910
gem_update_int_status(s);
911
break;
912
- case GEM_SPADDR1LO:
913
- case GEM_SPADDR2LO:
914
- case GEM_SPADDR3LO:
915
- case GEM_SPADDR4LO:
916
- s->sar_active[(offset - GEM_SPADDR1LO) / 2] = false;
917
+ case R_SPADDR1LO:
918
+ case R_SPADDR2LO:
919
+ case R_SPADDR3LO:
920
+ case R_SPADDR4LO:
921
+ s->sar_active[(offset - R_SPADDR1LO) / 2] = false;
922
break;
923
- case GEM_SPADDR1HI:
924
- case GEM_SPADDR2HI:
925
- case GEM_SPADDR3HI:
926
- case GEM_SPADDR4HI:
927
- s->sar_active[(offset - GEM_SPADDR1HI) / 2] = true;
928
+ case R_SPADDR1HI:
929
+ case R_SPADDR2HI:
930
+ case R_SPADDR3HI:
931
+ case R_SPADDR4HI:
932
+ s->sar_active[(offset - R_SPADDR1HI) / 2] = true;
933
break;
934
- case GEM_PHYMNTNC:
935
+ case R_PHYMNTNC:
936
if (val & GEM_PHYMNTNC_OP_W) {
937
uint32_t phy_addr, reg_num;
938
939
--
940
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Describe screening registers fields using the FIELD macros.
4
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
6
Reviewed-by: sai.pavan.boddu@amd.com
7
Message-id: 20231017194422.4124691-3-luc.michel@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/net/cadence_gem.c | 94 ++++++++++++++++++++++----------------------
11
1 file changed, 48 insertions(+), 46 deletions(-)
12
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/cadence_gem.c
16
+++ b/hw/net/cadence_gem.c
17
@@ -XXX,XX +XXX,XX @@ REG32(INT_Q1_DISABLE, 0x620)
18
REG32(INT_Q7_DISABLE, 0x638)
19
20
REG32(SCREENING_TYPE1_REG0, 0x500)
21
-
22
-#define GEM_ST1R_UDP_PORT_MATCH_ENABLE (1 << 29)
23
-#define GEM_ST1R_DSTC_ENABLE (1 << 28)
24
-#define GEM_ST1R_UDP_PORT_MATCH_SHIFT (12)
25
-#define GEM_ST1R_UDP_PORT_MATCH_WIDTH (27 - GEM_ST1R_UDP_PORT_MATCH_SHIFT + 1)
26
-#define GEM_ST1R_DSTC_MATCH_SHIFT (4)
27
-#define GEM_ST1R_DSTC_MATCH_WIDTH (11 - GEM_ST1R_DSTC_MATCH_SHIFT + 1)
28
-#define GEM_ST1R_QUEUE_SHIFT (0)
29
-#define GEM_ST1R_QUEUE_WIDTH (3 - GEM_ST1R_QUEUE_SHIFT + 1)
30
+ FIELD(SCREENING_TYPE1_REG0, QUEUE_NUM, 0, 4)
31
+ FIELD(SCREENING_TYPE1_REG0, DSTC_MATCH, 4, 8)
32
+ FIELD(SCREENING_TYPE1_REG0, UDP_PORT_MATCH, 12, 16)
33
+ FIELD(SCREENING_TYPE1_REG0, DSTC_ENABLE, 28, 1)
34
+ FIELD(SCREENING_TYPE1_REG0, UDP_PORT_MATCH_EN, 29, 1)
35
+ FIELD(SCREENING_TYPE1_REG0, DROP_ON_MATCH, 30, 1)
36
37
REG32(SCREENING_TYPE2_REG0, 0x540)
38
-
39
-#define GEM_ST2R_COMPARE_A_ENABLE (1 << 18)
40
-#define GEM_ST2R_COMPARE_A_SHIFT (13)
41
-#define GEM_ST2R_COMPARE_WIDTH (17 - GEM_ST2R_COMPARE_A_SHIFT + 1)
42
-#define GEM_ST2R_ETHERTYPE_ENABLE (1 << 12)
43
-#define GEM_ST2R_ETHERTYPE_INDEX_SHIFT (9)
44
-#define GEM_ST2R_ETHERTYPE_INDEX_WIDTH (11 - GEM_ST2R_ETHERTYPE_INDEX_SHIFT \
45
- + 1)
46
-#define GEM_ST2R_QUEUE_SHIFT (0)
47
-#define GEM_ST2R_QUEUE_WIDTH (3 - GEM_ST2R_QUEUE_SHIFT + 1)
48
+ FIELD(SCREENING_TYPE2_REG0, QUEUE_NUM, 0, 4)
49
+ FIELD(SCREENING_TYPE2_REG0, VLAN_PRIORITY, 4, 3)
50
+ FIELD(SCREENING_TYPE2_REG0, VLAN_ENABLE, 8, 1)
51
+ FIELD(SCREENING_TYPE2_REG0, ETHERTYPE_REG_INDEX, 9, 3)
52
+ FIELD(SCREENING_TYPE2_REG0, ETHERTYPE_ENABLE, 12, 1)
53
+ FIELD(SCREENING_TYPE2_REG0, COMPARE_A, 13, 5)
54
+ FIELD(SCREENING_TYPE2_REG0, COMPARE_A_ENABLE, 18, 1)
55
+ FIELD(SCREENING_TYPE2_REG0, COMPARE_B, 19, 5)
56
+ FIELD(SCREENING_TYPE2_REG0, COMPARE_B_ENABLE, 24, 1)
57
+ FIELD(SCREENING_TYPE2_REG0, COMPARE_C, 25, 5)
58
+ FIELD(SCREENING_TYPE2_REG0, COMPARE_C_ENABLE, 30, 1)
59
+ FIELD(SCREENING_TYPE2_REG0, DROP_ON_MATCH, 31, 1)
60
61
REG32(SCREENING_TYPE2_ETHERTYPE_REG0, 0x6e0)
62
-REG32(TYPE2_COMPARE_0_WORD_0, 0x700)
63
64
-#define GEM_T2CW1_COMPARE_OFFSET_SHIFT (7)
65
-#define GEM_T2CW1_COMPARE_OFFSET_WIDTH (8 - GEM_T2CW1_COMPARE_OFFSET_SHIFT + 1)
66
-#define GEM_T2CW1_OFFSET_VALUE_SHIFT (0)
67
-#define GEM_T2CW1_OFFSET_VALUE_WIDTH (6 - GEM_T2CW1_OFFSET_VALUE_SHIFT + 1)
68
+REG32(TYPE2_COMPARE_0_WORD_0, 0x700)
69
+ FIELD(TYPE2_COMPARE_0_WORD_0, MASK_VALUE, 0, 16)
70
+ FIELD(TYPE2_COMPARE_0_WORD_0, COMPARE_VALUE, 16, 16)
71
+
72
+REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
73
+ FIELD(TYPE2_COMPARE_0_WORD_1, OFFSET_VALUE, 0, 7)
74
+ FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET, 7, 2)
75
+ FIELD(TYPE2_COMPARE_0_WORD_1, DISABLE_MASK, 9, 1)
76
+ FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
77
78
/*****************************************/
79
#define GEM_NWCTRL_TXSTART 0x00000200 /* Transmit Enable */
80
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
81
mismatched = false;
82
83
/* Screening is based on UDP Port */
84
- if (reg & GEM_ST1R_UDP_PORT_MATCH_ENABLE) {
85
+ if (FIELD_EX32(reg, SCREENING_TYPE1_REG0, UDP_PORT_MATCH_EN)) {
86
uint16_t udp_port = rxbuf_ptr[14 + 22] << 8 | rxbuf_ptr[14 + 23];
87
- if (udp_port == extract32(reg, GEM_ST1R_UDP_PORT_MATCH_SHIFT,
88
- GEM_ST1R_UDP_PORT_MATCH_WIDTH)) {
89
+ if (udp_port == FIELD_EX32(reg, SCREENING_TYPE1_REG0, UDP_PORT_MATCH)) {
90
matched = true;
91
} else {
92
mismatched = true;
93
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
94
}
95
96
/* Screening is based on DS/TC */
97
- if (reg & GEM_ST1R_DSTC_ENABLE) {
98
+ if (FIELD_EX32(reg, SCREENING_TYPE1_REG0, DSTC_ENABLE)) {
99
uint8_t dscp = rxbuf_ptr[14 + 1];
100
- if (dscp == extract32(reg, GEM_ST1R_DSTC_MATCH_SHIFT,
101
- GEM_ST1R_DSTC_MATCH_WIDTH)) {
102
+ if (dscp == FIELD_EX32(reg, SCREENING_TYPE1_REG0, DSTC_MATCH)) {
103
matched = true;
104
} else {
105
mismatched = true;
106
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
107
}
108
109
if (matched && !mismatched) {
110
- return extract32(reg, GEM_ST1R_QUEUE_SHIFT, GEM_ST1R_QUEUE_WIDTH);
111
+ return FIELD_EX32(reg, SCREENING_TYPE1_REG0, QUEUE_NUM);
112
}
113
}
114
115
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
116
matched = false;
117
mismatched = false;
118
119
- if (reg & GEM_ST2R_ETHERTYPE_ENABLE) {
120
+ if (FIELD_EX32(reg, SCREENING_TYPE2_REG0, ETHERTYPE_ENABLE)) {
121
uint16_t type = rxbuf_ptr[12] << 8 | rxbuf_ptr[13];
122
- int et_idx = extract32(reg, GEM_ST2R_ETHERTYPE_INDEX_SHIFT,
123
- GEM_ST2R_ETHERTYPE_INDEX_WIDTH);
124
+ int et_idx = FIELD_EX32(reg, SCREENING_TYPE2_REG0,
125
+ ETHERTYPE_REG_INDEX);
126
127
if (et_idx > s->num_type2_screeners) {
128
qemu_log_mask(LOG_GUEST_ERROR, "Out of range ethertype "
129
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
130
131
/* Compare A, B, C */
132
for (j = 0; j < 3; j++) {
133
- uint32_t cr0, cr1, mask;
134
+ uint32_t cr0, cr1, mask, compare;
135
uint16_t rx_cmp;
136
int offset;
137
- int cr_idx = extract32(reg, GEM_ST2R_COMPARE_A_SHIFT + j * 6,
138
- GEM_ST2R_COMPARE_WIDTH);
139
+ int cr_idx = extract32(reg, R_SCREENING_TYPE2_REG0_COMPARE_A_SHIFT + j * 6,
140
+ R_SCREENING_TYPE2_REG0_COMPARE_A_LENGTH);
141
142
- if (!(reg & (GEM_ST2R_COMPARE_A_ENABLE << (j * 6)))) {
143
+ if (!extract32(reg, R_SCREENING_TYPE2_REG0_COMPARE_A_ENABLE_SHIFT + j * 6,
144
+ R_SCREENING_TYPE2_REG0_COMPARE_A_ENABLE_LENGTH)) {
145
continue;
146
}
147
+
148
if (cr_idx > s->num_type2_screeners) {
149
qemu_log_mask(LOG_GUEST_ERROR, "Out of range compare "
150
"register index: %d\n", cr_idx);
151
}
152
153
cr0 = s->regs[R_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2];
154
- cr1 = s->regs[R_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2 + 1];
155
- offset = extract32(cr1, GEM_T2CW1_OFFSET_VALUE_SHIFT,
156
- GEM_T2CW1_OFFSET_VALUE_WIDTH);
157
+ cr1 = s->regs[R_TYPE2_COMPARE_0_WORD_1 + cr_idx * 2];
158
+ offset = FIELD_EX32(cr1, TYPE2_COMPARE_0_WORD_1, OFFSET_VALUE);
159
160
- switch (extract32(cr1, GEM_T2CW1_COMPARE_OFFSET_SHIFT,
161
- GEM_T2CW1_COMPARE_OFFSET_WIDTH)) {
162
+ switch (FIELD_EX32(cr1, TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET)) {
163
case 3: /* Skip UDP header */
164
qemu_log_mask(LOG_UNIMP, "TCP compare offsets"
165
"unimplemented - assuming UDP\n");
166
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
167
}
168
169
rx_cmp = rxbuf_ptr[offset] << 8 | rxbuf_ptr[offset];
170
- mask = extract32(cr0, 0, 16);
171
+ mask = FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, MASK_VALUE);
172
+ compare = FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, COMPARE_VALUE);
173
174
- if ((rx_cmp & mask) == (extract32(cr0, 16, 16) & mask)) {
175
+ if ((rx_cmp & mask) == (compare & mask)) {
176
matched = true;
177
} else {
178
mismatched = true;
179
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
180
}
181
182
if (matched && !mismatched) {
183
- return extract32(reg, GEM_ST2R_QUEUE_SHIFT, GEM_ST2R_QUEUE_WIDTH);
184
+ return FIELD_EX32(reg, SCREENING_TYPE2_REG0, QUEUE_NUM);
185
}
186
}
187
188
--
189
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Use the FIELD macro to describe the NWCTRL register fields.
4
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
6
Reviewed-by: sai.pavan.boddu@amd.com
7
Message-id: 20231017194422.4124691-4-luc.michel@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/net/cadence_gem.c | 53 +++++++++++++++++++++++++++++++++-----------
11
1 file changed, 40 insertions(+), 13 deletions(-)
12
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/cadence_gem.c
16
+++ b/hw/net/cadence_gem.c
17
@@ -XXX,XX +XXX,XX @@
18
} while (0)
19
20
REG32(NWCTRL, 0x0) /* Network Control reg */
21
+ FIELD(NWCTRL, LOOPBACK , 0, 1)
22
+ FIELD(NWCTRL, LOOPBACK_LOCAL , 1, 1)
23
+ FIELD(NWCTRL, ENABLE_RECEIVE, 2, 1)
24
+ FIELD(NWCTRL, ENABLE_TRANSMIT, 3, 1)
25
+ FIELD(NWCTRL, MAN_PORT_EN , 4, 1)
26
+ FIELD(NWCTRL, CLEAR_ALL_STATS_REGS , 5, 1)
27
+ FIELD(NWCTRL, INC_ALL_STATS_REGS, 6, 1)
28
+ FIELD(NWCTRL, STATS_WRITE_EN, 7, 1)
29
+ FIELD(NWCTRL, BACK_PRESSURE, 8, 1)
30
+ FIELD(NWCTRL, TRANSMIT_START , 9, 1)
31
+ FIELD(NWCTRL, TRANSMIT_HALT, 10, 1)
32
+ FIELD(NWCTRL, TX_PAUSE_FRAME_RE, 11, 1)
33
+ FIELD(NWCTRL, TX_PAUSE_FRAME_ZE, 12, 1)
34
+ FIELD(NWCTRL, STATS_TAKE_SNAP, 13, 1)
35
+ FIELD(NWCTRL, STATS_READ_SNAP, 14, 1)
36
+ FIELD(NWCTRL, STORE_RX_TS, 15, 1)
37
+ FIELD(NWCTRL, PFC_ENABLE, 16, 1)
38
+ FIELD(NWCTRL, PFC_PRIO_BASED, 17, 1)
39
+ FIELD(NWCTRL, FLUSH_RX_PKT_PCLK , 18, 1)
40
+ FIELD(NWCTRL, TX_LPI_EN, 19, 1)
41
+ FIELD(NWCTRL, PTP_UNICAST_ENA, 20, 1)
42
+ FIELD(NWCTRL, ALT_SGMII_MODE, 21, 1)
43
+ FIELD(NWCTRL, STORE_UDP_OFFSET, 22, 1)
44
+ FIELD(NWCTRL, EXT_TSU_PORT_EN, 23, 1)
45
+ FIELD(NWCTRL, ONE_STEP_SYNC_MO, 24, 1)
46
+ FIELD(NWCTRL, PFC_CTRL , 25, 1)
47
+ FIELD(NWCTRL, EXT_RXQ_SEL_EN , 26, 1)
48
+ FIELD(NWCTRL, OSS_CORRECTION_FIELD, 27, 1)
49
+ FIELD(NWCTRL, SEL_MII_ON_RGMII, 28, 1)
50
+ FIELD(NWCTRL, TWO_PT_FIVE_GIG, 29, 1)
51
+ FIELD(NWCTRL, IFG_EATS_QAV_CREDIT, 30, 1)
52
+
53
REG32(NWCFG, 0x4) /* Network Config reg */
54
REG32(NWSTATUS, 0x8) /* Network Status reg */
55
REG32(USERIO, 0xc) /* User IO reg */
56
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
57
FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
58
59
/*****************************************/
60
-#define GEM_NWCTRL_TXSTART 0x00000200 /* Transmit Enable */
61
-#define GEM_NWCTRL_TXENA 0x00000008 /* Transmit Enable */
62
-#define GEM_NWCTRL_RXENA 0x00000004 /* Receive Enable */
63
-#define GEM_NWCTRL_LOCALLOOP 0x00000002 /* Local Loopback */
64
-
65
#define GEM_NWCFG_STRIP_FCS 0x00020000 /* Strip FCS field */
66
#define GEM_NWCFG_LERR_DISC 0x00010000 /* Discard RX frames with len err */
67
#define GEM_NWCFG_BUFF_OFST_M 0x0000C000 /* Receive buffer offset mask */
68
@@ -XXX,XX +XXX,XX @@ static bool gem_can_receive(NetClientState *nc)
69
s = qemu_get_nic_opaque(nc);
70
71
/* Do nothing if receive is not enabled. */
72
- if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_RXENA)) {
73
+ if (!FIELD_EX32(s->regs[R_NWCTRL], NWCTRL, ENABLE_RECEIVE)) {
74
if (s->can_rx_state != 1) {
75
s->can_rx_state = 1;
76
DB_PRINT("can't receive - no enable\n");
77
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
78
int q = 0;
79
80
/* Do nothing if transmit is not enabled. */
81
- if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_TXENA)) {
82
+ if (!FIELD_EX32(s->regs[R_NWCTRL], NWCTRL, ENABLE_TRANSMIT)) {
83
return;
84
}
85
86
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
87
while (tx_desc_get_used(desc) == 0) {
88
89
/* Do nothing if transmit is not enabled. */
90
- if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_TXENA)) {
91
+ if (!FIELD_EX32(s->regs[R_NWCTRL], NWCTRL, ENABLE_TRANSMIT)) {
92
return;
93
}
94
print_gem_tx_desc(desc, q);
95
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
96
gem_transmit_updatestats(s, s->tx_packet, total_bytes);
97
98
/* Send the packet somewhere */
99
- if (s->phy_loop || (s->regs[R_NWCTRL] &
100
- GEM_NWCTRL_LOCALLOOP)) {
101
+ if (s->phy_loop || FIELD_EX32(s->regs[R_NWCTRL], NWCTRL,
102
+ LOOPBACK_LOCAL)) {
103
qemu_receive_packet(qemu_get_queue(s->nic), s->tx_packet,
104
total_bytes);
105
} else {
106
@@ -XXX,XX +XXX,XX @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
107
/* Handle register write side effects */
108
switch (offset) {
109
case R_NWCTRL:
110
- if (val & GEM_NWCTRL_RXENA) {
111
+ if (FIELD_EX32(val, NWCTRL, ENABLE_RECEIVE)) {
112
for (i = 0; i < s->num_priority_queues; ++i) {
113
gem_get_rx_desc(s, i);
114
}
115
}
116
- if (val & GEM_NWCTRL_TXSTART) {
117
+ if (FIELD_EX32(val, NWCTRL, TRANSMIT_START)) {
118
gem_transmit(s);
119
}
120
- if (!(val & GEM_NWCTRL_TXENA)) {
121
+ if (!(FIELD_EX32(val, NWCTRL, ENABLE_TRANSMIT))) {
122
/* Reset to start of Q when transmit disabled. */
123
for (i = 0; i < s->num_priority_queues; i++) {
124
s->tx_desc_addr[i] = gem_get_tx_queue_base_addr(s, i);
125
--
126
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Use de FIELD macro to describe the NWCFG register fields.
4
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
6
Reviewed-by: sai.pavan.boddu@amd.com
7
Message-id: 20231017194422.4124691-5-luc.michel@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/net/cadence_gem.c | 60 ++++++++++++++++++++++++++++----------------
11
1 file changed, 39 insertions(+), 21 deletions(-)
12
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/cadence_gem.c
16
+++ b/hw/net/cadence_gem.c
17
@@ -XXX,XX +XXX,XX @@ REG32(NWCTRL, 0x0) /* Network Control reg */
18
FIELD(NWCTRL, IFG_EATS_QAV_CREDIT, 30, 1)
19
20
REG32(NWCFG, 0x4) /* Network Config reg */
21
+ FIELD(NWCFG, SPEED, 0, 1)
22
+ FIELD(NWCFG, FULL_DUPLEX, 1, 1)
23
+ FIELD(NWCFG, DISCARD_NON_VLAN_FRAMES, 2, 1)
24
+ FIELD(NWCFG, JUMBO_FRAMES, 3, 1)
25
+ FIELD(NWCFG, PROMISC, 4, 1)
26
+ FIELD(NWCFG, NO_BROADCAST, 5, 1)
27
+ FIELD(NWCFG, MULTICAST_HASH_EN, 6, 1)
28
+ FIELD(NWCFG, UNICAST_HASH_EN, 7, 1)
29
+ FIELD(NWCFG, RECV_1536_BYTE_FRAMES, 8, 1)
30
+ FIELD(NWCFG, EXTERNAL_ADDR_MATCH_EN, 9, 1)
31
+ FIELD(NWCFG, GIGABIT_MODE_ENABLE, 10, 1)
32
+ FIELD(NWCFG, PCS_SELECT, 11, 1)
33
+ FIELD(NWCFG, RETRY_TEST, 12, 1)
34
+ FIELD(NWCFG, PAUSE_ENABLE, 13, 1)
35
+ FIELD(NWCFG, RECV_BUF_OFFSET, 14, 2)
36
+ FIELD(NWCFG, LEN_ERR_DISCARD, 16, 1)
37
+ FIELD(NWCFG, FCS_REMOVE, 17, 1)
38
+ FIELD(NWCFG, MDC_CLOCK_DIV, 18, 3)
39
+ FIELD(NWCFG, DATA_BUS_WIDTH, 21, 2)
40
+ FIELD(NWCFG, DISABLE_COPY_PAUSE_FRAMES, 23, 1)
41
+ FIELD(NWCFG, RECV_CSUM_OFFLOAD_EN, 24, 1)
42
+ FIELD(NWCFG, EN_HALF_DUPLEX_RX, 25, 1)
43
+ FIELD(NWCFG, IGNORE_RX_FCS, 26, 1)
44
+ FIELD(NWCFG, SGMII_MODE_ENABLE, 27, 1)
45
+ FIELD(NWCFG, IPG_STRETCH_ENABLE, 28, 1)
46
+ FIELD(NWCFG, NSP_ACCEPT, 29, 1)
47
+ FIELD(NWCFG, IGNORE_IPG_RX_ER, 30, 1)
48
+ FIELD(NWCFG, UNI_DIRECTION_ENABLE, 31, 1)
49
+
50
REG32(NWSTATUS, 0x8) /* Network Status reg */
51
REG32(USERIO, 0xc) /* User IO reg */
52
REG32(DMACFG, 0x10) /* DMA Control reg */
53
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
54
FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
55
56
/*****************************************/
57
-#define GEM_NWCFG_STRIP_FCS 0x00020000 /* Strip FCS field */
58
-#define GEM_NWCFG_LERR_DISC 0x00010000 /* Discard RX frames with len err */
59
-#define GEM_NWCFG_BUFF_OFST_M 0x0000C000 /* Receive buffer offset mask */
60
-#define GEM_NWCFG_BUFF_OFST_S 14 /* Receive buffer offset shift */
61
-#define GEM_NWCFG_RCV_1538 0x00000100 /* Receive 1538 bytes frame */
62
-#define GEM_NWCFG_UCAST_HASH 0x00000080 /* accept unicast if hash match */
63
-#define GEM_NWCFG_MCAST_HASH 0x00000040 /* accept multicast if hash match */
64
-#define GEM_NWCFG_BCAST_REJ 0x00000020 /* Reject broadcast packets */
65
-#define GEM_NWCFG_PROMISC 0x00000010 /* Accept all packets */
66
-#define GEM_NWCFG_JUMBO_FRAME 0x00000008 /* Jumbo Frames enable */
67
-
68
#define GEM_DMACFG_ADDR_64B (1U << 30)
69
#define GEM_DMACFG_TX_BD_EXT (1U << 29)
70
#define GEM_DMACFG_RX_BD_EXT (1U << 28)
71
@@ -XXX,XX +XXX,XX @@ static const uint8_t broadcast_addr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
72
static uint32_t gem_get_max_buf_len(CadenceGEMState *s, bool tx)
73
{
74
uint32_t size;
75
- if (s->regs[R_NWCFG] & GEM_NWCFG_JUMBO_FRAME) {
76
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, JUMBO_FRAMES)) {
77
size = s->regs[R_JUMBO_MAX_LEN];
78
if (size > s->jumbo_max_len) {
79
size = s->jumbo_max_len;
80
@@ -XXX,XX +XXX,XX @@ static uint32_t gem_get_max_buf_len(CadenceGEMState *s, bool tx)
81
} else if (tx) {
82
size = 1518;
83
} else {
84
- size = s->regs[R_NWCFG] & GEM_NWCFG_RCV_1538 ? 1538 : 1518;
85
+ size = FIELD_EX32(s->regs[R_NWCFG],
86
+ NWCFG, RECV_1536_BYTE_FRAMES) ? 1538 : 1518;
87
}
88
return size;
89
}
90
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
91
int i, is_mc;
92
93
/* Promiscuous mode? */
94
- if (s->regs[R_NWCFG] & GEM_NWCFG_PROMISC) {
95
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, PROMISC)) {
96
return GEM_RX_PROMISCUOUS_ACCEPT;
97
}
98
99
if (!memcmp(packet, broadcast_addr, 6)) {
100
/* Reject broadcast packets? */
101
- if (s->regs[R_NWCFG] & GEM_NWCFG_BCAST_REJ) {
102
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, NO_BROADCAST)) {
103
return GEM_RX_REJECT;
104
}
105
return GEM_RX_BROADCAST_ACCEPT;
106
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
107
108
/* Accept packets -w- hash match? */
109
is_mc = is_multicast_ether_addr(packet);
110
- if ((is_mc && (s->regs[R_NWCFG] & GEM_NWCFG_MCAST_HASH)) ||
111
- (!is_mc && (s->regs[R_NWCFG] & GEM_NWCFG_UCAST_HASH))) {
112
+ if ((is_mc && (FIELD_EX32(s->regs[R_NWCFG], NWCFG, MULTICAST_HASH_EN))) ||
113
+ (!is_mc && FIELD_EX32(s->regs[R_NWCFG], NWCFG, UNICAST_HASH_EN))) {
114
uint64_t buckets;
115
unsigned hash_index;
116
117
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
118
}
119
120
/* Discard packets with receive length error enabled ? */
121
- if (s->regs[R_NWCFG] & GEM_NWCFG_LERR_DISC) {
122
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, LEN_ERR_DISCARD)) {
123
unsigned type_len;
124
125
/* Fish the ethertype / length field out of the RX packet */
126
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
127
/*
128
* Determine configured receive buffer offset (probably 0)
129
*/
130
- rxbuf_offset = (s->regs[R_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>
131
- GEM_NWCFG_BUFF_OFST_S;
132
+ rxbuf_offset = FIELD_EX32(s->regs[R_NWCFG], NWCFG, RECV_BUF_OFFSET);
133
134
/* The configure size of each receive buffer. Determines how many
135
* buffers needed to hold this packet.
136
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
137
}
138
139
/* Strip of FCS field ? (usually yes) */
140
- if (s->regs[R_NWCFG] & GEM_NWCFG_STRIP_FCS) {
141
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, FCS_REMOVE)) {
142
rxbuf_ptr = (void *)buf;
143
} else {
144
unsigned crc_val;
145
--
146
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Use de FIELD macro to describe the DMACFG register fields.
4
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
6
Reviewed-by: sai.pavan.boddu@amd.com
7
Message-id: 20231017194422.4124691-6-luc.michel@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/net/cadence_gem.c | 48 ++++++++++++++++++++++++++++----------------
11
1 file changed, 31 insertions(+), 17 deletions(-)
12
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/cadence_gem.c
16
+++ b/hw/net/cadence_gem.c
17
@@ -XXX,XX +XXX,XX @@ REG32(NWCFG, 0x4) /* Network Config reg */
18
19
REG32(NWSTATUS, 0x8) /* Network Status reg */
20
REG32(USERIO, 0xc) /* User IO reg */
21
+
22
REG32(DMACFG, 0x10) /* DMA Control reg */
23
+ FIELD(DMACFG, SEND_BCAST_TO_ALL_QS, 31, 1)
24
+ FIELD(DMACFG, DMA_ADDR_BUS_WIDTH, 30, 1)
25
+ FIELD(DMACFG, TX_BD_EXT_MODE_EN , 29, 1)
26
+ FIELD(DMACFG, RX_BD_EXT_MODE_EN , 28, 1)
27
+ FIELD(DMACFG, FORCE_MAX_AMBA_BURST_TX, 26, 1)
28
+ FIELD(DMACFG, FORCE_MAX_AMBA_BURST_RX, 25, 1)
29
+ FIELD(DMACFG, FORCE_DISCARD_ON_ERR, 24, 1)
30
+ FIELD(DMACFG, RX_BUF_SIZE, 16, 8)
31
+ FIELD(DMACFG, CRC_ERROR_REPORT, 13, 1)
32
+ FIELD(DMACFG, INF_LAST_DBUF_SIZE_EN, 12, 1)
33
+ FIELD(DMACFG, TX_PBUF_CSUM_OFFLOAD, 11, 1)
34
+ FIELD(DMACFG, TX_PBUF_SIZE, 10, 1)
35
+ FIELD(DMACFG, RX_PBUF_SIZE, 8, 2)
36
+ FIELD(DMACFG, ENDIAN_SWAP_PACKET, 7, 1)
37
+ FIELD(DMACFG, ENDIAN_SWAP_MGNT, 6, 1)
38
+ FIELD(DMACFG, HDR_DATA_SPLIT_EN, 5, 1)
39
+ FIELD(DMACFG, AMBA_BURST_LEN , 0, 5)
40
+#define GEM_DMACFG_RBUFSZ_MUL 64 /* DMA RX Buffer Size multiplier */
41
+
42
REG32(TXSTATUS, 0x14) /* TX Status reg */
43
REG32(RXQBASE, 0x18) /* RX Q Base address reg */
44
REG32(TXQBASE, 0x1c) /* TX Q Base address reg */
45
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
46
FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
47
48
/*****************************************/
49
-#define GEM_DMACFG_ADDR_64B (1U << 30)
50
-#define GEM_DMACFG_TX_BD_EXT (1U << 29)
51
-#define GEM_DMACFG_RX_BD_EXT (1U << 28)
52
-#define GEM_DMACFG_RBUFSZ_M 0x00FF0000 /* DMA RX Buffer Size mask */
53
-#define GEM_DMACFG_RBUFSZ_S 16 /* DMA RX Buffer Size shift */
54
-#define GEM_DMACFG_RBUFSZ_MUL 64 /* DMA RX Buffer Size multiplier */
55
-#define GEM_DMACFG_TXCSUM_OFFL 0x00000800 /* Transmit checksum offload */
56
57
#define GEM_TXSTATUS_TXCMPL 0x00000020 /* Transmit Complete */
58
#define GEM_TXSTATUS_USED 0x00000001 /* sw owned descriptor encountered */
59
@@ -XXX,XX +XXX,XX @@ static inline uint64_t tx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
60
{
61
uint64_t ret = desc[0];
62
63
- if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
64
+ if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
65
ret |= (uint64_t)desc[2] << 32;
66
}
67
return ret;
68
@@ -XXX,XX +XXX,XX @@ static inline uint64_t rx_desc_get_buffer(CadenceGEMState *s, uint32_t *desc)
69
{
70
uint64_t ret = desc[0] & ~0x3UL;
71
72
- if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
73
+ if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
74
ret |= (uint64_t)desc[2] << 32;
75
}
76
return ret;
77
@@ -XXX,XX +XXX,XX @@ static inline int gem_get_desc_len(CadenceGEMState *s, bool rx_n_tx)
78
{
79
int ret = 2;
80
81
- if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
82
+ if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
83
ret += 2;
84
}
85
- if (s->regs[R_DMACFG] & (rx_n_tx ? GEM_DMACFG_RX_BD_EXT
86
- : GEM_DMACFG_TX_BD_EXT)) {
87
+ if (s->regs[R_DMACFG] & (rx_n_tx ? R_DMACFG_RX_BD_EXT_MODE_EN_MASK
88
+ : R_DMACFG_TX_BD_EXT_MODE_EN_MASK)) {
89
ret += 2;
90
}
91
92
@@ -XXX,XX +XXX,XX @@ static hwaddr gem_get_desc_addr(CadenceGEMState *s, bool tx, int q)
93
{
94
hwaddr desc_addr = 0;
95
96
- if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
97
+ if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
98
desc_addr = s->regs[tx ? R_TBQPH : R_RBQPH];
99
}
100
desc_addr <<= 32;
101
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
102
/* The configure size of each receive buffer. Determines how many
103
* buffers needed to hold this packet.
104
*/
105
- rxbufsize = ((s->regs[R_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>
106
- GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
107
+ rxbufsize = FIELD_EX32(s->regs[R_DMACFG], DMACFG, RX_BUF_SIZE);
108
+ rxbufsize *= GEM_DMACFG_RBUFSZ_MUL;
109
+
110
bytes_to_copy = size;
111
112
/* Hardware allows a zero value here but warns against it. To avoid QEMU
113
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
114
gem_update_int_status(s);
115
116
/* Is checksum offload enabled? */
117
- if (s->regs[R_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
118
+ if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, TX_PBUF_CSUM_OFFLOAD)) {
119
net_checksum_calculate(s->tx_packet, total_bytes, CSUM_ALL);
120
}
121
122
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
123
124
/* read next descriptor */
125
if (tx_desc_get_wrap(desc)) {
126
- if (s->regs[R_DMACFG] & GEM_DMACFG_ADDR_64B) {
127
+ if (FIELD_EX32(s->regs[R_DMACFG], DMACFG, DMA_ADDR_BUS_WIDTH)) {
128
packet_desc_addr = s->regs[R_TBQPH];
129
packet_desc_addr <<= 32;
130
} else {
131
--
132
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Use de FIELD macro to describe the TXSTATUS and RXSTATUS register
4
fields.
5
6
Signed-off-by: Luc Michel <luc.michel@amd.com>
7
Reviewed-by: sai.pavan.boddu@amd.com
8
Message-id: 20231017194422.4124691-7-luc.michel@amd.com
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
hw/net/cadence_gem.c | 34 +++++++++++++++++++++++++---------
12
1 file changed, 25 insertions(+), 9 deletions(-)
13
14
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/net/cadence_gem.c
17
+++ b/hw/net/cadence_gem.c
18
@@ -XXX,XX +XXX,XX @@ REG32(DMACFG, 0x10) /* DMA Control reg */
19
#define GEM_DMACFG_RBUFSZ_MUL 64 /* DMA RX Buffer Size multiplier */
20
21
REG32(TXSTATUS, 0x14) /* TX Status reg */
22
+ FIELD(TXSTATUS, TX_USED_BIT_READ_MIDFRAME, 12, 1)
23
+ FIELD(TXSTATUS, TX_FRAME_TOO_LARGE, 11, 1)
24
+ FIELD(TXSTATUS, TX_DMA_LOCKUP, 10, 1)
25
+ FIELD(TXSTATUS, TX_MAC_LOCKUP, 9, 1)
26
+ FIELD(TXSTATUS, RESP_NOT_OK, 8, 1)
27
+ FIELD(TXSTATUS, LATE_COLLISION, 7, 1)
28
+ FIELD(TXSTATUS, TRANSMIT_UNDER_RUN, 6, 1)
29
+ FIELD(TXSTATUS, TRANSMIT_COMPLETE, 5, 1)
30
+ FIELD(TXSTATUS, AMBA_ERROR, 4, 1)
31
+ FIELD(TXSTATUS, TRANSMIT_GO, 3, 1)
32
+ FIELD(TXSTATUS, RETRY_LIMIT, 2, 1)
33
+ FIELD(TXSTATUS, COLLISION, 1, 1)
34
+ FIELD(TXSTATUS, USED_BIT_READ, 0, 1)
35
+
36
REG32(RXQBASE, 0x18) /* RX Q Base address reg */
37
REG32(TXQBASE, 0x1c) /* TX Q Base address reg */
38
REG32(RXSTATUS, 0x20) /* RX Status reg */
39
+ FIELD(RXSTATUS, RX_DMA_LOCKUP, 5, 1)
40
+ FIELD(RXSTATUS, RX_MAC_LOCKUP, 4, 1)
41
+ FIELD(RXSTATUS, RESP_NOT_OK, 3, 1)
42
+ FIELD(RXSTATUS, RECEIVE_OVERRUN, 2, 1)
43
+ FIELD(RXSTATUS, FRAME_RECEIVED, 1, 1)
44
+ FIELD(RXSTATUS, BUF_NOT_AVAILABLE, 0, 1)
45
+
46
REG32(ISR, 0x24) /* Interrupt Status reg */
47
REG32(IER, 0x28) /* Interrupt Enable reg */
48
REG32(IDR, 0x2c) /* Interrupt Disable reg */
49
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
50
51
/*****************************************/
52
53
-#define GEM_TXSTATUS_TXCMPL 0x00000020 /* Transmit Complete */
54
-#define GEM_TXSTATUS_USED 0x00000001 /* sw owned descriptor encountered */
55
-
56
-#define GEM_RXSTATUS_FRMRCVD 0x00000002 /* Frame received */
57
-#define GEM_RXSTATUS_NOBUF 0x00000001 /* Buffer unavailable */
58
59
/* GEM_ISR GEM_IER GEM_IDR GEM_IMR */
60
#define GEM_INT_TXCMPL 0x00000080 /* Transmit Complete */
61
@@ -XXX,XX +XXX,XX @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
62
/* Descriptor owned by software ? */
63
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
64
DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
65
- s->regs[R_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
66
+ s->regs[R_RXSTATUS] |= R_RXSTATUS_BUF_NOT_AVAILABLE_MASK;
67
gem_set_isr(s, q, GEM_INT_RXUSED);
68
/* Handle interrupt consequences */
69
gem_update_int_status(s);
70
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
71
/* Count it */
72
gem_receive_updatestats(s, buf, size);
73
74
- s->regs[R_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;
75
+ s->regs[R_RXSTATUS] |= R_RXSTATUS_FRAME_RECEIVED_MASK;
76
gem_set_isr(s, q, GEM_INT_RXCMPL);
77
78
/* Handle interrupt consequences */
79
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
80
}
81
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
82
83
- s->regs[R_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
84
+ s->regs[R_TXSTATUS] |= R_TXSTATUS_TRANSMIT_COMPLETE_MASK;
85
gem_set_isr(s, q, GEM_INT_TXCMPL);
86
87
/* Handle interrupt consequences */
88
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
89
}
90
91
if (tx_desc_get_used(desc)) {
92
- s->regs[R_TXSTATUS] |= GEM_TXSTATUS_USED;
93
+ s->regs[R_TXSTATUS] |= R_TXSTATUS_USED_BIT_READ_MASK;
94
/* IRQ TXUSED is defined only for queue 0 */
95
if (q == 0) {
96
gem_set_isr(s, 0, GEM_INT_TXUSED);
97
--
98
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Use de FIELD macro to describe the IRQ related register fields.
4
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
6
Reviewed-by: sai.pavan.boddu@amd.com
7
Message-id: 20231017194422.4124691-8-luc.michel@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/net/cadence_gem.c | 51 +++++++++++++++++++++++++++++++++-----------
11
1 file changed, 39 insertions(+), 12 deletions(-)
12
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/cadence_gem.c
16
+++ b/hw/net/cadence_gem.c
17
@@ -XXX,XX +XXX,XX @@ REG32(RXSTATUS, 0x20) /* RX Status reg */
18
FIELD(RXSTATUS, BUF_NOT_AVAILABLE, 0, 1)
19
20
REG32(ISR, 0x24) /* Interrupt Status reg */
21
+ FIELD(ISR, TX_LOCKUP, 31, 1)
22
+ FIELD(ISR, RX_LOCKUP, 30, 1)
23
+ FIELD(ISR, TSU_TIMER, 29, 1)
24
+ FIELD(ISR, WOL, 28, 1)
25
+ FIELD(ISR, RECV_LPI, 27, 1)
26
+ FIELD(ISR, TSU_SEC_INCR, 26, 1)
27
+ FIELD(ISR, PTP_PDELAY_RESP_XMIT, 25, 1)
28
+ FIELD(ISR, PTP_PDELAY_REQ_XMIT, 24, 1)
29
+ FIELD(ISR, PTP_PDELAY_RESP_RECV, 23, 1)
30
+ FIELD(ISR, PTP_PDELAY_REQ_RECV, 22, 1)
31
+ FIELD(ISR, PTP_SYNC_XMIT, 21, 1)
32
+ FIELD(ISR, PTP_DELAY_REQ_XMIT, 20, 1)
33
+ FIELD(ISR, PTP_SYNC_RECV, 19, 1)
34
+ FIELD(ISR, PTP_DELAY_REQ_RECV, 18, 1)
35
+ FIELD(ISR, PCS_LP_PAGE_RECV, 17, 1)
36
+ FIELD(ISR, PCS_AN_COMPLETE, 16, 1)
37
+ FIELD(ISR, EXT_IRQ, 15, 1)
38
+ FIELD(ISR, PAUSE_FRAME_XMIT, 14, 1)
39
+ FIELD(ISR, PAUSE_TIME_ELAPSED, 13, 1)
40
+ FIELD(ISR, PAUSE_FRAME_RECV, 12, 1)
41
+ FIELD(ISR, RESP_NOT_OK, 11, 1)
42
+ FIELD(ISR, RECV_OVERRUN, 10, 1)
43
+ FIELD(ISR, LINK_CHANGE, 9, 1)
44
+ FIELD(ISR, USXGMII_INT, 8, 1)
45
+ FIELD(ISR, XMIT_COMPLETE, 7, 1)
46
+ FIELD(ISR, AMBA_ERROR, 6, 1)
47
+ FIELD(ISR, RETRY_EXCEEDED, 5, 1)
48
+ FIELD(ISR, XMIT_UNDER_RUN, 4, 1)
49
+ FIELD(ISR, TX_USED, 3, 1)
50
+ FIELD(ISR, RX_USED, 2, 1)
51
+ FIELD(ISR, RECV_COMPLETE, 1, 1)
52
+ FIELD(ISR, MGNT_FRAME_SENT, 0, 1)
53
REG32(IER, 0x28) /* Interrupt Enable reg */
54
REG32(IDR, 0x2c) /* Interrupt Disable reg */
55
REG32(IMR, 0x30) /* Interrupt Mask reg */
56
+
57
REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
58
REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
59
REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
60
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
61
/*****************************************/
62
63
64
-/* GEM_ISR GEM_IER GEM_IDR GEM_IMR */
65
-#define GEM_INT_TXCMPL 0x00000080 /* Transmit Complete */
66
-#define GEM_INT_AMBA_ERR 0x00000040
67
-#define GEM_INT_TXUSED 0x00000008
68
-#define GEM_INT_RXUSED 0x00000004
69
-#define GEM_INT_RXCMPL 0x00000002
70
71
#define GEM_PHYMNTNC_OP_R 0x20000000 /* read operation */
72
#define GEM_PHYMNTNC_OP_W 0x10000000 /* write operation */
73
@@ -XXX,XX +XXX,XX @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
74
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
75
DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
76
s->regs[R_RXSTATUS] |= R_RXSTATUS_BUF_NOT_AVAILABLE_MASK;
77
- gem_set_isr(s, q, GEM_INT_RXUSED);
78
+ gem_set_isr(s, q, R_ISR_RX_USED_MASK);
79
/* Handle interrupt consequences */
80
gem_update_int_status(s);
81
}
82
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
83
84
if (size > gem_get_max_buf_len(s, false)) {
85
qemu_log_mask(LOG_GUEST_ERROR, "rx frame too long\n");
86
- gem_set_isr(s, q, GEM_INT_AMBA_ERR);
87
+ gem_set_isr(s, q, R_ISR_AMBA_ERROR_MASK);
88
return -1;
89
}
90
91
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
92
gem_receive_updatestats(s, buf, size);
93
94
s->regs[R_RXSTATUS] |= R_RXSTATUS_FRAME_RECEIVED_MASK;
95
- gem_set_isr(s, q, GEM_INT_RXCMPL);
96
+ gem_set_isr(s, q, R_ISR_RECV_COMPLETE_MASK);
97
98
/* Handle interrupt consequences */
99
gem_update_int_status(s);
100
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
101
HWADDR_PRIx " too large: size 0x%x space 0x%zx\n",
102
packet_desc_addr, tx_desc_get_length(desc),
103
gem_get_max_buf_len(s, true) - (p - s->tx_packet));
104
- gem_set_isr(s, q, GEM_INT_AMBA_ERR);
105
+ gem_set_isr(s, q, R_ISR_AMBA_ERROR_MASK);
106
break;
107
}
108
109
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
110
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
111
112
s->regs[R_TXSTATUS] |= R_TXSTATUS_TRANSMIT_COMPLETE_MASK;
113
- gem_set_isr(s, q, GEM_INT_TXCMPL);
114
+ gem_set_isr(s, q, R_ISR_XMIT_COMPLETE_MASK);
115
116
/* Handle interrupt consequences */
117
gem_update_int_status(s);
118
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
119
s->regs[R_TXSTATUS] |= R_TXSTATUS_USED_BIT_READ_MASK;
120
/* IRQ TXUSED is defined only for queue 0 */
121
if (q == 0) {
122
- gem_set_isr(s, 0, GEM_INT_TXUSED);
123
+ gem_set_isr(s, 0, R_ISR_TX_USED_MASK);
124
}
125
gem_update_int_status(s);
126
}
127
--
128
2.34.1
diff view generated by jsdifflib
Deleted patch
1
From: Luc Michel <luc.michel@amd.com>
2
1
3
Use the FIELD macro to describe the PHYMNTNC register fields.
4
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
6
Reviewed-by: sai.pavan.boddu@amd.com
7
Message-id: 20231017194422.4124691-10-luc.michel@amd.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
hw/net/cadence_gem.c | 27 ++++++++++++++-------------
11
1 file changed, 14 insertions(+), 13 deletions(-)
12
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/net/cadence_gem.c
16
+++ b/hw/net/cadence_gem.c
17
@@ -XXX,XX +XXX,XX @@ REG32(IDR, 0x2c) /* Interrupt Disable reg */
18
REG32(IMR, 0x30) /* Interrupt Mask reg */
19
20
REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
21
+ FIELD(PHYMNTNC, DATA, 0, 16)
22
+ FIELD(PHYMNTNC, REG_ADDR, 18, 5)
23
+ FIELD(PHYMNTNC, PHY_ADDR, 23, 5)
24
+ FIELD(PHYMNTNC, OP, 28, 2)
25
+ FIELD(PHYMNTNC, ST, 30, 2)
26
+#define MDIO_OP_READ 0x3
27
+#define MDIO_OP_WRITE 0x2
28
+
29
REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
30
REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
31
REG32(TXPARTIALSF, 0x40) /* TX Partial Store and Forward */
32
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
33
34
35
36
-#define GEM_PHYMNTNC_OP_R 0x20000000 /* read operation */
37
-#define GEM_PHYMNTNC_OP_W 0x10000000 /* write operation */
38
-#define GEM_PHYMNTNC_ADDR 0x0F800000 /* Address bits */
39
-#define GEM_PHYMNTNC_ADDR_SHFT 23
40
-#define GEM_PHYMNTNC_REG 0x007C0000 /* register bits */
41
-#define GEM_PHYMNTNC_REG_SHIFT 18
42
-
43
/* Marvell PHY definitions */
44
#define BOARD_PHY_ADDRESS 0 /* PHY address we will emulate a device at */
45
46
@@ -XXX,XX +XXX,XX @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
47
/* The interrupts get updated at the end of the function. */
48
break;
49
case R_PHYMNTNC:
50
- if (retval & GEM_PHYMNTNC_OP_R) {
51
+ if (FIELD_EX32(retval, PHYMNTNC, OP) == MDIO_OP_READ) {
52
uint32_t phy_addr, reg_num;
53
54
- phy_addr = (retval & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
55
+ phy_addr = FIELD_EX32(retval, PHYMNTNC, PHY_ADDR);
56
if (phy_addr == s->phy_addr) {
57
- reg_num = (retval & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
58
+ reg_num = FIELD_EX32(retval, PHYMNTNC, REG_ADDR);
59
retval &= 0xFFFF0000;
60
retval |= gem_phy_read(s, reg_num);
61
} else {
62
@@ -XXX,XX +XXX,XX @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
63
s->sar_active[(offset - R_SPADDR1HI) / 2] = true;
64
break;
65
case R_PHYMNTNC:
66
- if (val & GEM_PHYMNTNC_OP_W) {
67
+ if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_WRITE) {
68
uint32_t phy_addr, reg_num;
69
70
- phy_addr = (val & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
71
+ phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR);
72
if (phy_addr == s->phy_addr) {
73
- reg_num = (val & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
74
+ reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR);
75
gem_phy_write(s, reg_num, val);
76
}
77
}
78
--
79
2.34.1
diff view generated by jsdifflib