1
First pullreq for arm of the 4.1 series, since I'm back from
1
Hi; here's the latest target-arm queue. Mostly this is refactoring
2
holiday now. This is mostly my M-profile FPU series and Philippe's
2
and cleanup type patches.
3
devices.h cleanup. I have a pile of other patchsets to work through
4
in my to-review folder, but 42 patches is definitely quite
5
big enough to send now...
6
3
7
thanks
4
thanks
8
-- PMM
5
-- PMM
9
6
10
The following changes since commit 413a99a92c13ec408dcf2adaa87918dc81e890c8:
7
The following changes since commit c60be6e3e38cb36dc66129e757ec4b34152232be:
11
8
12
Add Nios II semihosting support. (2019-04-29 16:09:51 +0100)
9
Merge tag 'pull-sp-20231025' of https://gitlab.com/rth7680/qemu into staging (2023-10-27 09:43:53 +0900)
13
10
14
are available in the Git repository at:
11
are available in the Git repository at:
15
12
16
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190429
13
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20231027
17
14
18
for you to fetch changes up to 437cc27ddfded3bbab6afd5ac1761e0e195edba7:
15
for you to fetch changes up to df93de987f423a0ed918c425f5dbd9a25d3c6229:
19
16
20
hw/devices: Move SMSC 91C111 declaration into a new header (2019-04-29 17:57:21 +0100)
17
hw/net/cadence_gem: enforce 32 bits variable size for CRC (2023-10-27 15:27:06 +0100)
21
18
22
----------------------------------------------------------------
19
----------------------------------------------------------------
23
target-arm queue:
20
target-arm queue:
24
* remove "bag of random stuff" hw/devices.h header
21
* Correct minor errors in Cortex-A710 definition
25
* implement FPU for Cortex-M and enable it for Cortex-M4 and -M33
22
* Implement Neoverse N2 CPU model
26
* hw/dma: Compile the bcm2835_dma device as common object
23
* Refactor feature test functions out into separate header
27
* configure: Remove --source-path option
24
* Fix syndrome for FGT traps on ERET
28
* hw/ssi/xilinx_spips: Avoid variable length array
25
* Remove 'hw/arm/boot.h' includes from various header files
29
* hw/arm/smmuv3: Remove SMMUNotifierNode
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
30
32
31
----------------------------------------------------------------
33
----------------------------------------------------------------
32
Eric Auger (1):
34
Glenn Miles (1):
33
hw/arm/smmuv3: Remove SMMUNotifierNode
35
misc/led: LED state is set opposite of what is expected
34
36
35
Peter Maydell (28):
37
Luc Michel (11):
36
hw/ssi/xilinx_spips: Avoid variable length array
38
hw/net/cadence_gem: use REG32 macro for register definitions
37
configure: Remove --source-path option
39
hw/net/cadence_gem: use FIELD for screening registers
38
target/arm: Make sure M-profile FPSCR RES0 bits are not settable
40
hw/net/cadence_gem: use FIELD to describe NWCTRL register fields
39
hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers
41
hw/net/cadence_gem: use FIELD to describe NWCFG register fields
40
target/arm: Implement dummy versions of M-profile FP-related registers
42
hw/net/cadence_gem: use FIELD to describe DMACFG register fields
41
target/arm: Disable most VFP sysregs for M-profile
43
hw/net/cadence_gem: use FIELD to describe [TX|RX]STATUS register fields
42
target/arm: Honour M-profile FP enable bits
44
hw/net/cadence_gem: use FIELD to describe IRQ register fields
43
target/arm: Decode FP instructions for M profile
45
hw/net/cadence_gem: use FIELD to describe DESCONF6 register fields
44
target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present
46
hw/net/cadence_gem: use FIELD to describe PHYMNTNC register fields
45
target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL
47
hw/net/cadence_gem: perform PHY access on write only
46
target/arm/helper: don't return early for STKOF faults during stacking
48
hw/net/cadence_gem: enforce 32 bits variable size for CRC
47
target/arm: Handle floating point registers in exception entry
48
target/arm: Implement v7m_update_fpccr()
49
target/arm: Clear CONTROL.SFPA in BXNS and BLXNS
50
target/arm: Clean excReturn bits when tail chaining
51
target/arm: Allow for floating point in callee stack integrity check
52
target/arm: Handle floating point registers in exception return
53
target/arm: Move NS TBFLAG from bit 19 to bit 6
54
target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags
55
target/arm: Set FPCCR.S when executing M-profile floating point insns
56
target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set
57
target/arm: New helper function arm_v7m_mmu_idx_all()
58
target/arm: New function armv7m_nvic_set_pending_lazyfp()
59
target/arm: Add lazy-FP-stacking support to v7m_stack_write()
60
target/arm: Implement M-profile lazy FP state preservation
61
target/arm: Implement VLSTM for v7M CPUs with an FPU
62
target/arm: Implement VLLDM for v7M CPUs with an FPU
63
target/arm: Enable FPU for Cortex-M4 and Cortex-M33
64
49
65
Philippe Mathieu-Daudé (13):
50
Peter Maydell (9):
66
hw/dma: Compile the bcm2835_dma device as common object
51
target/arm: Correct minor errors in Cortex-A710 definition
67
hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string
52
target/arm: Implement Neoverse N2 CPU model
68
hw/arm/nseries: Use TYPE_TMP105 instead of hardcoded string
53
target/arm: Move feature test functions to their own header
69
hw/display/tc6393xb: Remove unused functions
54
target/arm: Move ID_AA64MMFR1 and ID_AA64MMFR2 tests together
70
hw/devices: Move TC6393XB declarations into a new header
55
target/arm: Move ID_AA64MMFR0 tests up to before MMFR1 and MMFR2
71
hw/devices: Move Blizzard declarations into a new header
56
target/arm: Move ID_AA64ISAR* test functions together
72
hw/devices: Move CBus declarations into a new header
57
target/arm: Move ID_AA64PFR* tests together
73
hw/devices: Move Gamepad declarations into a new header
58
target/arm: Move ID_AA64DFR* feature tests together
74
hw/devices: Move TI touchscreen declarations into a new header
59
target/arm: Fix syndrome for FGT traps on ERET
75
hw/devices: Move LAN9118 declarations into a new header
76
hw/net/ne2000-isa: Add guards to the header
77
hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string
78
hw/devices: Move SMSC 91C111 declaration into a new header
79
60
80
configure | 10 +-
61
Philippe Mathieu-Daudé (20):
81
hw/dma/Makefile.objs | 2 +-
62
hw/arm/allwinner-a10: Remove 'hw/arm/boot.h' from header
82
include/hw/arm/omap.h | 6 +-
63
hw/arm/allwinner-h3: Remove 'hw/arm/boot.h' from header
83
include/hw/arm/smmu-common.h | 8 +-
64
hw/arm/allwinner-r40: Remove 'hw/arm/boot.h' from header
84
include/hw/devices.h | 62 ---
65
hw/arm/fsl-imx25: Remove 'hw/arm/boot.h' from header
85
include/hw/display/blizzard.h | 22 ++
66
hw/arm/fsl-imx31: Remove 'hw/arm/boot.h' from header
86
include/hw/display/tc6393xb.h | 24 ++
67
hw/arm/fsl-imx6: Remove 'hw/arm/boot.h' from header
87
include/hw/input/gamepad.h | 19 +
68
hw/arm/fsl-imx6ul: Remove 'hw/arm/boot.h' from header
88
include/hw/input/tsc2xxx.h | 36 ++
69
hw/arm/fsl-imx7: Remove 'hw/arm/boot.h' from header
89
include/hw/misc/cbus.h | 32 ++
70
hw/arm/xlnx-versal: Remove 'hw/arm/boot.h' from header
90
include/hw/net/lan9118.h | 21 +
71
hw/arm/xlnx-zynqmp: Remove 'hw/arm/boot.h' from header
91
include/hw/net/ne2000-isa.h | 6 +
72
hw/sd/pxa2xx: Realize sysbus device before accessing it
92
include/hw/net/smc91c111.h | 19 +
73
hw/sd/pxa2xx: Do not open-code sysbus_create_simple()
93
include/qemu/typedefs.h | 1 -
74
hw/pcmcia/pxa2xx: Realize sysbus device before accessing it
94
target/arm/cpu.h | 95 ++++-
75
hw/pcmcia/pxa2xx: Do not open-code sysbus_create_simple()
95
target/arm/helper.h | 5 +
76
hw/pcmcia/pxa2xx: Inline pxa2xx_pcmcia_init()
96
target/arm/translate.h | 3 +
77
hw/intc/pxa2xx: Convert to Resettable interface
97
hw/arm/aspeed.c | 13 +-
78
hw/intc/pxa2xx: Pass CPU reference using QOM link property
98
hw/arm/exynos4_boards.c | 3 +-
79
hw/intc/pxa2xx: Factor pxa2xx_pic_realize() out of pxa2xx_pic_init()
99
hw/arm/gumstix.c | 2 +-
80
hw/arm/pxa2xx: Realize PXA2XX_I2C device before accessing it
100
hw/arm/integratorcp.c | 2 +-
81
hw/arm: Avoid using 'first_cpu' when first ARM CPU is reachable
101
hw/arm/kzm.c | 2 +-
102
hw/arm/mainstone.c | 2 +-
103
hw/arm/mps2-tz.c | 3 +-
104
hw/arm/mps2.c | 2 +-
105
hw/arm/nseries.c | 7 +-
106
hw/arm/palm.c | 2 +-
107
hw/arm/realview.c | 3 +-
108
hw/arm/smmu-common.c | 6 +-
109
hw/arm/smmuv3.c | 28 +-
110
hw/arm/stellaris.c | 2 +-
111
hw/arm/tosa.c | 2 +-
112
hw/arm/versatilepb.c | 2 +-
113
hw/arm/vexpress.c | 2 +-
114
hw/display/blizzard.c | 2 +-
115
hw/display/tc6393xb.c | 18 +-
116
hw/input/stellaris_input.c | 2 +-
117
hw/input/tsc2005.c | 2 +-
118
hw/input/tsc210x.c | 4 +-
119
hw/intc/armv7m_nvic.c | 261 +++++++++++++
120
hw/misc/cbus.c | 2 +-
121
hw/net/lan9118.c | 3 +-
122
hw/net/smc91c111.c | 2 +-
123
hw/ssi/xilinx_spips.c | 6 +-
124
target/arm/cpu.c | 20 +
125
target/arm/helper.c | 873 +++++++++++++++++++++++++++++++++++++++---
126
target/arm/machine.c | 16 +
127
target/arm/translate.c | 150 +++++++-
128
target/arm/vfp_helper.c | 8 +
129
MAINTAINERS | 7 +
130
50 files changed, 1595 insertions(+), 235 deletions(-)
131
delete mode 100644 include/hw/devices.h
132
create mode 100644 include/hw/display/blizzard.h
133
create mode 100644 include/hw/display/tc6393xb.h
134
create mode 100644 include/hw/input/gamepad.h
135
create mode 100644 include/hw/input/tsc2xxx.h
136
create mode 100644 include/hw/misc/cbus.h
137
create mode 100644 include/hw/net/lan9118.h
138
create mode 100644 include/hw/net/smc91c111.h
139
82
83
docs/system/arm/virt.rst | 1 +
84
bsd-user/arm/target_arch.h | 1 +
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
diff view generated by jsdifflib
1
Enable the FPU by default for the Cortex-M4 and Cortex-M33.
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
2
5
6
Fixes: e3d45c0a89576 ("target/arm: Implement cortex-a710")
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Tested-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
5
Message-id: 20190416125744.27770-27-peter.maydell@linaro.org
9
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
10
Message-id: 20230915185453.1871167-2-peter.maydell@linaro.org
6
---
11
---
7
target/arm/cpu.c | 8 ++++++++
12
target/arm/tcg/cpu64.c | 11 +++++++++--
8
1 file changed, 8 insertions(+)
13
1 file changed, 9 insertions(+), 2 deletions(-)
9
14
10
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
15
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
11
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
12
--- a/target/arm/cpu.c
17
--- a/target/arm/tcg/cpu64.c
13
+++ b/target/arm/cpu.c
18
+++ b/target/arm/tcg/cpu64.c
14
@@ -XXX,XX +XXX,XX @@ static void cortex_m4_initfn(Object *obj)
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cortex_a710_cp_reginfo[] = {
15
set_feature(&cpu->env, ARM_FEATURE_M);
20
{ .name = "CPUPFR_EL3", .state = ARM_CP_STATE_AA64,
16
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
21
.opc0 = 3, .opc1 = 6, .crn = 15, .crm = 8, .opc2 = 6,
17
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
22
.access = PL3_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
18
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
23
+ /*
19
cpu->midr = 0x410fc240; /* r0p0 */
24
+ * Report CPUCFR_EL1.SCU as 1, as we do not implement the DSU
20
cpu->pmsav7_dregion = 8;
25
+ * (and in particular its system registers).
21
+ cpu->isar.mvfr0 = 0x10110021;
26
+ */
22
+ cpu->isar.mvfr1 = 0x11000011;
27
+ { .name = "CPUCFR_EL1", .state = ARM_CP_STATE_AA64,
23
+ cpu->isar.mvfr2 = 0x00000000;
28
+ .opc0 = 3, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
24
cpu->id_pfr0 = 0x00000030;
29
+ .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 4 },
25
cpu->id_pfr1 = 0x00000200;
30
26
cpu->id_dfr0 = 0x00100000;
31
/*
27
@@ -XXX,XX +XXX,XX @@ static void cortex_m33_initfn(Object *obj)
32
* Stub RAMINDEX, as we don't actually implement caches, BTB,
28
set_feature(&cpu->env, ARM_FEATURE_M_MAIN);
33
@@ -XXX,XX +XXX,XX @@ static void aarch64_a710_initfn(Object *obj)
29
set_feature(&cpu->env, ARM_FEATURE_M_SECURITY);
34
cpu->isar.id_aa64pfr0 = 0x1201111120111112ull; /* GIC filled in later */
30
set_feature(&cpu->env, ARM_FEATURE_THUMB_DSP);
35
cpu->isar.id_aa64pfr1 = 0x0000000000000221ull;
31
+ set_feature(&cpu->env, ARM_FEATURE_VFP4);
36
cpu->isar.id_aa64zfr0 = 0x0000110100110021ull; /* with Crypto */
32
cpu->midr = 0x410fd213; /* r0p3 */
37
- cpu->isar.id_aa64dfr0 = 0x000011f010305611ull;
33
cpu->pmsav7_dregion = 16;
38
+ cpu->isar.id_aa64dfr0 = 0x000011f010305619ull;
34
cpu->sau_sregion = 8;
39
cpu->isar.id_aa64dfr1 = 0;
35
+ cpu->isar.mvfr0 = 0x10110021;
40
cpu->id_aa64afr0 = 0;
36
+ cpu->isar.mvfr1 = 0x11000011;
41
cpu->id_aa64afr1 = 0;
37
+ cpu->isar.mvfr2 = 0x00000040;
42
cpu->isar.id_aa64isar0 = 0x0221111110212120ull; /* with Crypto */
38
cpu->id_pfr0 = 0x00000030;
43
- cpu->isar.id_aa64isar1 = 0x0010111101211032ull;
39
cpu->id_pfr1 = 0x00000210;
44
+ cpu->isar.id_aa64isar1 = 0x0010111101211052ull;
40
cpu->id_dfr0 = 0x00200000;
45
cpu->isar.id_aa64mmfr0 = 0x0000022200101122ull;
46
cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
47
cpu->isar.id_aa64mmfr2 = 0x1221011110101011ull;
41
--
48
--
42
2.20.1
49
2.34.1
43
50
44
51
diff view generated by jsdifflib
1
Like AArch64, M-profile floating point has no FPEXC enable
1
Implement a model of the Neoverse N2 CPU. This is an Armv9.0-A
2
bit to gate floating point; so always set the VFPEN TB flag.
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)
3
10
4
M-profile also has CPACR and NSACR similar to A-profile;
11
Because it has 48-bit physical address support, we can use
5
they behave slightly differently:
12
this CPU in the sbsa-ref board as well as the virt board.
6
* the CPACR is banked between Secure and Non-Secure
7
* if the NSACR forces a trap then this is taken to
8
the Secure state, not the Non-Secure state
9
10
Honour the CPACR and NSACR settings. The NSACR handling
11
requires us to borrow the exception.target_el field
12
(usually meaningless for M profile) to distinguish the
13
NOCP UsageFault taken to Secure state from the more
14
usual fault taken to the current security state.
15
13
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Tested-by: Marcin Juszkiewicz <marcin.juszkiewicz@linaro.org>
18
Message-id: 20190416125744.27770-6-peter.maydell@linaro.org
16
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
17
Message-id: 20230915185453.1871167-3-peter.maydell@linaro.org
19
---
18
---
20
target/arm/helper.c | 55 +++++++++++++++++++++++++++++++++++++++---
19
docs/system/arm/virt.rst | 1 +
21
target/arm/translate.c | 10 ++++++--
20
hw/arm/sbsa-ref.c | 1 +
22
2 files changed, 60 insertions(+), 5 deletions(-)
21
hw/arm/virt.c | 1 +
22
target/arm/tcg/cpu64.c | 103 +++++++++++++++++++++++++++++++++++++++
23
4 files changed, 106 insertions(+)
23
24
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst
25
index XXXXXXX..XXXXXXX 100644
26
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
27
--- a/docs/system/arm/virt.rst
27
+++ b/target/arm/helper.c
28
+++ b/docs/system/arm/virt.rst
28
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
29
@@ -XXX,XX +XXX,XX @@ Supported guest CPU types:
29
return target_el;
30
- ``host`` (with KVM only)
31
- ``neoverse-n1`` (64-bit)
32
- ``neoverse-v1`` (64-bit)
33
+- ``neoverse-n2`` (64-bit)
34
- ``max`` (same as ``host`` for KVM; best possible emulation with TCG)
35
36
Note that the default is ``cortex-a15``, so for an AArch64 guest you must
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
62
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/tcg/cpu64.c
64
+++ b/target/arm/tcg/cpu64.c
65
@@ -XXX,XX +XXX,XX @@ static void aarch64_a710_initfn(Object *obj)
66
aarch64_add_sve_properties(obj);
30
}
67
}
31
68
32
+/*
69
+/* Extra IMPDEF regs in the N2 beyond those in the A710 */
33
+ * Return true if the v7M CPACR permits access to the FPU for the specified
70
+static const ARMCPRegInfo neoverse_n2_cp_reginfo[] = {
34
+ * security state and privilege level.
71
+ { .name = "CPURNDBR_EL3", .state = ARM_CP_STATE_AA64,
35
+ */
72
+ .opc0 = 3, .opc1 = 6, .crn = 15, .crm = 3, .opc2 = 0,
36
+static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
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)
37
+{
80
+{
38
+ switch (extract32(env->v7m.cpacr[is_secure], 20, 2)) {
81
+ ARMCPU *cpu = ARM_CPU(obj);
39
+ case 0:
82
+
40
+ case 2: /* UNPREDICTABLE: we treat like 0 */
83
+ cpu->dtb_compatible = "arm,neoverse-n2";
41
+ return false;
84
+ set_feature(&cpu->env, ARM_FEATURE_V8);
42
+ case 1:
85
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
43
+ return is_priv;
86
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
44
+ case 3:
87
+ set_feature(&cpu->env, ARM_FEATURE_AARCH64);
45
+ return true;
88
+ set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
46
+ default:
89
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
47
+ g_assert_not_reached();
90
+ set_feature(&cpu->env, ARM_FEATURE_EL3);
48
+ }
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);
49
+}
169
+}
50
+
170
+
51
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
171
/*
52
ARMMMUIdx mmu_idx, bool ignfault)
172
* -cpu max: a CPU with as many features enabled as our emulation supports.
53
{
173
* The version of '-cpu max' for qemu-system-arm is defined in cpu32.c;
54
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
174
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo aarch64_cpus[] = {
55
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNDEFINSTR_MASK;
175
{ .name = "a64fx", .initfn = aarch64_a64fx_initfn },
56
break;
176
{ .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
57
case EXCP_NOCP:
177
{ .name = "neoverse-v1", .initfn = aarch64_neoverse_v1_initfn },
58
- armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
178
+ { .name = "neoverse-n2", .initfn = aarch64_neoverse_n2_initfn },
59
- env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
179
};
60
+ {
180
61
+ /*
181
static void aarch64_cpu_register_types(void)
62
+ * NOCP might be directed to something other than the current
63
+ * security state if this fault is because of NSACR; we indicate
64
+ * the target security state using exception.target_el.
65
+ */
66
+ int target_secstate;
67
+
68
+ if (env->exception.target_el == 3) {
69
+ target_secstate = M_REG_S;
70
+ } else {
71
+ target_secstate = env->v7m.secure;
72
+ }
73
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, target_secstate);
74
+ env->v7m.cfsr[target_secstate] |= R_V7M_CFSR_NOCP_MASK;
75
break;
76
+ }
77
case EXCP_INVSTATE:
78
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
79
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVSTATE_MASK;
80
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
81
return 0;
82
}
83
84
+ if (arm_feature(env, ARM_FEATURE_M)) {
85
+ /* CPACR can cause a NOCP UsageFault taken to current security state */
86
+ if (!v7m_cpacr_pass(env, env->v7m.secure, cur_el != 0)) {
87
+ return 1;
88
+ }
89
+
90
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) && !env->v7m.secure) {
91
+ if (!extract32(env->v7m.nsacr, 10, 1)) {
92
+ /* FP insns cause a NOCP UsageFault taken to Secure */
93
+ return 3;
94
+ }
95
+ }
96
+
97
+ return 0;
98
+ }
99
+
100
/* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
101
* 0, 2 : trap EL0 and EL1/PL1 accesses
102
* 1 : trap only EL0 accesses
103
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
104
flags = FIELD_DP32(flags, TBFLAG_A32, SCTLR_B, arm_sctlr_b(env));
105
flags = FIELD_DP32(flags, TBFLAG_A32, NS, !access_secure_reg(env));
106
if (env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)
107
- || arm_el_is_aa64(env, 1)) {
108
+ || arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
109
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
110
}
111
flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
112
diff --git a/target/arm/translate.c b/target/arm/translate.c
113
index XXXXXXX..XXXXXXX 100644
114
--- a/target/arm/translate.c
115
+++ b/target/arm/translate.c
116
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
117
* for attempts to execute invalid vfp/neon encodings with FP disabled.
118
*/
119
if (s->fp_excp_el) {
120
- gen_exception_insn(s, 4, EXCP_UDEF,
121
- syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
122
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
123
+ gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
124
+ s->fp_excp_el);
125
+ } else {
126
+ gen_exception_insn(s, 4, EXCP_UDEF,
127
+ syn_fp_access_trap(1, 0xe, false),
128
+ s->fp_excp_el);
129
+ }
130
return 0;
131
}
132
133
--
182
--
134
2.20.1
183
2.34.1
135
184
136
185
diff view generated by jsdifflib
1
The M-profile floating point support has three associated config
1
The feature test functions isar_feature_*() now take up nearly
2
registers: FPCAR, FPCCR and FPDSCR. It also makes the registers
2
a thousand lines in target/arm/cpu.h. This header file is included
3
CPACR and NSACR have behaviour other than reads-as-zero.
3
by a lot of source files, most of which don't need these functions.
4
Add support for all of these as simple reads-as-written registers.
4
Move the feature test functions to their own header file.
5
We will hook up actual functionality later.
6
7
The main complexity here is handling the FPCCR register, which
8
has a mix of banked and unbanked bits.
9
10
Note that we don't share storage with the A-profile
11
cpu->cp15.nsacr and cpu->cp15.cpacr_el1, though the behaviour
12
is quite similar, for two reasons:
13
* the M profile CPACR is banked between security states
14
* it preserves the invariant that M profile uses no state
15
inside the cp15 substruct
16
5
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
18
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
19
Message-id: 20190416125744.27770-4-peter.maydell@linaro.org
9
Message-id: 20231024163510.2972081-2-peter.maydell@linaro.org
20
---
10
---
21
target/arm/cpu.h | 34 ++++++++++++
11
bsd-user/arm/target_arch.h | 1 +
22
hw/intc/armv7m_nvic.c | 125 ++++++++++++++++++++++++++++++++++++++++++
12
linux-user/aarch64/target_prctl.h | 2 +
23
target/arm/cpu.c | 5 ++
13
target/arm/cpu-features.h | 994 ++++++++++++++++++++++++++++++
24
target/arm/machine.c | 16 ++++++
14
target/arm/cpu.h | 971 -----------------------------
25
4 files changed, 180 insertions(+)
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
26
42
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
27
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
1068
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
28
index XXXXXXX..XXXXXXX 100644
1069
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/cpu.h
1070
--- a/target/arm/cpu.h
30
+++ b/target/arm/cpu.h
1071
+++ b/target/arm/cpu.h
31
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
1072
@@ -XXX,XX +XXX,XX @@ static inline target_ulong cpu_untagged_addr(CPUState *cs, target_ulong x)
32
uint32_t scr[M_REG_NUM_BANKS];
1073
}
33
uint32_t msplim[M_REG_NUM_BANKS];
1074
#endif
34
uint32_t psplim[M_REG_NUM_BANKS];
1075
35
+ uint32_t fpcar[M_REG_NUM_BANKS];
1076
-/*
36
+ uint32_t fpccr[M_REG_NUM_BANKS];
1077
- * Naming convention for isar_feature functions:
37
+ uint32_t fpdscr[M_REG_NUM_BANKS];
1078
- * Functions which test 32-bit ID registers should have _aa32_ in
38
+ uint32_t cpacr[M_REG_NUM_BANKS];
1079
- * their name. Functions which test 64-bit ID registers should have
39
+ uint32_t nsacr;
1080
- * _aa64_ in their name. These must only be used in code where we
40
} v7m;
1081
- * know for certain that the CPU has AArch32 or AArch64 respectively
41
1082
- * or where the correct answer for a CPU which doesn't implement that
42
/* Information associated with an exception about to be taken:
1083
- * CPU state is "false" (eg when generating A32 or A64 code, if adding
43
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_CSSELR, LEVEL, 1, 3)
1084
- * system registers that are specific to that CPU state, for "should
44
*/
1085
- * we let this system register bit be set" tests where the 32-bit
45
FIELD(V7M_CSSELR, INDEX, 0, 4)
1086
- * flavour of the register doesn't have the bit, and so on).
46
1087
- * Functions which simply ask "does this feature exist at all" have
47
+/* v7M FPCCR bits */
1088
- * _any_ in their name, and always return the logical OR of the _aa64_
48
+FIELD(V7M_FPCCR, LSPACT, 0, 1)
1089
- * and the _aa32_ function.
49
+FIELD(V7M_FPCCR, USER, 1, 1)
1090
- */
50
+FIELD(V7M_FPCCR, S, 2, 1)
1091
-
51
+FIELD(V7M_FPCCR, THREAD, 3, 1)
1092
-/*
52
+FIELD(V7M_FPCCR, HFRDY, 4, 1)
1093
- * 32-bit feature tests via id registers.
53
+FIELD(V7M_FPCCR, MMRDY, 5, 1)
1094
- */
54
+FIELD(V7M_FPCCR, BFRDY, 6, 1)
1095
-static inline bool isar_feature_aa32_thumb_div(const ARMISARegisters *id)
55
+FIELD(V7M_FPCCR, SFRDY, 7, 1)
1096
-{
56
+FIELD(V7M_FPCCR, MONRDY, 8, 1)
1097
- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) != 0;
57
+FIELD(V7M_FPCCR, SPLIMVIOL, 9, 1)
1098
-}
58
+FIELD(V7M_FPCCR, UFRDY, 10, 1)
1099
-
59
+FIELD(V7M_FPCCR, RES0, 11, 15)
1100
-static inline bool isar_feature_aa32_arm_div(const ARMISARegisters *id)
60
+FIELD(V7M_FPCCR, TS, 26, 1)
1101
-{
61
+FIELD(V7M_FPCCR, CLRONRETS, 27, 1)
1102
- return FIELD_EX32(id->id_isar0, ID_ISAR0, DIVIDE) > 1;
62
+FIELD(V7M_FPCCR, CLRONRET, 28, 1)
1103
-}
63
+FIELD(V7M_FPCCR, LSPENS, 29, 1)
1104
-
64
+FIELD(V7M_FPCCR, LSPEN, 30, 1)
1105
-static inline bool isar_feature_aa32_lob(const ARMISARegisters *id)
65
+FIELD(V7M_FPCCR, ASPEN, 31, 1)
1106
-{
66
+/* These bits are banked. Others are non-banked and live in the M_REG_S bank */
1107
- /* (M-profile) low-overhead loops and branch future */
67
+#define R_V7M_FPCCR_BANKED_MASK \
1108
- return FIELD_EX32(id->id_isar0, ID_ISAR0, CMPBRANCH) >= 3;
68
+ (R_V7M_FPCCR_LSPACT_MASK | \
1109
-}
69
+ R_V7M_FPCCR_USER_MASK | \
1110
-
70
+ R_V7M_FPCCR_THREAD_MASK | \
1111
-static inline bool isar_feature_aa32_jazelle(const ARMISARegisters *id)
71
+ R_V7M_FPCCR_MMRDY_MASK | \
1112
-{
72
+ R_V7M_FPCCR_SPLIMVIOL_MASK | \
1113
- return FIELD_EX32(id->id_isar1, ID_ISAR1, JAZELLE) != 0;
73
+ R_V7M_FPCCR_UFRDY_MASK | \
1114
-}
74
+ R_V7M_FPCCR_ASPEN_MASK)
1115
-
75
+
1116
-static inline bool isar_feature_aa32_aes(const ARMISARegisters *id)
76
/*
1117
-{
77
* System register ID fields.
1118
- return FIELD_EX32(id->id_isar5, ID_ISAR5, AES) != 0;
78
*/
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
2049
index XXXXXXX..XXXXXXX 100644
2050
--- a/target/arm/internals.h
2051
+++ b/target/arm/internals.h
2052
@@ -XXX,XX +XXX,XX @@
2053
#include "hw/registerfields.h"
2054
#include "tcg/tcg-gvec-desc.h"
2055
#include "syndrome.h"
2056
+#include "cpu-features.h"
2057
2058
/* register banks for CPU modes */
2059
#define BANK_USRSYS 0
2060
diff --git a/target/arm/tcg/translate.h b/target/arm/tcg/translate.h
2061
index XXXXXXX..XXXXXXX 100644
2062
--- a/target/arm/tcg/translate.h
2063
+++ b/target/arm/tcg/translate.h
2064
@@ -XXX,XX +XXX,XX @@
2065
#include "exec/translator.h"
2066
#include "exec/helper-gen.h"
2067
#include "internals.h"
2068
-
2069
+#include "cpu-features.h"
2070
2071
/* internal defines */
2072
2073
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
2074
index XXXXXXX..XXXXXXX 100644
2075
--- a/hw/arm/armv7m.c
2076
+++ b/hw/arm/armv7m.c
2077
@@ -XXX,XX +XXX,XX @@
2078
#include "qemu/module.h"
2079
#include "qemu/log.h"
2080
#include "target/arm/idau.h"
2081
+#include "target/arm/cpu-features.h"
2082
#include "migration/vmstate.h"
2083
2084
/* Bitbanded IO. Each word corresponds to a single bit. */
79
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
2085
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
80
index XXXXXXX..XXXXXXX 100644
2086
index XXXXXXX..XXXXXXX 100644
81
--- a/hw/intc/armv7m_nvic.c
2087
--- a/hw/intc/armv7m_nvic.c
82
+++ b/hw/intc/armv7m_nvic.c
2088
+++ b/hw/intc/armv7m_nvic.c
83
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
2089
@@ -XXX,XX +XXX,XX @@
84
}
2090
#include "sysemu/tcg.h"
85
case 0xd84: /* CSSELR */
2091
#include "sysemu/runstate.h"
86
return cpu->env.v7m.csselr[attrs.secure];
2092
#include "target/arm/cpu.h"
87
+ case 0xd88: /* CPACR */
2093
+#include "target/arm/cpu-features.h"
88
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2094
#include "exec/exec-all.h"
89
+ return 0;
2095
#include "exec/memop.h"
90
+ }
2096
#include "qemu/log.h"
91
+ return cpu->env.v7m.cpacr[attrs.secure];
2097
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
92
+ case 0xd8c: /* NSACR */
2098
index XXXXXXX..XXXXXXX 100644
93
+ if (!attrs.secure || !arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2099
--- a/linux-user/aarch64/cpu_loop.c
94
+ return 0;
2100
+++ b/linux-user/aarch64/cpu_loop.c
95
+ }
2101
@@ -XXX,XX +XXX,XX @@
96
+ return cpu->env.v7m.nsacr;
2102
#include "qemu/guest-random.h"
97
/* TODO: Implement debug registers. */
2103
#include "semihosting/common-semi.h"
98
case 0xd90: /* MPU_TYPE */
2104
#include "target/arm/syndrome.h"
99
/* Unified MPU; if the MPU is not present this value is zero */
2105
+#include "target/arm/cpu-features.h"
100
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
2106
101
return 0;
2107
#define get_user_code_u32(x, gaddr, env) \
102
}
2108
({ abi_long __r = get_user_u32((x), (gaddr)); \
103
return cpu->env.v7m.sfar;
2109
diff --git a/linux-user/aarch64/signal.c b/linux-user/aarch64/signal.c
104
+ case 0xf34: /* FPCCR */
2110
index XXXXXXX..XXXXXXX 100644
105
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2111
--- a/linux-user/aarch64/signal.c
106
+ return 0;
2112
+++ b/linux-user/aarch64/signal.c
107
+ }
2113
@@ -XXX,XX +XXX,XX @@
108
+ if (attrs.secure) {
2114
#include "user-internals.h"
109
+ return cpu->env.v7m.fpccr[M_REG_S];
2115
#include "signal-common.h"
110
+ } else {
2116
#include "linux-user/trace.h"
111
+ /*
2117
+#include "target/arm/cpu-features.h"
112
+ * NS can read LSPEN, CLRONRET and MONRDY. It can read
2118
113
+ * BFRDY and HFRDY if AIRCR.BFHFNMINS != 0;
2119
struct target_sigcontext {
114
+ * other non-banked bits RAZ.
2120
uint64_t fault_address;
115
+ * TODO: MONRDY should RAZ/WI if DEMCR.SDME is set.
2121
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
116
+ */
2122
index XXXXXXX..XXXXXXX 100644
117
+ uint32_t value = cpu->env.v7m.fpccr[M_REG_S];
2123
--- a/linux-user/arm/signal.c
118
+ uint32_t mask = R_V7M_FPCCR_LSPEN_MASK |
2124
+++ b/linux-user/arm/signal.c
119
+ R_V7M_FPCCR_CLRONRET_MASK |
2125
@@ -XXX,XX +XXX,XX @@
120
+ R_V7M_FPCCR_MONRDY_MASK;
2126
#include "user-internals.h"
121
+
2127
#include "signal-common.h"
122
+ if (s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) {
2128
#include "linux-user/trace.h"
123
+ mask |= R_V7M_FPCCR_BFRDY_MASK | R_V7M_FPCCR_HFRDY_MASK;
2129
+#include "target/arm/cpu-features.h"
124
+ }
2130
125
+
2131
struct target_sigcontext {
126
+ value &= mask;
2132
abi_ulong trap_no;
127
+
2133
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
128
+ value |= cpu->env.v7m.fpccr[M_REG_NS];
2134
index XXXXXXX..XXXXXXX 100644
129
+ return value;
2135
--- a/linux-user/elfload.c
130
+ }
2136
+++ b/linux-user/elfload.c
131
+ case 0xf38: /* FPCAR */
2137
@@ -XXX,XX +XXX,XX @@
132
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2138
#include "target_signal.h"
133
+ return 0;
2139
#include "accel/tcg/debuginfo.h"
134
+ }
2140
135
+ return cpu->env.v7m.fpcar[attrs.secure];
2141
+#ifdef TARGET_ARM
136
+ case 0xf3c: /* FPDSCR */
2142
+#include "target/arm/cpu-features.h"
137
+ if (!arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2143
+#endif
138
+ return 0;
2144
+
139
+ }
2145
#ifdef _ARCH_PPC64
140
+ return cpu->env.v7m.fpdscr[attrs.secure];
2146
#undef ARCH_DLINFO
141
case 0xf40: /* MVFR0 */
2147
#undef ELF_PLATFORM
142
return cpu->isar.mvfr0;
2148
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
143
case 0xf44: /* MVFR1 */
2149
index XXXXXXX..XXXXXXX 100644
144
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
2150
--- a/linux-user/mmap.c
145
cpu->env.v7m.csselr[attrs.secure] = value & R_V7M_CSSELR_INDEX_MASK;
2151
+++ b/linux-user/mmap.c
146
}
2152
@@ -XXX,XX +XXX,XX @@
147
break;
2153
#include "target_mman.h"
148
+ case 0xd88: /* CPACR */
2154
#include "qemu/interval-tree.h"
149
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2155
150
+ /* We implement only the Floating Point extension's CP10/CP11 */
2156
+#ifdef TARGET_ARM
151
+ cpu->env.v7m.cpacr[attrs.secure] = value & (0xf << 20);
2157
+#include "target/arm/cpu-features.h"
152
+ }
2158
+#endif
153
+ break;
2159
+
154
+ case 0xd8c: /* NSACR */
2160
static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
155
+ if (attrs.secure && arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2161
static __thread int mmap_lock_count;
156
+ /* We implement only the Floating Point extension's CP10/CP11 */
2162
157
+ cpu->env.v7m.nsacr = value & (3 << 10);
2163
diff --git a/target/arm/arch_dump.c b/target/arm/arch_dump.c
158
+ }
2164
index XXXXXXX..XXXXXXX 100644
159
+ break;
2165
--- a/target/arm/arch_dump.c
160
case 0xd90: /* MPU_TYPE */
2166
+++ b/target/arm/arch_dump.c
161
return; /* RO */
2167
@@ -XXX,XX +XXX,XX @@
162
case 0xd94: /* MPU_CTRL */
2168
#include "cpu.h"
163
@@ -XXX,XX +XXX,XX @@ static void nvic_writel(NVICState *s, uint32_t offset, uint32_t value,
2169
#include "elf.h"
164
}
2170
#include "sysemu/dump.h"
165
break;
2171
+#include "cpu-features.h"
166
}
2172
167
+ case 0xf34: /* FPCCR */
2173
/* struct user_pt_regs from arch/arm64/include/uapi/asm/ptrace.h */
168
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
2174
struct aarch64_user_regs {
169
+ /* Not all bits here are banked. */
170
+ uint32_t fpccr_s;
171
+
172
+ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) {
173
+ /* Don't allow setting of bits not present in v7M */
174
+ value &= (R_V7M_FPCCR_LSPACT_MASK |
175
+ R_V7M_FPCCR_USER_MASK |
176
+ R_V7M_FPCCR_THREAD_MASK |
177
+ R_V7M_FPCCR_HFRDY_MASK |
178
+ R_V7M_FPCCR_MMRDY_MASK |
179
+ R_V7M_FPCCR_BFRDY_MASK |
180
+ R_V7M_FPCCR_MONRDY_MASK |
181
+ R_V7M_FPCCR_LSPEN_MASK |
182
+ R_V7M_FPCCR_ASPEN_MASK);
183
+ }
184
+ value &= ~R_V7M_FPCCR_RES0_MASK;
185
+
186
+ if (!attrs.secure) {
187
+ /* Some non-banked bits are configurably writable by NS */
188
+ fpccr_s = cpu->env.v7m.fpccr[M_REG_S];
189
+ if (!(fpccr_s & R_V7M_FPCCR_LSPENS_MASK)) {
190
+ uint32_t lspen = FIELD_EX32(value, V7M_FPCCR, LSPEN);
191
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, LSPEN, lspen);
192
+ }
193
+ if (!(fpccr_s & R_V7M_FPCCR_CLRONRETS_MASK)) {
194
+ uint32_t cor = FIELD_EX32(value, V7M_FPCCR, CLRONRET);
195
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, CLRONRET, cor);
196
+ }
197
+ if ((s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) {
198
+ uint32_t hfrdy = FIELD_EX32(value, V7M_FPCCR, HFRDY);
199
+ uint32_t bfrdy = FIELD_EX32(value, V7M_FPCCR, BFRDY);
200
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
201
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
202
+ }
203
+ /* TODO MONRDY should RAZ/WI if DEMCR.SDME is set */
204
+ {
205
+ uint32_t monrdy = FIELD_EX32(value, V7M_FPCCR, MONRDY);
206
+ fpccr_s = FIELD_DP32(fpccr_s, V7M_FPCCR, MONRDY, monrdy);
207
+ }
208
+
209
+ /*
210
+ * All other non-banked bits are RAZ/WI from NS; write
211
+ * just the banked bits to fpccr[M_REG_NS].
212
+ */
213
+ value &= R_V7M_FPCCR_BANKED_MASK;
214
+ cpu->env.v7m.fpccr[M_REG_NS] = value;
215
+ } else {
216
+ fpccr_s = value;
217
+ }
218
+ cpu->env.v7m.fpccr[M_REG_S] = fpccr_s;
219
+ }
220
+ break;
221
+ case 0xf38: /* FPCAR */
222
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
223
+ value &= ~7;
224
+ cpu->env.v7m.fpcar[attrs.secure] = value;
225
+ }
226
+ break;
227
+ case 0xf3c: /* FPDSCR */
228
+ if (arm_feature(&cpu->env, ARM_FEATURE_VFP)) {
229
+ value &= 0x07c00000;
230
+ cpu->env.v7m.fpdscr[attrs.secure] = value;
231
+ }
232
+ break;
233
case 0xf50: /* ICIALLU */
234
case 0xf58: /* ICIMVAU */
235
case 0xf5c: /* DCIMVAC */
236
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
2175
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
237
index XXXXXXX..XXXXXXX 100644
2176
index XXXXXXX..XXXXXXX 100644
238
--- a/target/arm/cpu.c
2177
--- a/target/arm/cpu.c
239
+++ b/target/arm/cpu.c
2178
+++ b/target/arm/cpu.c
240
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
2179
@@ -XXX,XX +XXX,XX @@
241
env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
2180
#include "hw/core/tcg-cpu-ops.h"
242
}
2181
#endif /* CONFIG_TCG */
243
2182
#include "internals.h"
244
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
2183
+#include "cpu-features.h"
245
+ env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
2184
#include "exec/exec-all.h"
246
+ env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
2185
#include "hw/qdev-properties.h"
247
+ R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
2186
#if !defined(CONFIG_USER_ONLY)
248
+ }
2187
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
249
/* Unlike A/R profile, M profile defines the reset LR value */
2188
index XXXXXXX..XXXXXXX 100644
250
env->regs[14] = 0xffffffff;
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
2224
index XXXXXXX..XXXXXXX 100644
2225
--- a/target/arm/helper.c
2226
+++ b/target/arm/helper.c
2227
@@ -XXX,XX +XXX,XX @@
2228
#include "trace.h"
2229
#include "cpu.h"
2230
#include "internals.h"
2231
+#include "cpu-features.h"
2232
#include "exec/helper-proto.h"
2233
#include "qemu/main-loop.h"
2234
#include "qemu/timer.h"
2235
diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c
2236
index XXXXXXX..XXXXXXX 100644
2237
--- a/target/arm/kvm64.c
2238
+++ b/target/arm/kvm64.c
2239
@@ -XXX,XX +XXX,XX @@
2240
#include "sysemu/kvm_int.h"
2241
#include "kvm_arm.h"
2242
#include "internals.h"
2243
+#include "cpu-features.h"
2244
#include "hw/acpi/acpi.h"
2245
#include "hw/acpi/ghes.h"
251
2246
252
diff --git a/target/arm/machine.c b/target/arm/machine.c
2247
diff --git a/target/arm/machine.c b/target/arm/machine.c
253
index XXXXXXX..XXXXXXX 100644
2248
index XXXXXXX..XXXXXXX 100644
254
--- a/target/arm/machine.c
2249
--- a/target/arm/machine.c
255
+++ b/target/arm/machine.c
2250
+++ b/target/arm/machine.c
256
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m_v8m = {
2251
@@ -XXX,XX +XXX,XX @@
257
}
2252
#include "sysemu/tcg.h"
258
};
2253
#include "kvm_arm.h"
259
2254
#include "internals.h"
260
+static const VMStateDescription vmstate_m_fp = {
2255
+#include "cpu-features.h"
261
+ .name = "cpu/m/fp",
2256
#include "migration/cpu.h"
262
+ .version_id = 1,
2257
263
+ .minimum_version_id = 1,
2258
static bool vfp_needed(void *opaque)
264
+ .needed = vfp_needed,
2259
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
265
+ .fields = (VMStateField[]) {
2260
index XXXXXXX..XXXXXXX 100644
266
+ VMSTATE_UINT32_ARRAY(env.v7m.fpcar, ARMCPU, M_REG_NUM_BANKS),
2261
--- a/target/arm/ptw.c
267
+ VMSTATE_UINT32_ARRAY(env.v7m.fpccr, ARMCPU, M_REG_NUM_BANKS),
2262
+++ b/target/arm/ptw.c
268
+ VMSTATE_UINT32_ARRAY(env.v7m.fpdscr, ARMCPU, M_REG_NUM_BANKS),
2263
@@ -XXX,XX +XXX,XX @@
269
+ VMSTATE_UINT32_ARRAY(env.v7m.cpacr, ARMCPU, M_REG_NUM_BANKS),
2264
#include "exec/exec-all.h"
270
+ VMSTATE_UINT32(env.v7m.nsacr, ARMCPU),
2265
#include "cpu.h"
271
+ VMSTATE_END_OF_LIST()
2266
#include "internals.h"
272
+ }
2267
+#include "cpu-features.h"
273
+};
2268
#include "idau.h"
274
+
2269
#ifdef CONFIG_TCG
275
static const VMStateDescription vmstate_m = {
2270
# include "tcg/oversized-guest.h"
276
.name = "cpu/m",
2271
diff --git a/target/arm/tcg/cpu64.c b/target/arm/tcg/cpu64.c
277
.version_id = 4,
2272
index XXXXXXX..XXXXXXX 100644
278
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_m = {
2273
--- a/target/arm/tcg/cpu64.c
279
&vmstate_m_scr,
2274
+++ b/target/arm/tcg/cpu64.c
280
&vmstate_m_other_sp,
2275
@@ -XXX,XX +XXX,XX @@
281
&vmstate_m_v8m,
2276
#include "hw/qdev-properties.h"
282
+ &vmstate_m_fp,
2277
#include "qemu/units.h"
283
NULL
2278
#include "internals.h"
284
}
2279
+#include "cpu-features.h"
285
};
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"
286
--
2355
--
287
2.20.1
2356
2.34.1
288
2357
289
2358
diff view generated by jsdifflib
1
Implement the VLLDM instruction for v7M for the FPU present cas.
1
Our list of isar_feature functions is not in any particular order,
2
but tests on fields of the same ID register tend to be grouped
3
together. A few functions that are tests of fields in ID_AA64MMFR1
4
and ID_AA64MMFR2 are not in the same place as the rest; move them
5
into their groups.
2
6
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-26-peter.maydell@linaro.org
10
Message-id: 20231024163510.2972081-3-peter.maydell@linaro.org
6
---
11
---
7
target/arm/helper.h | 1 +
12
target/arm/cpu-features.h | 60 +++++++++++++++++++--------------------
8
target/arm/helper.c | 54 ++++++++++++++++++++++++++++++++++++++++++
13
1 file changed, 30 insertions(+), 30 deletions(-)
9
target/arm/translate.c | 2 +-
10
3 files changed, 56 insertions(+), 1 deletion(-)
11
14
12
diff --git a/target/arm/helper.h b/target/arm/helper.h
15
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.h
17
--- a/target/arm/cpu-features.h
15
+++ b/target/arm/helper.h
18
+++ b/target/arm/cpu-features.h
16
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
19
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_tidcp1(const ARMISARegisters *id)
17
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
20
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR1, TIDCP1) != 0;
18
19
DEF_HELPER_2(v7m_vlstm, void, env, i32)
20
+DEF_HELPER_2(v7m_vlldm, void, env, i32)
21
22
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
23
24
diff --git a/target/arm/helper.c b/target/arm/helper.c
25
index XXXXXXX..XXXXXXX 100644
26
--- a/target/arm/helper.c
27
+++ b/target/arm/helper.c
28
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
29
g_assert_not_reached();
30
}
21
}
31
22
32
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
23
+static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
33
+{
24
+{
34
+ /* translate.c should never generate calls here in user-only mode */
25
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
35
+ g_assert_not_reached();
36
+}
26
+}
37
+
27
+
38
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
28
+static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
39
{
40
/* The TT instructions can be used by unprivileged code, but in
41
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
42
env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
43
}
44
45
+void HELPER(v7m_vlldm)(CPUARMState *env, uint32_t fptr)
46
+{
29
+{
47
+ /* fptr is the value of Rn, the frame pointer we load the FP regs from */
30
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
48
+ assert(env->v7m.secure);
49
+
50
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
51
+ return;
52
+ }
53
+
54
+ /* Check access to the coprocessor is permitted */
55
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
56
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
57
+ }
58
+
59
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
60
+ /* State in FP is still valid */
61
+ env->v7m.fpccr[M_REG_S] &= ~R_V7M_FPCCR_LSPACT_MASK;
62
+ } else {
63
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
64
+ int i;
65
+ uint32_t fpscr;
66
+
67
+ if (fptr & 7) {
68
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
69
+ }
70
+
71
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
72
+ uint32_t slo, shi;
73
+ uint64_t dn;
74
+ uint32_t faddr = fptr + 4 * i;
75
+
76
+ if (i >= 16) {
77
+ faddr += 8; /* skip the slot for the FPSCR */
78
+ }
79
+
80
+ slo = cpu_ldl_data(env, faddr);
81
+ shi = cpu_ldl_data(env, faddr + 4);
82
+
83
+ dn = (uint64_t) shi << 32 | slo;
84
+ *aa32_vfp_dreg(env, i / 2) = dn;
85
+ }
86
+ fpscr = cpu_ldl_data(env, fptr + 0x40);
87
+ vfp_set_fpscr(env, fpscr);
88
+ }
89
+
90
+ env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
91
+}
31
+}
92
+
32
+
93
static bool v7m_push_stack(ARMCPU *cpu)
33
+static inline bool isar_feature_aa64_tts2uxn(const ARMISARegisters *id)
34
+{
35
+ return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, XNX) != 0;
36
+}
37
+
38
static inline bool isar_feature_aa64_uao(const ARMISARegisters *id)
94
{
39
{
95
/* Do the "set up stack frame" part of exception entry,
40
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, UAO) != 0;
96
diff --git a/target/arm/translate.c b/target/arm/translate.c
41
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_evt(const ARMISARegisters *id)
97
index XXXXXXX..XXXXXXX 100644
42
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, EVT) >= 2;
98
--- a/target/arm/translate.c
43
}
99
+++ b/target/arm/translate.c
44
100
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
45
+static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
101
TCGv_i32 fptr = load_reg(s, rn);
46
+{
102
47
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
103
if (extract32(insn, 20, 1)) {
48
+}
104
- /* VLLDM */
49
+
105
+ gen_helper_v7m_vlldm(cpu_env, fptr);
50
+static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
106
} else {
51
+{
107
gen_helper_v7m_vlstm(cpu_env, fptr);
52
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
108
}
53
+}
54
+
55
+static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
56
+{
57
+ return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
58
+}
59
+
60
static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
61
{
62
return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
63
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fgt(const ARMISARegisters *id)
64
return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, FGT) != 0;
65
}
66
67
-static inline bool isar_feature_aa64_ccidx(const ARMISARegisters *id)
68
-{
69
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, CCIDX) != 0;
70
-}
71
-
72
-static inline bool isar_feature_aa64_lva(const ARMISARegisters *id)
73
-{
74
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, VARANGE) != 0;
75
-}
76
-
77
-static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
78
-{
79
- return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
80
-}
81
-
82
-static inline bool isar_feature_aa64_hafs(const ARMISARegisters *id)
83
-{
84
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) != 0;
85
-}
86
-
87
-static inline bool isar_feature_aa64_hdbs(const ARMISARegisters *id)
88
-{
89
- return FIELD_EX64(id->id_aa64mmfr1, ID_AA64MMFR1, HAFDBS) >= 2;
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;
109
--
100
--
110
2.20.1
101
2.34.1
111
102
112
103
diff view generated by jsdifflib
1
The M-profile architecture floating point system supports
1
Move the ID_AA64MMFR0 feature test functions up so they are
2
lazy FP state preservation, where FP registers are not
2
before the ones for ID_AA64MMFR1 and ID_AA64MMFR2.
3
pushed to the stack when an exception occurs but are instead
4
only saved if and when the first FP instruction in the exception
5
handler is executed. Implement this in QEMU, corresponding
6
to the check of LSPACT in the pseudocode ExecuteFPCheck().
7
3
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Message-id: 20190416125744.27770-24-peter.maydell@linaro.org
7
Message-id: 20231024163510.2972081-4-peter.maydell@linaro.org
11
---
8
---
12
target/arm/cpu.h | 3 ++
9
target/arm/cpu-features.h | 120 +++++++++++++++++++-------------------
13
target/arm/helper.h | 2 +
10
1 file changed, 60 insertions(+), 60 deletions(-)
14
target/arm/translate.h | 1 +
15
target/arm/helper.c | 112 +++++++++++++++++++++++++++++++++++++++++
16
target/arm/translate.c | 22 ++++++++
17
5 files changed, 140 insertions(+)
18
11
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
20
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
14
--- a/target/arm/cpu-features.h
22
+++ b/target/arm/cpu.h
15
+++ b/target/arm/cpu-features.h
23
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
24
#define EXCP_NOCP 17 /* v7M NOCP UsageFault */
17
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
25
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
26
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
27
+#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
28
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
29
30
#define ARMV7M_EXCP_RESET 1
31
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
32
FIELD(TBFLAG_A32, VFPEN, 7, 1)
33
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
34
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
35
+/* For M profile only, set if FPCCR.LSPACT is set */
36
+FIELD(TBFLAG_A32, LSPACT, 18, 1)
37
/* For M profile only, set if we must create a new FP context */
38
FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
39
/* For M profile only, set if FPCCR.S does not match current security state */
40
diff --git a/target/arm/helper.h b/target/arm/helper.h
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.h
43
+++ b/target/arm/helper.h
44
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(v7m_blxns, void, env, i32)
45
46
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
47
48
+DEF_HELPER_1(v7m_preserve_fp_state, void, env)
49
+
50
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
51
52
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
53
diff --git a/target/arm/translate.h b/target/arm/translate.h
54
index XXXXXXX..XXXXXXX 100644
55
--- a/target/arm/translate.h
56
+++ b/target/arm/translate.h
57
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
58
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
59
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
60
bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
61
+ bool v7m_lspact; /* FPCCR.LSPACT set */
62
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
63
* so that top level loop can generate correct syndrome information.
64
*/
65
diff --git a/target/arm/helper.c b/target/arm/helper.c
66
index XXXXXXX..XXXXXXX 100644
67
--- a/target/arm/helper.c
68
+++ b/target/arm/helper.c
69
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
70
g_assert_not_reached();
71
}
18
}
72
19
73
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
20
+static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
74
+{
21
+{
75
+ /* translate.c should never generate calls here in user-only mode */
22
+ return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
76
+ g_assert_not_reached();
77
+}
23
+}
78
+
24
+
79
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
25
+static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
80
{
81
/* The TT instructions can be used by unprivileged code, but in
82
@@ -XXX,XX +XXX,XX @@ pend_fault:
83
return false;
84
}
85
86
+void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
87
+{
26
+{
88
+ /*
27
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
89
+ * Preserve FP state (because LSPACT was set and we are about
28
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
90
+ * to execute an FP instruction). This corresponds to the
91
+ * PreserveFPState() pseudocode.
92
+ * We may throw an exception if the stacking fails.
93
+ */
94
+ ARMCPU *cpu = arm_env_get_cpu(env);
95
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
96
+ bool negpri = !(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_HFRDY_MASK);
97
+ bool is_priv = !(env->v7m.fpccr[is_secure] & R_V7M_FPCCR_USER_MASK);
98
+ bool splimviol = env->v7m.fpccr[is_secure] & R_V7M_FPCCR_SPLIMVIOL_MASK;
99
+ uint32_t fpcar = env->v7m.fpcar[is_secure];
100
+ bool stacked_ok = true;
101
+ bool ts = is_secure && (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
102
+ bool take_exception;
103
+
104
+ /* Take the iothread lock as we are going to touch the NVIC */
105
+ qemu_mutex_lock_iothread();
106
+
107
+ /* Check the background context had access to the FPU */
108
+ if (!v7m_cpacr_pass(env, is_secure, is_priv)) {
109
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, is_secure);
110
+ env->v7m.cfsr[is_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ stacked_ok = false;
112
+ } else if (!is_secure && !extract32(env->v7m.nsacr, 10, 1)) {
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
114
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
115
+ stacked_ok = false;
116
+ }
117
+
118
+ if (!splimviol && stacked_ok) {
119
+ /* We only stack if the stack limit wasn't violated */
120
+ int i;
121
+ ARMMMUIdx mmu_idx;
122
+
123
+ mmu_idx = arm_v7m_mmu_idx_all(env, is_secure, is_priv, negpri);
124
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
125
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
126
+ uint32_t faddr = fpcar + 4 * i;
127
+ uint32_t slo = extract64(dn, 0, 32);
128
+ uint32_t shi = extract64(dn, 32, 32);
129
+
130
+ if (i >= 16) {
131
+ faddr += 8; /* skip the slot for the FPSCR */
132
+ }
133
+ stacked_ok = stacked_ok &&
134
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, STACK_LAZYFP) &&
135
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, STACK_LAZYFP);
136
+ }
137
+
138
+ stacked_ok = stacked_ok &&
139
+ v7m_stack_write(cpu, fpcar + 0x40,
140
+ vfp_get_fpscr(env), mmu_idx, STACK_LAZYFP);
141
+ }
142
+
143
+ /*
144
+ * We definitely pended an exception, but it's possible that it
145
+ * might not be able to be taken now. If its priority permits us
146
+ * to take it now, then we must not update the LSPACT or FP regs,
147
+ * but instead jump out to take the exception immediately.
148
+ * If it's just pending and won't be taken until the current
149
+ * handler exits, then we do update LSPACT and the FP regs.
150
+ */
151
+ take_exception = !stacked_ok &&
152
+ armv7m_nvic_can_take_pending_exception(env->nvic);
153
+
154
+ qemu_mutex_unlock_iothread();
155
+
156
+ if (take_exception) {
157
+ raise_exception_ra(env, EXCP_LAZYFP, 0, 1, GETPC());
158
+ }
159
+
160
+ env->v7m.fpccr[is_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
161
+
162
+ if (ts) {
163
+ /* Clear s0 to s31 and the FPSCR */
164
+ int i;
165
+
166
+ for (i = 0; i < 32; i += 2) {
167
+ *aa32_vfp_dreg(env, i / 2) = 0;
168
+ }
169
+ vfp_set_fpscr(env, 0);
170
+ }
171
+ /*
172
+ * Otherwise s0 to s15 and FPSCR are UNKNOWN; we choose to leave them
173
+ * unchanged.
174
+ */
175
+}
29
+}
176
+
30
+
177
/* Write to v7M CONTROL.SPSEL bit for the specified security bank.
31
+static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
178
* This may change the current stack pointer between Main and Process
32
+{
179
* stack pointers if it is done for the CONTROL register for the current
33
+ return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
180
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
34
+}
181
[EXCP_NOCP] = "v7M NOCP UsageFault",
182
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
183
[EXCP_STKOF] = "v8M STKOF UsageFault",
184
+ [EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
185
};
186
187
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
188
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
189
return;
190
}
191
break;
192
+ case EXCP_LAZYFP:
193
+ /*
194
+ * We already pended the specific exception in the NVIC in the
195
+ * v7m_preserve_fp_state() helper function.
196
+ */
197
+ break;
198
default:
199
cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);
200
return; /* Never happens. Keep compiler happy. */
201
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
202
flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
203
}
204
205
+ if (arm_feature(env, ARM_FEATURE_M)) {
206
+ bool is_secure = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
207
+
35
+
208
+ if (env->v7m.fpccr[is_secure] & R_V7M_FPCCR_LSPACT_MASK) {
36
+static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
209
+ flags = FIELD_DP32(flags, TBFLAG_A32, LSPACT, 1);
37
+{
210
+ }
38
+ unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
211
+ }
39
+ return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
40
+}
212
+
41
+
213
*pflags = flags;
42
+static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
214
*cs_base = 0;
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
+}
79
+
80
static inline bool isar_feature_aa64_vh(const ARMISARegisters *id)
81
{
82
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)
84
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, BC) != 0;
215
}
85
}
216
diff --git a/target/arm/translate.c b/target/arm/translate.c
86
217
index XXXXXXX..XXXXXXX 100644
87
-static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
218
--- a/target/arm/translate.c
88
-{
219
+++ b/target/arm/translate.c
89
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
220
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
90
-}
221
if (arm_dc_feature(s, ARM_FEATURE_M)) {
91
-
222
/* Handle M-profile lazy FP state mechanics */
92
-static inline bool isar_feature_aa64_tgran4_2_lpa2(const ARMISARegisters *id)
223
93
-{
224
+ /* Trigger lazy-state preservation if necessary */
94
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4_2);
225
+ if (s->v7m_lspact) {
95
- return t >= 3 || (t == 0 && isar_feature_aa64_tgran4_lpa2(id));
226
+ /*
96
-}
227
+ * Lazy state saving affects external memory and also the NVIC,
97
-
228
+ * so we must mark it as an IO operation for icount.
98
-static inline bool isar_feature_aa64_tgran16_lpa2(const ARMISARegisters *id)
229
+ */
99
-{
230
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
100
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 2;
231
+ gen_io_start();
101
-}
232
+ }
102
-
233
+ gen_helper_v7m_preserve_fp_state(cpu_env);
103
-static inline bool isar_feature_aa64_tgran16_2_lpa2(const ARMISARegisters *id)
234
+ if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
104
-{
235
+ gen_io_end();
105
- unsigned t = FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16_2);
236
+ }
106
- return t >= 3 || (t == 0 && isar_feature_aa64_tgran16_lpa2(id));
237
+ /*
107
-}
238
+ * If the preserve_fp_state helper doesn't throw an exception
108
-
239
+ * then it will clear LSPACT; we don't need to repeat this for
109
-static inline bool isar_feature_aa64_tgran4(const ARMISARegisters *id)
240
+ * any further FP insns in this TB.
110
-{
241
+ */
111
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 0;
242
+ s->v7m_lspact = false;
112
-}
243
+ }
113
-
244
+
114
-static inline bool isar_feature_aa64_tgran16(const ARMISARegisters *id)
245
/* Update ownership of FP context: set FPCCR.S to match current state */
115
-{
246
if (s->v8m_fpccr_s_wrong) {
116
- return FIELD_EX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN16) >= 1;
247
TCGv_i32 tmp;
117
-}
248
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
118
-
249
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
119
-static inline bool isar_feature_aa64_tgran64(const ARMISARegisters *id)
250
dc->v7m_new_fp_ctxt_needed =
120
-{
251
FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
121
- return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN64) >= 0;
252
+ dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
122
-}
253
dc->cp_regs = cpu->cp_regs;
123
-
254
dc->features = env->features;
124
-static inline bool isar_feature_aa64_tgran4_2(const ARMISARegisters *id)
255
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
{
149
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
256
--
150
--
257
2.20.1
151
2.34.1
258
152
259
153
diff view generated by jsdifflib
1
The magic value pushed onto the callee stack as an integrity
1
Move the feature test functions that test ID_AA64ISAR* fields
2
check is different if floating point is present.
2
together.
3
3
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190416125744.27770-15-peter.maydell@linaro.org
7
Message-id: 20231024163510.2972081-5-peter.maydell@linaro.org
7
---
8
---
8
target/arm/helper.c | 22 +++++++++++++++++++---
9
target/arm/cpu-features.h | 70 +++++++++++++++++++--------------------
9
1 file changed, 19 insertions(+), 3 deletions(-)
10
1 file changed, 35 insertions(+), 35 deletions(-)
10
11
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
14
--- a/target/arm/cpu-features.h
14
+++ b/target/arm/helper.c
15
+++ b/target/arm/cpu-features.h
15
@@ -XXX,XX +XXX,XX @@ load_fail:
16
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rndr(const ARMISARegisters *id)
16
return false;
17
return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, RNDR) != 0;
17
}
18
}
18
19
19
+static uint32_t v7m_integrity_sig(CPUARMState *env, uint32_t lr)
20
+static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
20
+{
21
+{
21
+ /*
22
+ return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
22
+ * Return the integrity signature value for the callee-saves
23
+ * stack frame section. @lr is the exception return payload/LR value
24
+ * whose FType bit forms bit 0 of the signature if FP is present.
25
+ */
26
+ uint32_t sig = 0xfefa125a;
27
+
28
+ if (!arm_feature(env, ARM_FEATURE_VFP) || (lr & R_V7M_EXCRET_FTYPE_MASK)) {
29
+ sig |= 1;
30
+ }
31
+ return sig;
32
+}
23
+}
33
+
24
+
34
static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
25
+static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
35
bool ignore_faults)
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)
36
{
31
{
37
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
32
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, JSCVT) != 0;
38
bool stacked_ok;
33
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pauth_qarma3(const ARMISARegisters *id)
39
uint32_t limit;
34
return FIELD_EX64(id->id_aa64isar2, ID_AA64ISAR2, APA3) != 0;
40
bool want_psp;
35
}
41
+ uint32_t sig;
36
42
37
-static inline bool isar_feature_aa64_tlbirange(const ARMISARegisters *id)
43
if (dotailchain) {
38
-{
44
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
39
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) == 2;
45
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
40
-}
46
/* Write as much of the stack frame as we can. A write failure may
41
-
47
* cause us to pend a derived exception.
42
-static inline bool isar_feature_aa64_tlbios(const ARMISARegisters *id)
48
*/
43
-{
49
+ sig = v7m_integrity_sig(env, lr);
44
- return FIELD_EX64(id->id_aa64isar0, ID_AA64ISAR0, TLB) != 0;
50
stacked_ok =
45
-}
51
- v7m_stack_write(cpu, frameptr, 0xfefa125b, mmu_idx, ignore_faults) &&
46
-
52
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
47
static inline bool isar_feature_aa64_sb(const ARMISARegisters *id)
53
v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
48
{
54
ignore_faults) &&
49
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, SB) != 0;
55
v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
50
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_bf16(const ARMISARegisters *id)
56
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
51
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, BF16) != 0;
57
if (return_to_secure &&
52
}
58
((excret & R_V7M_EXCRET_ES_MASK) == 0 ||
53
59
(excret & R_V7M_EXCRET_DCRS_MASK) == 0)) {
54
+static inline bool isar_feature_aa64_rcpc_8_3(const ARMISARegisters *id)
60
- uint32_t expected_sig = 0xfefa125b;
55
+{
61
uint32_t actual_sig;
56
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) != 0;
62
57
+}
63
pop_ok = v7m_stack_read(cpu, &actual_sig, frameptr, mmu_idx);
58
+
64
59
+static inline bool isar_feature_aa64_rcpc_8_4(const ARMISARegisters *id)
65
- if (pop_ok && expected_sig != actual_sig) {
60
+{
66
+ if (pop_ok && v7m_integrity_sig(env, excret) != actual_sig) {
61
+ return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, LRCPC) >= 2;
67
/* Take a SecureFault on the current stack */
62
+}
68
env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK;
63
+
69
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
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
*/
70
--
121
--
71
2.20.1
122
2.34.1
72
123
73
124
diff view generated by jsdifflib
1
Implement the code which updates the FPCCR register on an
1
Move all the ID_AA64PFR* feature test functions together.
2
exception entry where we are going to use lazy FP stacking.
3
We have to defer to the NVIC to determine whether the
4
various exceptions are currently ready or not.
5
2
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190416125744.27770-12-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-6-peter.maydell@linaro.org
8
---
7
---
9
target/arm/cpu.h | 14 +++++++++
8
target/arm/cpu-features.h | 86 +++++++++++++++++++--------------------
10
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
9
1 file changed, 43 insertions(+), 43 deletions(-)
11
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
12
3 files changed, 114 insertions(+), 1 deletion(-)
13
10
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
15
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
13
--- a/target/arm/cpu-features.h
17
+++ b/target/arm/cpu.h
14
+++ b/target/arm/cpu-features.h
18
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_acknowledge_irq(void *opaque);
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_rme(const ARMISARegisters *id)
19
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
16
return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, RME) != 0;
20
*/
21
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
22
+/**
23
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
24
+ * @opaque: the NVIC
25
+ * @irq: the exception number to mark pending
26
+ * @secure: false for non-banked exceptions or for the nonsecure
27
+ * version of a banked exception, true for the secure version of a banked
28
+ * exception.
29
+ *
30
+ * Return whether an exception is "ready", i.e. whether the exception is
31
+ * enabled and is configured at a priority which would allow it to
32
+ * interrupt the current execution priority. This controls whether the
33
+ * RDY bit for it in the FPCCR is set.
34
+ */
35
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
36
/**
37
* armv7m_nvic_raw_execution_priority: return the raw execution priority
38
* @opaque: the NVIC
39
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/hw/intc/armv7m_nvic.c
42
+++ b/hw/intc/armv7m_nvic.c
43
@@ -XXX,XX +XXX,XX @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
44
return ret;
45
}
17
}
46
18
47
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
19
+static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
48
+{
20
+{
49
+ /*
21
+ return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
50
+ * Return whether an exception is "ready", i.e. it is enabled and is
51
+ * configured at a priority which would allow it to interrupt the
52
+ * current execution priority.
53
+ *
54
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
55
+ * for non-banked exceptions secure is always false; for banked exceptions
56
+ * it indicates which of the exceptions is required.
57
+ */
58
+ NVICState *s = (NVICState *)opaque;
59
+ bool banked = exc_is_banked(irq);
60
+ VecInfo *vec;
61
+ int running = nvic_exec_prio(s);
62
+
63
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
64
+ assert(!secure || banked);
65
+
66
+ /*
67
+ * HardFault is an odd special case: we always check against -1,
68
+ * even if we're secure and HardFault has priority -3; we never
69
+ * need to check for enabled state.
70
+ */
71
+ if (irq == ARMV7M_EXCP_HARD) {
72
+ return running > -1;
73
+ }
74
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
76
+
77
+ return vec->enabled &&
78
+ exc_group_prio(s, vec->prio, secure) < running;
79
+}
22
+}
80
+
23
+
81
/* callback when external interrupt line is changed */
24
+static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
82
static void set_irq_level(void *opaque, int n, int level)
83
{
84
diff --git a/target/arm/helper.c b/target/arm/helper.c
85
index XXXXXXX..XXXXXXX 100644
86
--- a/target/arm/helper.c
87
+++ b/target/arm/helper.c
88
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
89
env->thumb = addr & 1;
90
}
91
92
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
93
+ bool apply_splim)
94
+{
25
+{
95
+ /*
26
+ int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
96
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
27
+ if (key >= 2) {
97
+ * that we will need later in order to do lazy FP reg stacking.
28
+ return true; /* FEAT_CSV2_2 */
98
+ */
99
+ bool is_secure = env->v7m.secure;
100
+ void *nvic = env->nvic;
101
+ /*
102
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
103
+ * are banked and we want to update the bit in the bank for the
104
+ * current security state; and in one case we want to specifically
105
+ * update the NS banked version of a bit even if we are secure.
106
+ */
107
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
108
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
109
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
110
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
111
+
112
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
113
+
114
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
115
+ bool splimviol;
116
+ uint32_t splim = v7m_sp_limit(env);
117
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
118
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
119
+
120
+ splimviol = !ign && frameptr < splim;
121
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
122
+ }
29
+ }
123
+
30
+ if (key == 1) {
124
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
31
+ key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
125
+
32
+ return key >= 2; /* FEAT_CSV2_1p2 */
126
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
127
+
128
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
129
+
130
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
131
+ !arm_v7m_is_handler_mode(env));
132
+
133
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
134
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
135
+
136
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
137
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
138
+
139
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
140
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
141
+
142
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
143
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
144
+
145
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
146
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
147
+
148
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
149
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
150
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
151
+
152
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
153
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
154
+ }
33
+ }
34
+ return false;
155
+}
35
+}
156
+
36
+
157
static bool v7m_push_stack(ARMCPU *cpu)
37
+static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
38
+{
39
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
40
+}
41
+
42
+static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
43
+{
44
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
45
+}
46
+
47
+static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
48
+{
49
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
50
+}
51
+
52
+static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
53
+{
54
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
55
+}
56
+
57
+static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
58
+{
59
+ return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
60
+}
61
+
62
static inline bool isar_feature_aa64_tgran4_lpa2(const ARMISARegisters *id)
158
{
63
{
159
/* Do the "set up stack frame" part of exception entry,
64
return FIELD_SEX64(id->id_aa64mmfr0, ID_AA64MMFR0, TGRAN4) >= 1;
160
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_e0pd(const ARMISARegisters *id)
161
}
66
return FIELD_EX64(id->id_aa64mmfr2, ID_AA64MMFR2, E0PD) != 0;
162
} else {
67
}
163
/* Lazy stacking enabled, save necessary info to stack later */
68
164
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
69
-static inline bool isar_feature_aa64_bti(const ARMISARegisters *id)
165
+ v7m_update_fpccr(env, frameptr + 0x20, true);
70
-{
166
}
71
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, BT) != 0;
167
}
72
-}
168
}
73
-
74
-static inline bool isar_feature_aa64_mte_insn_reg(const ARMISARegisters *id)
75
-{
76
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) != 0;
77
-}
78
-
79
-static inline bool isar_feature_aa64_mte(const ARMISARegisters *id)
80
-{
81
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, MTE) >= 2;
82
-}
83
-
84
-static inline bool isar_feature_aa64_sme(const ARMISARegisters *id)
85
-{
86
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SME) != 0;
87
-}
88
-
89
static inline bool isar_feature_aa64_pmuv3p1(const ARMISARegisters *id)
90
{
91
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) >= 4 &&
92
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_pmuv3p5(const ARMISARegisters *id)
93
FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, PMUVER) != 0xf;
94
}
95
96
-static inline bool isar_feature_aa64_dit(const ARMISARegisters *id)
97
-{
98
- return FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, DIT) != 0;
99
-}
100
-
101
-static inline bool isar_feature_aa64_scxtnum(const ARMISARegisters *id)
102
-{
103
- int key = FIELD_EX64(id->id_aa64pfr0, ID_AA64PFR0, CSV2);
104
- if (key >= 2) {
105
- return true; /* FEAT_CSV2_2 */
106
- }
107
- if (key == 1) {
108
- key = FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, CSV2_FRAC);
109
- return key >= 2; /* FEAT_CSV2_1p2 */
110
- }
111
- return false;
112
-}
113
-
114
-static inline bool isar_feature_aa64_ssbs(const ARMISARegisters *id)
115
-{
116
- return FIELD_EX64(id->id_aa64pfr1, ID_AA64PFR1, SSBS) != 0;
117
-}
118
-
119
static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
120
{
121
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
169
--
122
--
170
2.20.1
123
2.34.1
171
124
172
125
diff view generated by jsdifflib
1
Implement the VLSTM instruction for v7M for the FPU present case.
1
Move all the ID_AA64DFR* feature test functions together.
2
2
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
3
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190416125744.27770-25-peter.maydell@linaro.org
6
Message-id: 20231024163510.2972081-7-peter.maydell@linaro.org
6
---
7
---
7
target/arm/cpu.h | 2 +
8
target/arm/cpu-features.h | 10 +++++-----
8
target/arm/helper.h | 2 +
9
1 file changed, 5 insertions(+), 5 deletions(-)
9
target/arm/helper.c | 84 ++++++++++++++++++++++++++++++++++++++++++
10
target/arm/translate.c | 15 +++++++-
11
4 files changed, 102 insertions(+), 1 deletion(-)
12
10
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
11
diff --git a/target/arm/cpu-features.h b/target/arm/cpu-features.h
14
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
13
--- a/target/arm/cpu-features.h
16
+++ b/target/arm/cpu.h
14
+++ b/target/arm/cpu-features.h
17
@@ -XXX,XX +XXX,XX @@
15
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_debugv8p2(const ARMISARegisters *id)
18
#define EXCP_INVSTATE 18 /* v7M INVSTATE UsageFault */
16
return FIELD_EX64(id->id_aa64dfr0, ID_AA64DFR0, DEBUGVER) >= 8;
19
#define EXCP_STKOF 19 /* v8M STKOF UsageFault */
20
#define EXCP_LAZYFP 20 /* v7M fault during lazy FP stacking */
21
+#define EXCP_LSERR 21 /* v8M LSERR SecureFault */
22
+#define EXCP_UNALIGNED 22 /* v7M UNALIGNED UsageFault */
23
/* NB: add new EXCP_ defines to the array in arm_log_exception() too */
24
25
#define ARMV7M_EXCP_RESET 1
26
diff --git a/target/arm/helper.h b/target/arm/helper.h
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper.h
29
+++ b/target/arm/helper.h
30
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
31
32
DEF_HELPER_1(v7m_preserve_fp_state, void, env)
33
34
+DEF_HELPER_2(v7m_vlstm, void, env, i32)
35
+
36
DEF_HELPER_2(v8m_stackcheck, void, env, i32)
37
38
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
39
diff --git a/target/arm/helper.c b/target/arm/helper.c
40
index XXXXXXX..XXXXXXX 100644
41
--- a/target/arm/helper.c
42
+++ b/target/arm/helper.c
43
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_preserve_fp_state)(CPUARMState *env)
44
g_assert_not_reached();
45
}
17
}
46
18
47
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
19
+static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
48
+{
20
+{
49
+ /* translate.c should never generate calls here in user-only mode */
21
+ return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
50
+ g_assert_not_reached();
51
+}
22
+}
52
+
23
+
53
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
24
static inline bool isar_feature_aa64_sve2(const ARMISARegisters *id)
54
{
25
{
55
/* The TT instructions can be used by unprivileged code, but in
26
return FIELD_EX64(id->id_aa64zfr0, ID_AA64ZFR0, SVEVER) != 0;
56
@@ -XXX,XX +XXX,XX @@ static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
27
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_sme_fa64(const ARMISARegisters *id)
57
}
28
return FIELD_EX64(id->id_aa64smfr0, ID_AA64SMFR0, FA64);
58
}
29
}
59
30
60
+void HELPER(v7m_vlstm)(CPUARMState *env, uint32_t fptr)
31
-static inline bool isar_feature_aa64_doublelock(const ARMISARegisters *id)
61
+{
32
-{
62
+ /* fptr is the value of Rn, the frame pointer we store the FP regs to */
33
- return FIELD_SEX64(id->id_aa64dfr0, ID_AA64DFR0, DOUBLELOCK) >= 0;
63
+ bool s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
34
-}
64
+ bool lspact = env->v7m.fpccr[s] & R_V7M_FPCCR_LSPACT_MASK;
35
-
65
+
36
/*
66
+ assert(env->v7m.secure);
37
* Feature tests for "does this exist in either 32-bit or 64-bit?"
67
+
38
*/
68
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
69
+ return;
70
+ }
71
+
72
+ /* Check access to the coprocessor is permitted */
73
+ if (!v7m_cpacr_pass(env, true, arm_current_el(env) != 0)) {
74
+ raise_exception_ra(env, EXCP_NOCP, 0, 1, GETPC());
75
+ }
76
+
77
+ if (lspact) {
78
+ /* LSPACT should not be active when there is active FP state */
79
+ raise_exception_ra(env, EXCP_LSERR, 0, 1, GETPC());
80
+ }
81
+
82
+ if (fptr & 7) {
83
+ raise_exception_ra(env, EXCP_UNALIGNED, 0, 1, GETPC());
84
+ }
85
+
86
+ /*
87
+ * Note that we do not use v7m_stack_write() here, because the
88
+ * accesses should not set the FSR bits for stacking errors if they
89
+ * fail. (In pseudocode terms, they are AccType_NORMAL, not AccType_STACK
90
+ * or AccType_LAZYFP). Faults in cpu_stl_data() will throw exceptions
91
+ * and longjmp out.
92
+ */
93
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
94
+ bool ts = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK;
95
+ int i;
96
+
97
+ for (i = 0; i < (ts ? 32 : 16); i += 2) {
98
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
99
+ uint32_t faddr = fptr + 4 * i;
100
+ uint32_t slo = extract64(dn, 0, 32);
101
+ uint32_t shi = extract64(dn, 32, 32);
102
+
103
+ if (i >= 16) {
104
+ faddr += 8; /* skip the slot for the FPSCR */
105
+ }
106
+ cpu_stl_data(env, faddr, slo);
107
+ cpu_stl_data(env, faddr + 4, shi);
108
+ }
109
+ cpu_stl_data(env, fptr + 0x40, vfp_get_fpscr(env));
110
+
111
+ /*
112
+ * If TS is 0 then s0 to s15 and FPSCR are UNKNOWN; we choose to
113
+ * leave them unchanged, matching our choice in v7m_preserve_fp_state.
114
+ */
115
+ if (ts) {
116
+ for (i = 0; i < 32; i += 2) {
117
+ *aa32_vfp_dreg(env, i / 2) = 0;
118
+ }
119
+ vfp_set_fpscr(env, 0);
120
+ }
121
+ } else {
122
+ v7m_update_fpccr(env, fptr, false);
123
+ }
124
+
125
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
126
+}
127
+
128
static bool v7m_push_stack(ARMCPU *cpu)
129
{
130
/* Do the "set up stack frame" part of exception entry,
131
@@ -XXX,XX +XXX,XX @@ static void arm_log_exception(int idx)
132
[EXCP_INVSTATE] = "v7M INVSTATE UsageFault",
133
[EXCP_STKOF] = "v8M STKOF UsageFault",
134
[EXCP_LAZYFP] = "v7M exception during lazy FP stacking",
135
+ [EXCP_LSERR] = "v8M LSERR UsageFault",
136
+ [EXCP_UNALIGNED] = "v7M UNALIGNED UsageFault",
137
};
138
139
if (idx >= 0 && idx < ARRAY_SIZE(excnames)) {
140
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
141
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
142
env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_STKOF_MASK;
143
break;
144
+ case EXCP_LSERR:
145
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
146
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
147
+ break;
148
+ case EXCP_UNALIGNED:
149
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure);
150
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_UNALIGNED_MASK;
151
+ break;
152
case EXCP_SWI:
153
/* The PC already points to the next instruction. */
154
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC, env->v7m.secure);
155
diff --git a/target/arm/translate.c b/target/arm/translate.c
156
index XXXXXXX..XXXXXXX 100644
157
--- a/target/arm/translate.c
158
+++ b/target/arm/translate.c
159
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
160
if (!s->v8m_secure || (insn & 0x0040f0ff)) {
161
goto illegal_op;
162
}
163
- /* Just NOP since FP support is not implemented */
164
+
165
+ if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
166
+ TCGv_i32 fptr = load_reg(s, rn);
167
+
168
+ if (extract32(insn, 20, 1)) {
169
+ /* VLLDM */
170
+ } else {
171
+ gen_helper_v7m_vlstm(cpu_env, fptr);
172
+ }
173
+ tcg_temp_free_i32(fptr);
174
+
175
+ /* End the TB, because we have updated FP control bits */
176
+ s->base.is_jmp = DISAS_UPDATE;
177
+ }
178
break;
179
}
180
if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
181
--
39
--
182
2.20.1
40
2.34.1
183
41
184
42
diff view generated by jsdifflib
1
Move the NS TBFLAG down from bit 19 to bit 6, which has not
1
In commit 442c9d682c94fc2 when we converted the ERET, ERETAA, ERETAB
2
been used since commit c1e3781090b9d36c60 in 2015, when we
2
instructions to decodetree, the conversion accidentally lost the
3
started passing the entire MMU index in the TB flags rather
3
correct setting of the syndrome register when taking a trap because
4
than just a 'privilege level' bit.
4
of the FEAT_FGT HFGITR_EL1.ERET bit. Instead of reporting a correct
5
full syndrome value with the EC and IL bits, we only reported the low
6
two bits of the syndrome, because the call to syn_erettrap() got
7
dropped.
5
8
6
This rearrangement is not strictly necessary, but means that
9
Fix the syndrome values for these traps by reinstating the
7
we can put M-profile-only bits next to each other rather
10
syn_erettrap() calls.
8
than scattered across the flag word.
9
11
12
Fixes: 442c9d682c94fc2 ("target/arm: Convert ERET, ERETAA, ERETAB to decodetree")
13
Cc: qemu-stable@nongnu.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-17-peter.maydell@linaro.org
16
Message-id: 20231024172438.2990945-1-peter.maydell@linaro.org
13
---
17
---
14
target/arm/cpu.h | 11 ++++++-----
18
target/arm/tcg/translate-a64.c | 4 ++--
15
1 file changed, 6 insertions(+), 5 deletions(-)
19
1 file changed, 2 insertions(+), 2 deletions(-)
16
20
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/target/arm/tcg/translate-a64.c b/target/arm/tcg/translate-a64.c
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
23
--- a/target/arm/tcg/translate-a64.c
20
+++ b/target/arm/cpu.h
24
+++ b/target/arm/tcg/translate-a64.c
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
25
@@ -XXX,XX +XXX,XX @@ static bool trans_ERET(DisasContext *s, arg_ERET *a)
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
26
return false;
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
27
}
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
28
if (s->fgt_eret) {
25
+/*
29
- gen_exception_insn_el(s, 0, EXCP_UDEF, 0, 2);
26
+ * Indicates whether cp register reads and writes by guest code should access
30
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(0), 2);
27
+ * the secure or nonsecure bank of banked registers; note that this is not
31
return true;
28
+ * the same thing as the current security state of the processor!
32
}
29
+ */
33
dst = tcg_temp_new_i64();
30
+FIELD(TBFLAG_A32, NS, 6, 1)
34
@@ -XXX,XX +XXX,XX @@ static bool trans_ERETA(DisasContext *s, arg_reta *a)
31
FIELD(TBFLAG_A32, VFPEN, 7, 1)
35
}
32
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
36
/* The FGT trap takes precedence over an auth trap. */
33
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
37
if (s->fgt_eret) {
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
38
- gen_exception_insn_el(s, 0, EXCP_UDEF, a->m ? 3 : 2, 2);
35
* checks on the other bits at runtime
39
+ gen_exception_insn_el(s, 0, EXCP_UDEF, syn_erettrap(a->m ? 3 : 2), 2);
36
*/
40
return true;
37
FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
41
}
38
-/* Indicates whether cp register reads and writes by guest code should access
42
dst = tcg_temp_new_i64();
39
- * the secure or nonsecure bank of banked registers; note that this is not
40
- * the same thing as the current security state of the processor!
41
- */
42
-FIELD(TBFLAG_A32, NS, 19, 1)
43
/* For M profile only, Handler (ie not Thread) mode */
44
FIELD(TBFLAG_A32, HANDLER, 21, 1)
45
/* For M profile only, whether we should generate stack-limit checks */
46
--
43
--
47
2.20.1
44
2.34.1
48
49
diff view generated by jsdifflib
1
The TailChain() pseudocode specifies that a tail chaining
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
exception should sanitize the excReturn all-ones bits and
3
(if there is no FPU) the excReturn FType bits; we weren't
4
doing this.
5
2
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-14-peter.maydell@linaro.org
9
---
10
---
10
target/arm/helper.c | 8 ++++++++
11
include/hw/arm/allwinner-a10.h | 1 -
11
1 file changed, 8 insertions(+)
12
hw/arm/cubieboard.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/arm/allwinner-a10.h b/include/hw/arm/allwinner-a10.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/include/hw/arm/allwinner-a10.h
16
+++ b/target/arm/helper.c
18
+++ b/include/hw/arm/allwinner-a10.h
17
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
@@ -XXX,XX +XXX,XX @@
18
qemu_log_mask(CPU_LOG_INT, "...taking pending %s exception %d\n",
20
#ifndef HW_ARM_ALLWINNER_A10_H
19
targets_secure ? "secure" : "nonsecure", exc);
21
#define HW_ARM_ALLWINNER_A10_H
20
22
21
+ if (dotailchain) {
23
-#include "hw/arm/boot.h"
22
+ /* Sanitize LR FType and PREFIX bits */
24
#include "hw/timer/allwinner-a10-pit.h"
23
+ if (!arm_feature(env, ARM_FEATURE_VFP)) {
25
#include "hw/intc/allwinner-a10-pic.h"
24
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
26
#include "hw/net/allwinner_emac.h"
25
+ }
27
diff --git a/hw/arm/cubieboard.c b/hw/arm/cubieboard.c
26
+ lr = deposit32(lr, 24, 8, 0xff);
28
index XXXXXXX..XXXXXXX 100644
27
+ }
29
--- a/hw/arm/cubieboard.c
28
+
30
+++ b/hw/arm/cubieboard.c
29
if (arm_feature(env, ARM_FEATURE_V8)) {
31
@@ -XXX,XX +XXX,XX @@
30
if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
32
#include "hw/boards.h"
31
(lr & R_V7M_EXCRET_S_MASK)) {
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 = {
32
--
39
--
33
2.20.1
40
2.34.1
34
41
35
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Suggested-by: Markus Armbruster <armbru@redhat.com>
3
"hw/arm/boot.h" is only required on the source file.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-3-philmd@redhat.com
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@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
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
hw/arm/nseries.c | 3 ++-
11
include/hw/arm/allwinner-h3.h | 1 -
10
1 file changed, 2 insertions(+), 1 deletion(-)
12
hw/arm/orangepi.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
11
14
12
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
15
diff --git a/include/hw/arm/allwinner-h3.h b/include/hw/arm/allwinner-h3.h
13
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/arm/nseries.c
17
--- a/include/hw/arm/allwinner-h3.h
15
+++ b/hw/arm/nseries.c
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
16
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
17
#include "hw/boards.h"
32
#include "hw/boards.h"
18
#include "hw/i2c/i2c.h"
33
#include "hw/qdev-properties.h"
19
#include "hw/devices.h"
34
#include "hw/arm/allwinner-h3.h"
20
+#include "hw/misc/tmp105.h"
35
+#include "hw/arm/boot.h"
21
#include "hw/block/flash.h"
36
22
#include "hw/hw.h"
37
static struct arm_boot_info orangepi_binfo;
23
#include "hw/bt.h"
24
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
25
qemu_register_powerdown_notifier(&n8x0_system_powerdown_notifier);
26
27
/* Attach a TMP105 PM chip (A0 wired to ground) */
28
- dev = i2c_create_slave(i2c, "tmp105", N8X0_TMP105_ADDR);
29
+ dev = i2c_create_slave(i2c, TYPE_TMP105, N8X0_TMP105_ADDR);
30
qdev_connect_gpio_out(dev, 0, tmp_irq);
31
}
32
38
33
--
39
--
34
2.20.1
40
2.34.1
35
41
36
42
diff view generated by jsdifflib
1
For v8M floating point support, transitions from Secure
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
to Non-secure state via BLNS and BLXNS must clear the
3
CONTROL.SFPA bit. (This corresponds to the pseudocode
4
BranchToNS() function.)
5
2
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-13-peter.maydell@linaro.org
9
---
10
---
10
target/arm/helper.c | 4 ++++
11
include/hw/arm/allwinner-r40.h | 1 -
11
1 file changed, 4 insertions(+)
12
hw/arm/bananapi_m2u.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/arm/allwinner-r40.h b/include/hw/arm/allwinner-r40.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/include/hw/arm/allwinner-r40.h
16
+++ b/target/arm/helper.c
18
+++ b/include/hw/arm/allwinner-r40.h
17
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_bxns)(CPUARMState *env, uint32_t dest)
19
@@ -XXX,XX +XXX,XX @@
18
/* translate.c should have made BXNS UNDEF unless we're secure */
20
#define HW_ARM_ALLWINNER_R40_H
19
assert(env->v7m.secure);
21
20
22
#include "qom/object.h"
21
+ if (!(dest & 1)) {
23
-#include "hw/arm/boot.h"
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
24
#include "hw/timer/allwinner-a10-pit.h"
23
+ }
25
#include "hw/intc/arm_gic.h"
24
switch_v7m_security_state(env, dest & 1);
26
#include "hw/sd/allwinner-sdhost.h"
25
env->thumb = 1;
27
diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c
26
env->regs[15] = dest & ~1;
28
index XXXXXXX..XXXXXXX 100644
27
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
29
--- a/hw/arm/bananapi_m2u.c
28
*/
30
+++ b/hw/arm/bananapi_m2u.c
29
write_v7m_exception(env, 1);
31
@@ -XXX,XX +XXX,XX @@
30
}
32
#include "hw/i2c/i2c.h"
31
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
33
#include "hw/qdev-properties.h"
32
switch_v7m_security_state(env, 0);
34
#include "hw/arm/allwinner-r40.h"
33
env->thumb = 1;
35
+#include "hw/arm/boot.h"
34
env->regs[15] = dest;
36
37
static struct arm_boot_info bpim2u_binfo;
38
35
--
39
--
36
2.20.1
40
2.34.1
37
41
38
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
"hw/arm/boot.h" is only required on the source file.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-5-philmd@redhat.com
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/devices.h | 6 ------
11
include/hw/arm/fsl-imx25.h | 1 -
9
include/hw/display/tc6393xb.h | 24 ++++++++++++++++++++++++
12
hw/arm/imx25_pdk.c | 1 +
10
hw/arm/tosa.c | 2 +-
13
2 files changed, 1 insertion(+), 1 deletion(-)
11
hw/display/tc6393xb.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 27 insertions(+), 8 deletions(-)
14
create mode 100644 include/hw/display/tc6393xb.h
15
14
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/include/hw/arm/fsl-imx25.h b/include/hw/arm/fsl-imx25.h
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
17
--- a/include/hw/arm/fsl-imx25.h
19
+++ b/include/hw/devices.h
18
+++ b/include/hw/arm/fsl-imx25.h
20
@@ -XXX,XX +XXX,XX @@ void *tahvo_init(qemu_irq irq, int betty);
21
22
void retu_key_event(void *retu, int state);
23
24
-/* tc6393xb.c */
25
-typedef struct TC6393xbState TC6393xbState;
26
-TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
27
- uint32_t base, qemu_irq irq);
28
-qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
-
30
#endif
31
diff --git a/include/hw/display/tc6393xb.h b/include/hw/display/tc6393xb.h
32
new file mode 100644
33
index XXXXXXX..XXXXXXX
34
--- /dev/null
35
+++ b/include/hw/display/tc6393xb.h
36
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
37
+/*
20
#ifndef FSL_IMX25_H
38
+ * Toshiba TC6393XB I/O Controller.
21
#define FSL_IMX25_H
39
+ * Found in Sharp Zaurus SL-6000 (tosa) or some
22
40
+ * Toshiba e-Series PDAs.
23
-#include "hw/arm/boot.h"
41
+ *
24
#include "hw/intc/imx_avic.h"
42
+ * Copyright (c) 2007 Hervé Poussineau
25
#include "hw/misc/imx25_ccm.h"
43
+ *
26
#include "hw/char/imx_serial.h"
44
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
27
diff --git a/hw/arm/imx25_pdk.c b/hw/arm/imx25_pdk.c
45
+ * See the COPYING file in the top-level directory.
46
+ */
47
+
48
+#ifndef HW_DISPLAY_TC6393XB_H
49
+#define HW_DISPLAY_TC6393XB_H
50
+
51
+#include "exec/memory.h"
52
+#include "hw/irq.h"
53
+
54
+typedef struct TC6393xbState TC6393xbState;
55
+
56
+TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
57
+ uint32_t base, qemu_irq irq);
58
+qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
59
+
60
+#endif
61
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
62
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
63
--- a/hw/arm/tosa.c
29
--- a/hw/arm/imx25_pdk.c
64
+++ b/hw/arm/tosa.c
30
+++ b/hw/arm/imx25_pdk.c
65
@@ -XXX,XX +XXX,XX @@
66
#include "hw/hw.h"
67
#include "hw/arm/pxa.h"
68
#include "hw/arm/arm.h"
69
-#include "hw/devices.h"
70
#include "hw/arm/sharpsl.h"
71
#include "hw/pcmcia.h"
72
#include "hw/boards.h"
73
+#include "hw/display/tc6393xb.h"
74
#include "hw/i2c/i2c.h"
75
#include "hw/ssi/ssi.h"
76
#include "hw/sysbus.h"
77
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/tc6393xb.c
80
+++ b/hw/display/tc6393xb.c
81
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
82
#include "qapi/error.h"
32
#include "qapi/error.h"
83
#include "qemu/host-utils.h"
33
#include "hw/qdev-properties.h"
84
#include "hw/hw.h"
34
#include "hw/arm/fsl-imx25.h"
85
-#include "hw/devices.h"
35
+#include "hw/arm/boot.h"
86
+#include "hw/display/tc6393xb.h"
36
#include "hw/boards.h"
87
#include "hw/block/flash.h"
37
#include "qemu/error-report.h"
88
#include "ui/console.h"
38
#include "sysemu/qtest.h"
89
#include "ui/pixel_ops.h"
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ F: hw/misc/mst_fpga.c
95
F: hw/misc/max111x.c
96
F: include/hw/arm/pxa.h
97
F: include/hw/arm/sharpsl.h
98
+F: include/hw/display/tc6393xb.h
99
100
SABRELITE / i.MX6
101
M: Peter Maydell <peter.maydell@linaro.org>
102
--
39
--
103
2.20.1
40
2.34.1
104
41
105
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
"hw/arm/boot.h" is only required on the source file.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-10-philmd@redhat.com
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
include/hw/devices.h | 3 ---
11
include/hw/arm/fsl-imx31.h | 1 -
9
include/hw/net/lan9118.h | 19 +++++++++++++++++++
12
hw/arm/kzm.c | 1 +
10
hw/arm/kzm.c | 2 +-
13
2 files changed, 1 insertion(+), 1 deletion(-)
11
hw/arm/mps2.c | 2 +-
12
hw/arm/realview.c | 1 +
13
hw/arm/vexpress.c | 2 +-
14
hw/net/lan9118.c | 2 +-
15
7 files changed, 24 insertions(+), 7 deletions(-)
16
create mode 100644 include/hw/net/lan9118.h
17
14
18
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/include/hw/arm/fsl-imx31.h b/include/hw/arm/fsl-imx31.h
19
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
20
--- a/include/hw/devices.h
17
--- a/include/hw/arm/fsl-imx31.h
21
+++ b/include/hw/devices.h
18
+++ b/include/hw/arm/fsl-imx31.h
22
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
23
/* smc91c111.c */
20
#ifndef FSL_IMX31_H
24
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
21
#define FSL_IMX31_H
25
22
26
-/* lan9118.c */
23
-#include "hw/arm/boot.h"
27
-void lan9118_init(NICInfo *, uint32_t, qemu_irq);
24
#include "hw/intc/imx_avic.h"
28
-
25
#include "hw/misc/imx31_ccm.h"
29
#endif
26
#include "hw/char/imx_serial.h"
30
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
31
new file mode 100644
32
index XXXXXXX..XXXXXXX
33
--- /dev/null
34
+++ b/include/hw/net/lan9118.h
35
@@ -XXX,XX +XXX,XX @@
36
+/*
37
+ * SMSC LAN9118 Ethernet interface emulation
38
+ *
39
+ * Copyright (c) 2009 CodeSourcery, LLC.
40
+ * Written by Paul Brook
41
+ *
42
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
43
+ * See the COPYING file in the top-level directory.
44
+ */
45
+
46
+#ifndef HW_NET_LAN9118_H
47
+#define HW_NET_LAN9118_H
48
+
49
+#include "hw/irq.h"
50
+#include "net/net.h"
51
+
52
+void lan9118_init(NICInfo *, uint32_t, qemu_irq);
53
+
54
+#endif
55
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
27
diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c
56
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
57
--- a/hw/arm/kzm.c
29
--- a/hw/arm/kzm.c
58
+++ b/hw/arm/kzm.c
30
+++ b/hw/arm/kzm.c
59
@@ -XXX,XX +XXX,XX @@
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"
60
#include "qemu/error-report.h"
37
#include "qemu/error-report.h"
61
#include "exec/address-spaces.h"
38
#include "exec/address-spaces.h"
62
#include "net/net.h"
63
-#include "hw/devices.h"
64
+#include "hw/net/lan9118.h"
65
#include "hw/char/serial.h"
66
#include "sysemu/qtest.h"
67
68
diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c
69
index XXXXXXX..XXXXXXX 100644
70
--- a/hw/arm/mps2.c
71
+++ b/hw/arm/mps2.c
72
@@ -XXX,XX +XXX,XX @@
73
#include "hw/timer/cmsdk-apb-timer.h"
74
#include "hw/timer/cmsdk-apb-dualtimer.h"
75
#include "hw/misc/mps2-scc.h"
76
-#include "hw/devices.h"
77
+#include "hw/net/lan9118.h"
78
#include "net/net.h"
79
80
typedef enum MPS2FPGAType {
81
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
82
index XXXXXXX..XXXXXXX 100644
83
--- a/hw/arm/realview.c
84
+++ b/hw/arm/realview.c
85
@@ -XXX,XX +XXX,XX @@
86
#include "hw/arm/arm.h"
87
#include "hw/arm/primecell.h"
88
#include "hw/devices.h"
89
+#include "hw/net/lan9118.h"
90
#include "hw/pci/pci.h"
91
#include "net/net.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/vexpress.c
96
+++ b/hw/arm/vexpress.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/sysbus.h"
99
#include "hw/arm/arm.h"
100
#include "hw/arm/primecell.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/lan9118.h"
103
#include "hw/i2c/i2c.h"
104
#include "net/net.h"
105
#include "sysemu/sysemu.h"
106
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/net/lan9118.c
109
+++ b/hw/net/lan9118.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "net/net.h"
113
#include "net/eth.h"
114
-#include "hw/devices.h"
115
+#include "hw/net/lan9118.h"
116
#include "sysemu/sysemu.h"
117
#include "hw/ptimer.h"
118
#include "qemu/log.h"
119
--
39
--
120
2.20.1
40
2.34.1
121
41
122
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
This commit finally deletes "hw/devices.h".
3
"hw/arm/boot.h" is only required on the source file.
4
4
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190412165416.7977-13-philmd@redhat.com
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20231025065316.56817-7-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
---
10
include/hw/devices.h | 11 -----------
11
include/hw/arm/fsl-imx6.h | 1 -
11
include/hw/net/smc91c111.h | 19 +++++++++++++++++++
12
hw/arm/sabrelite.c | 1 +
12
hw/arm/gumstix.c | 2 +-
13
2 files changed, 1 insertion(+), 1 deletion(-)
13
hw/arm/integratorcp.c | 2 +-
14
hw/arm/mainstone.c | 2 +-
15
hw/arm/realview.c | 2 +-
16
hw/arm/versatilepb.c | 2 +-
17
hw/net/smc91c111.c | 2 +-
18
8 files changed, 25 insertions(+), 17 deletions(-)
19
delete mode 100644 include/hw/devices.h
20
create mode 100644 include/hw/net/smc91c111.h
21
14
22
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/include/hw/arm/fsl-imx6.h b/include/hw/arm/fsl-imx6.h
23
deleted file mode 100644
16
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX
17
--- a/include/hw/arm/fsl-imx6.h
25
--- a/include/hw/devices.h
18
+++ b/include/hw/arm/fsl-imx6.h
26
+++ /dev/null
27
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
28
-#ifndef QEMU_DEVICES_H
20
#ifndef FSL_IMX6_H
29
-#define QEMU_DEVICES_H
21
#define FSL_IMX6_H
30
-
22
31
-/* Devices that have nowhere better to go. */
23
-#include "hw/arm/boot.h"
32
-
24
#include "hw/cpu/a9mpcore.h"
33
-#include "hw/hw.h"
25
#include "hw/misc/imx6_ccm.h"
34
-
26
#include "hw/misc/imx6_src.h"
35
-/* smc91c111.c */
27
diff --git a/hw/arm/sabrelite.c b/hw/arm/sabrelite.c
36
-void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
37
-
38
-#endif
39
diff --git a/include/hw/net/smc91c111.h b/include/hw/net/smc91c111.h
40
new file mode 100644
41
index XXXXXXX..XXXXXXX
42
--- /dev/null
43
+++ b/include/hw/net/smc91c111.h
44
@@ -XXX,XX +XXX,XX @@
45
+/*
46
+ * SMSC 91C111 Ethernet interface emulation
47
+ *
48
+ * Copyright (c) 2005 CodeSourcery, LLC.
49
+ * Written by Paul Brook
50
+ *
51
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
52
+ * See the COPYING file in the top-level directory.
53
+ */
54
+
55
+#ifndef HW_NET_SMC91C111_H
56
+#define HW_NET_SMC91C111_H
57
+
58
+#include "hw/irq.h"
59
+#include "net/net.h"
60
+
61
+void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
62
+
63
+#endif
64
diff --git a/hw/arm/gumstix.c b/hw/arm/gumstix.c
65
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
66
--- a/hw/arm/gumstix.c
29
--- a/hw/arm/sabrelite.c
67
+++ b/hw/arm/gumstix.c
30
+++ b/hw/arm/sabrelite.c
68
@@ -XXX,XX +XXX,XX @@
69
#include "hw/arm/pxa.h"
70
#include "net/net.h"
71
#include "hw/block/flash.h"
72
-#include "hw/devices.h"
73
+#include "hw/net/smc91c111.h"
74
#include "hw/boards.h"
75
#include "exec/address-spaces.h"
76
#include "sysemu/qtest.h"
77
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/arm/integratorcp.c
80
+++ b/hw/arm/integratorcp.c
81
@@ -XXX,XX +XXX,XX @@
82
#include "qemu-common.h"
83
#include "cpu.h"
84
#include "hw/sysbus.h"
85
-#include "hw/devices.h"
86
#include "hw/boards.h"
87
#include "hw/arm/arm.h"
88
#include "hw/misc/arm_integrator_debug.h"
89
+#include "hw/net/smc91c111.h"
90
#include "net/net.h"
91
#include "exec/address-spaces.h"
92
#include "sysemu/sysemu.h"
93
diff --git a/hw/arm/mainstone.c b/hw/arm/mainstone.c
94
index XXXXXXX..XXXXXXX 100644
95
--- a/hw/arm/mainstone.c
96
+++ b/hw/arm/mainstone.c
97
@@ -XXX,XX +XXX,XX @@
98
#include "hw/arm/pxa.h"
99
#include "hw/arm/arm.h"
100
#include "net/net.h"
101
-#include "hw/devices.h"
102
+#include "hw/net/smc91c111.h"
103
#include "hw/boards.h"
104
#include "hw/block/flash.h"
105
#include "hw/sysbus.h"
106
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
107
index XXXXXXX..XXXXXXX 100644
108
--- a/hw/arm/realview.c
109
+++ b/hw/arm/realview.c
110
@@ -XXX,XX +XXX,XX @@
111
#include "hw/sysbus.h"
112
#include "hw/arm/arm.h"
113
#include "hw/arm/primecell.h"
114
-#include "hw/devices.h"
115
#include "hw/net/lan9118.h"
116
+#include "hw/net/smc91c111.h"
117
#include "hw/pci/pci.h"
118
#include "net/net.h"
119
#include "sysemu/sysemu.h"
120
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
121
index XXXXXXX..XXXXXXX 100644
122
--- a/hw/arm/versatilepb.c
123
+++ b/hw/arm/versatilepb.c
124
@@ -XXX,XX +XXX,XX @@
125
#include "cpu.h"
126
#include "hw/sysbus.h"
127
#include "hw/arm/arm.h"
128
-#include "hw/devices.h"
129
+#include "hw/net/smc91c111.h"
130
#include "net/net.h"
131
#include "sysemu/sysemu.h"
132
#include "hw/pci/pci.h"
133
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
134
index XXXXXXX..XXXXXXX 100644
135
--- a/hw/net/smc91c111.c
136
+++ b/hw/net/smc91c111.c
137
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
138
#include "qemu/osdep.h"
32
#include "qemu/osdep.h"
139
#include "hw/sysbus.h"
33
#include "qapi/error.h"
140
#include "net/net.h"
34
#include "hw/arm/fsl-imx6.h"
141
-#include "hw/devices.h"
35
+#include "hw/arm/boot.h"
142
+#include "hw/net/smc91c111.h"
36
#include "hw/boards.h"
143
#include "qemu/log.h"
37
#include "hw/qdev-properties.h"
144
/* For crc32 */
38
#include "qemu/error-report.h"
145
#include <zlib.h>
146
--
39
--
147
2.20.1
40
2.34.1
148
41
149
42
diff view generated by jsdifflib
1
Handle floating point registers in exception entry.
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
This corresponds to the FP-specific parts of the pseudocode
3
functions ActivateException() and PushStack().
4
2
5
We defer the code corresponding to UpdateFPCCR() to a later patch.
3
"hw/arm/boot.h" is only required on the source file.
6
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
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-11-peter.maydell@linaro.org
10
---
10
---
11
target/arm/helper.c | 98 +++++++++++++++++++++++++++++++++++++++++++--
11
include/hw/arm/fsl-imx6ul.h | 1 -
12
1 file changed, 95 insertions(+), 3 deletions(-)
12
hw/arm/mcimx6ul-evk.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
13
14
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/arm/fsl-imx6ul.h b/include/hw/arm/fsl-imx6ul.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
--- a/include/hw/arm/fsl-imx6ul.h
17
+++ b/target/arm/helper.c
18
+++ b/include/hw/arm/fsl-imx6ul.h
18
@@ -XXX,XX +XXX,XX @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
19
@@ -XXX,XX +XXX,XX @@
19
switch_v7m_security_state(env, targets_secure);
20
#ifndef FSL_IMX6UL_H
20
write_v7m_control_spsel(env, 0);
21
#define FSL_IMX6UL_H
21
arm_clear_exclusive(env);
22
22
+ /* Clear SFPA and FPCA (has no effect if no FPU) */
23
-#include "hw/arm/boot.h"
23
+ env->v7m.control[M_REG_S] &=
24
#include "hw/cpu/a15mpcore.h"
24
+ ~(R_V7M_CONTROL_FPCA_MASK | R_V7M_CONTROL_SFPA_MASK);
25
#include "hw/misc/imx6ul_ccm.h"
25
/* Clear IT bits */
26
#include "hw/misc/imx6_src.h"
26
env->condexec_bits = 0;
27
diff --git a/hw/arm/mcimx6ul-evk.c b/hw/arm/mcimx6ul-evk.c
27
env->regs[14] = lr;
28
index XXXXXXX..XXXXXXX 100644
28
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
29
--- a/hw/arm/mcimx6ul-evk.c
29
uint32_t xpsr = xpsr_read(env);
30
+++ b/hw/arm/mcimx6ul-evk.c
30
uint32_t frameptr = env->regs[13];
31
@@ -XXX,XX +XXX,XX @@
31
ARMMMUIdx mmu_idx = arm_mmu_idx(env);
32
#include "qemu/osdep.h"
32
+ uint32_t framesize;
33
#include "qapi/error.h"
33
+ bool nsacr_cp10 = extract32(env->v7m.nsacr, 10, 1);
34
#include "hw/arm/fsl-imx6ul.h"
34
+
35
+#include "hw/arm/boot.h"
35
+ if ((env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) &&
36
#include "hw/boards.h"
36
+ (env->v7m.secure || nsacr_cp10)) {
37
#include "hw/qdev-properties.h"
37
+ if (env->v7m.secure &&
38
#include "qemu/error-report.h"
38
+ env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK) {
39
+ framesize = 0xa8;
40
+ } else {
41
+ framesize = 0x68;
42
+ }
43
+ } else {
44
+ framesize = 0x20;
45
+ }
46
47
/* Align stack pointer if the guest wants that */
48
if ((frameptr & 4) &&
49
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
50
xpsr |= XPSR_SPREALIGN;
51
}
52
53
- frameptr -= 0x20;
54
+ xpsr &= ~XPSR_SFPA;
55
+ if (env->v7m.secure &&
56
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)) {
57
+ xpsr |= XPSR_SFPA;
58
+ }
59
+
60
+ frameptr -= framesize;
61
62
if (arm_feature(env, ARM_FEATURE_V8)) {
63
uint32_t limit = v7m_sp_limit(env);
64
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
65
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
66
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
67
68
+ if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
69
+ /* FPU is active, try to save its registers */
70
+ bool fpccr_s = env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_S_MASK;
71
+ bool lspact = env->v7m.fpccr[fpccr_s] & R_V7M_FPCCR_LSPACT_MASK;
72
+
73
+ if (lspact && arm_feature(env, ARM_FEATURE_M_SECURITY)) {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...SecureFault because LSPACT and FPCA both set\n");
76
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
77
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
78
+ } else if (!env->v7m.secure && !nsacr_cp10) {
79
+ qemu_log_mask(CPU_LOG_INT,
80
+ "...Secure UsageFault with CFSR.NOCP because "
81
+ "NSACR.CP10 prevents stacking FP regs\n");
82
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, M_REG_S);
83
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_NOCP_MASK;
84
+ } else {
85
+ if (!(env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPEN_MASK)) {
86
+ /* Lazy stacking disabled, save registers now */
87
+ int i;
88
+ bool cpacr_pass = v7m_cpacr_pass(env, env->v7m.secure,
89
+ arm_current_el(env) != 0);
90
+
91
+ if (stacked_ok && !cpacr_pass) {
92
+ /*
93
+ * Take UsageFault if CPACR forbids access. The pseudocode
94
+ * here does a full CheckCPEnabled() but we know the NSACR
95
+ * check can never fail as we have already handled that.
96
+ */
97
+ qemu_log_mask(CPU_LOG_INT,
98
+ "...UsageFault with CFSR.NOCP because "
99
+ "CPACR.CP10 prevents stacking FP regs\n");
100
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
101
+ env->v7m.secure);
102
+ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_NOCP_MASK;
103
+ stacked_ok = false;
104
+ }
105
+
106
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
107
+ uint64_t dn = *aa32_vfp_dreg(env, i / 2);
108
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
109
+ uint32_t slo = extract64(dn, 0, 32);
110
+ uint32_t shi = extract64(dn, 32, 32);
111
+
112
+ if (i >= 16) {
113
+ faddr += 8; /* skip the slot for the FPSCR */
114
+ }
115
+ stacked_ok = stacked_ok &&
116
+ v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
117
+ v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
118
+ }
119
+ stacked_ok = stacked_ok &&
120
+ v7m_stack_write(cpu, frameptr + 0x60,
121
+ vfp_get_fpscr(env), mmu_idx, false);
122
+ if (cpacr_pass) {
123
+ for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
124
+ *aa32_vfp_dreg(env, i / 2) = 0;
125
+ }
126
+ vfp_set_fpscr(env, 0);
127
+ }
128
+ } else {
129
+ /* Lazy stacking enabled, save necessary info to stack later */
130
+ /* TODO : equivalent of UpdateFPCCR() pseudocode */
131
+ }
132
+ }
133
+ }
134
+
135
/*
136
* If we broke a stack limit then SP was already updated earlier;
137
* otherwise we update SP regardless of whether any of the stack
138
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
139
140
if (arm_feature(env, ARM_FEATURE_V8)) {
141
lr = R_V7M_EXCRET_RES1_MASK |
142
- R_V7M_EXCRET_DCRS_MASK |
143
- R_V7M_EXCRET_FTYPE_MASK;
144
+ R_V7M_EXCRET_DCRS_MASK;
145
/* The S bit indicates whether we should return to Secure
146
* or NonSecure (ie our current state).
147
* The ES bit indicates whether we're taking this exception
148
@@ -XXX,XX +XXX,XX @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
149
if (env->v7m.secure) {
150
lr |= R_V7M_EXCRET_S_MASK;
151
}
152
+ if (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
153
+ lr |= R_V7M_EXCRET_FTYPE_MASK;
154
+ }
155
} else {
156
lr = R_V7M_EXCRET_RES1_MASK |
157
R_V7M_EXCRET_S_MASK |
158
--
39
--
159
2.20.1
40
2.34.1
160
41
161
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
"hw/arm/boot.h" is only required on the source file.
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Message-id: 20190412165416.7977-7-philmd@redhat.com
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
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
10
---
9
include/hw/devices.h | 14 --------------
11
include/hw/arm/fsl-imx7.h | 1 -
10
include/hw/misc/cbus.h | 32 ++++++++++++++++++++++++++++++++
12
hw/arm/mcimx7d-sabre.c | 1 +
11
hw/arm/nseries.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
12
hw/misc/cbus.c | 2 +-
13
MAINTAINERS | 1 +
14
5 files changed, 35 insertions(+), 15 deletions(-)
15
create mode 100644 include/hw/misc/cbus.h
16
14
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
17
--- a/include/hw/arm/fsl-imx7.h
20
+++ b/include/hw/devices.h
18
+++ b/include/hw/arm/fsl-imx7.h
21
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
22
/* stellaris_input.c */
23
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
25
-/* cbus.c */
26
-typedef struct {
27
- qemu_irq clk;
28
- qemu_irq dat;
29
- qemu_irq sel;
30
-} CBus;
31
-CBus *cbus_init(qemu_irq dat_out);
32
-void cbus_attach(CBus *bus, void *slave_opaque);
33
-
34
-void *retu_init(qemu_irq irq, int vilma);
35
-void *tahvo_init(qemu_irq irq, int betty);
36
-
37
-void retu_key_event(void *retu, int state);
38
-
39
#endif
40
diff --git a/include/hw/misc/cbus.h b/include/hw/misc/cbus.h
41
new file mode 100644
42
index XXXXXXX..XXXXXXX
43
--- /dev/null
44
+++ b/include/hw/misc/cbus.h
45
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
46
+/*
20
#ifndef FSL_IMX7_H
47
+ * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma /
21
#define FSL_IMX7_H
48
+ * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms.
22
49
+ * Based on reverse-engineering of a linux driver.
23
-#include "hw/arm/boot.h"
50
+ *
24
#include "hw/cpu/a15mpcore.h"
51
+ * Copyright (C) 2008 Nokia Corporation
25
#include "hw/intc/imx_gpcv2.h"
52
+ * Written by Andrzej Zaborowski
26
#include "hw/misc/imx7_ccm.h"
53
+ *
27
diff --git a/hw/arm/mcimx7d-sabre.c b/hw/arm/mcimx7d-sabre.c
54
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
55
+ * See the COPYING file in the top-level directory.
56
+ */
57
+
58
+#ifndef HW_MISC_CBUS_H
59
+#define HW_MISC_CBUS_H
60
+
61
+#include "hw/irq.h"
62
+
63
+typedef struct {
64
+ qemu_irq clk;
65
+ qemu_irq dat;
66
+ qemu_irq sel;
67
+} CBus;
68
+
69
+CBus *cbus_init(qemu_irq dat_out);
70
+void cbus_attach(CBus *bus, void *slave_opaque);
71
+
72
+void *retu_init(qemu_irq irq, int vilma);
73
+void *tahvo_init(qemu_irq irq, int betty);
74
+
75
+void retu_key_event(void *retu, int state);
76
+
77
+#endif
78
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
79
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
80
--- a/hw/arm/nseries.c
29
--- a/hw/arm/mcimx7d-sabre.c
81
+++ b/hw/arm/nseries.c
30
+++ b/hw/arm/mcimx7d-sabre.c
82
@@ -XXX,XX +XXX,XX @@
83
#include "hw/i2c/i2c.h"
84
#include "hw/devices.h"
85
#include "hw/display/blizzard.h"
86
+#include "hw/misc/cbus.h"
87
#include "hw/misc/tmp105.h"
88
#include "hw/block/flash.h"
89
#include "hw/hw.h"
90
diff --git a/hw/misc/cbus.c b/hw/misc/cbus.c
91
index XXXXXXX..XXXXXXX 100644
92
--- a/hw/misc/cbus.c
93
+++ b/hw/misc/cbus.c
94
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
95
#include "qemu/osdep.h"
32
#include "qemu/osdep.h"
96
#include "hw/hw.h"
33
#include "qapi/error.h"
97
#include "hw/irq.h"
34
#include "hw/arm/fsl-imx7.h"
98
-#include "hw/devices.h"
35
+#include "hw/arm/boot.h"
99
+#include "hw/misc/cbus.h"
36
#include "hw/boards.h"
100
#include "sysemu/sysemu.h"
37
#include "hw/qdev-properties.h"
101
38
#include "qemu/error-report.h"
102
//#define DEBUG
103
diff --git a/MAINTAINERS b/MAINTAINERS
104
index XXXXXXX..XXXXXXX 100644
105
--- a/MAINTAINERS
106
+++ b/MAINTAINERS
107
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
108
F: hw/misc/cbus.c
109
F: hw/timer/twl92230.c
110
F: include/hw/display/blizzard.h
111
+F: include/hw/misc/cbus.h
112
113
Palm
114
M: Andrzej Zaborowski <balrogg@gmail.com>
115
--
39
--
116
2.20.1
40
2.34.1
117
41
118
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Since uWireSlave is only used in this new header, there is no
3
"hw/arm/boot.h" is only required on the source file.
4
need to expose it via "qemu/typedefs.h".
5
4
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190412165416.7977-9-philmd@redhat.com
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>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
include/hw/arm/omap.h | 6 +-----
11
include/hw/arm/xlnx-versal.h | 1 -
12
include/hw/devices.h | 15 ---------------
12
hw/arm/xlnx-versal-virt.c | 1 +
13
include/hw/input/tsc2xxx.h | 36 ++++++++++++++++++++++++++++++++++++
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
include/qemu/typedefs.h | 1 -
15
hw/arm/nseries.c | 2 +-
16
hw/arm/palm.c | 2 +-
17
hw/input/tsc2005.c | 2 +-
18
hw/input/tsc210x.c | 4 ++--
19
MAINTAINERS | 2 ++
20
9 files changed, 44 insertions(+), 26 deletions(-)
21
create mode 100644 include/hw/input/tsc2xxx.h
22
14
23
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
15
diff --git a/include/hw/arm/xlnx-versal.h b/include/hw/arm/xlnx-versal.h
24
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
25
--- a/include/hw/arm/omap.h
17
--- a/include/hw/arm/xlnx-versal.h
26
+++ b/include/hw/arm/omap.h
18
+++ b/include/hw/arm/xlnx-versal.h
27
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
28
#include "exec/memory.h"
20
#define XLNX_VERSAL_H
29
# define hw_omap_h        "omap.h"
21
30
#include "hw/irq.h"
22
#include "hw/sysbus.h"
31
+#include "hw/input/tsc2xxx.h"
23
-#include "hw/arm/boot.h"
32
#include "target/arm/cpu-qom.h"
24
#include "hw/cpu/cluster.h"
33
#include "qemu/log.h"
25
#include "hw/or-irq.h"
34
26
#include "hw/sd/sdhci.h"
35
@@ -XXX,XX +XXX,XX @@ qemu_irq *omap_mpuio_in_get(struct omap_mpuio_s *s);
27
diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c
36
void omap_mpuio_out_set(struct omap_mpuio_s *s, int line, qemu_irq handler);
37
void omap_mpuio_key(struct omap_mpuio_s *s, int row, int col, int down);
38
39
-struct uWireSlave {
40
- uint16_t (*receive)(void *opaque);
41
- void (*send)(void *opaque, uint16_t data);
42
- void *opaque;
43
-};
44
struct omap_uwire_s;
45
void omap_uwire_attach(struct omap_uwire_s *s,
46
uWireSlave *slave, int chipselect);
47
diff --git a/include/hw/devices.h b/include/hw/devices.h
48
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
49
--- a/include/hw/devices.h
29
--- a/hw/arm/xlnx-versal-virt.c
50
+++ b/include/hw/devices.h
30
+++ b/hw/arm/xlnx-versal-virt.c
51
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
52
/* Devices that have nowhere better to go. */
53
54
#include "hw/hw.h"
55
-#include "ui/console.h"
56
57
/* smc91c111.c */
58
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
59
@@ -XXX,XX +XXX,XX @@ void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
60
/* lan9118.c */
61
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
62
63
-/* tsc210x.c */
64
-uWireSlave *tsc2102_init(qemu_irq pint);
65
-uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
66
-I2SCodec *tsc210x_codec(uWireSlave *chip);
67
-uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
68
-void tsc210x_set_transform(uWireSlave *chip,
69
- MouseTransformInfo *info);
70
-void tsc210x_key_event(uWireSlave *chip, int key, int down);
71
-
72
-/* tsc2005.c */
73
-void *tsc2005_init(qemu_irq pintdav);
74
-uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
75
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
76
-
77
#endif
78
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
79
new file mode 100644
80
index XXXXXXX..XXXXXXX
81
--- /dev/null
82
+++ b/include/hw/input/tsc2xxx.h
83
@@ -XXX,XX +XXX,XX @@
84
+/*
85
+ * TI touchscreen controller
86
+ *
87
+ * Copyright (c) 2006 Andrzej Zaborowski
88
+ * Copyright (C) 2008 Nokia Corporation
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
+#ifndef HW_INPUT_TSC2XXX_H
95
+#define HW_INPUT_TSC2XXX_H
96
+
97
+#include "hw/irq.h"
98
+#include "ui/console.h"
99
+
100
+typedef struct uWireSlave {
101
+ uint16_t (*receive)(void *opaque);
102
+ void (*send)(void *opaque, uint16_t data);
103
+ void *opaque;
104
+} uWireSlave;
105
+
106
+/* tsc210x.c */
107
+uWireSlave *tsc2102_init(qemu_irq pint);
108
+uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
109
+I2SCodec *tsc210x_codec(uWireSlave *chip);
110
+uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
111
+void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
112
+void tsc210x_key_event(uWireSlave *chip, int key, int down);
113
+
114
+/* tsc2005.c */
115
+void *tsc2005_init(qemu_irq pintdav);
116
+uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
117
+void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
118
+
119
+#endif
120
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
121
index XXXXXXX..XXXXXXX 100644
122
--- a/include/qemu/typedefs.h
123
+++ b/include/qemu/typedefs.h
124
@@ -XXX,XX +XXX,XX @@ typedef struct RAMBlock RAMBlock;
125
typedef struct Range Range;
126
typedef struct SHPCDevice SHPCDevice;
127
typedef struct SSIBus SSIBus;
128
-typedef struct uWireSlave uWireSlave;
129
typedef struct VirtIODevice VirtIODevice;
130
typedef struct Visitor Visitor;
131
typedef void SaveStateHandler(QEMUFile *f, void *opaque);
132
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
133
index XXXXXXX..XXXXXXX 100644
134
--- a/hw/arm/nseries.c
135
+++ b/hw/arm/nseries.c
136
@@ -XXX,XX +XXX,XX @@
137
#include "ui/console.h"
138
#include "hw/boards.h"
139
#include "hw/i2c/i2c.h"
140
-#include "hw/devices.h"
141
#include "hw/display/blizzard.h"
142
+#include "hw/input/tsc2xxx.h"
143
#include "hw/misc/cbus.h"
144
#include "hw/misc/tmp105.h"
145
#include "hw/block/flash.h"
146
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
147
index XXXXXXX..XXXXXXX 100644
148
--- a/hw/arm/palm.c
149
+++ b/hw/arm/palm.c
150
@@ -XXX,XX +XXX,XX @@
151
#include "hw/arm/omap.h"
152
#include "hw/boards.h"
153
#include "hw/arm/arm.h"
154
-#include "hw/devices.h"
155
+#include "hw/input/tsc2xxx.h"
156
#include "hw/loader.h"
157
#include "exec/address-spaces.h"
158
#include "cpu.h"
32
#include "cpu.h"
159
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
33
#include "hw/qdev-properties.h"
160
index XXXXXXX..XXXXXXX 100644
34
#include "hw/arm/xlnx-versal.h"
161
--- a/hw/input/tsc2005.c
35
+#include "hw/arm/boot.h"
162
+++ b/hw/input/tsc2005.c
36
#include "qom/object.h"
163
@@ -XXX,XX +XXX,XX @@
37
164
#include "hw/hw.h"
38
#define TYPE_XLNX_VERSAL_VIRT_MACHINE MACHINE_TYPE_NAME("xlnx-versal-virt")
165
#include "qemu/timer.h"
166
#include "ui/console.h"
167
-#include "hw/devices.h"
168
+#include "hw/input/tsc2xxx.h"
169
#include "trace.h"
170
171
#define TSC_CUT_RESOLUTION(value, p)    ((value) >> (16 - (p ? 12 : 10)))
172
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
173
index XXXXXXX..XXXXXXX 100644
174
--- a/hw/input/tsc210x.c
175
+++ b/hw/input/tsc210x.c
176
@@ -XXX,XX +XXX,XX @@
177
#include "audio/audio.h"
178
#include "qemu/timer.h"
179
#include "ui/console.h"
180
-#include "hw/arm/omap.h"    /* For I2SCodec and uWireSlave */
181
-#include "hw/devices.h"
182
+#include "hw/arm/omap.h" /* For I2SCodec */
183
+#include "hw/input/tsc2xxx.h"
184
185
#define TSC_DATA_REGISTERS_PAGE        0x0
186
#define TSC_CONTROL_REGISTERS_PAGE    0x1
187
diff --git a/MAINTAINERS b/MAINTAINERS
188
index XXXXXXX..XXXXXXX 100644
189
--- a/MAINTAINERS
190
+++ b/MAINTAINERS
191
@@ -XXX,XX +XXX,XX @@ F: hw/input/tsc2005.c
192
F: hw/misc/cbus.c
193
F: hw/timer/twl92230.c
194
F: include/hw/display/blizzard.h
195
+F: include/hw/input/tsc2xxx.h
196
F: include/hw/misc/cbus.h
197
198
Palm
199
@@ -XXX,XX +XXX,XX @@ L: qemu-arm@nongnu.org
200
S: Odd Fixes
201
F: hw/arm/palm.c
202
F: hw/input/tsc210x.c
203
+F: include/hw/input/tsc2xxx.h
204
205
Raspberry Pi
206
M: Peter Maydell <peter.maydell@linaro.org>
207
--
39
--
208
2.20.1
40
2.34.1
209
41
210
42
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Add an entries the Blizzard device in MAINTAINERS.
3
"hw/arm/boot.h" is only required on the source file.
4
4
5
Reviewed-by: Thomas Huth <thuth@redhat.com>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Markus Armbruster <armbru@redhat.com>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
7
Reviewed-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20190412165416.7977-6-philmd@redhat.com
8
Message-id: 20231025065316.56817-11-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
include/hw/devices.h | 7 -------
11
include/hw/arm/xlnx-zynqmp.h | 1 -
12
include/hw/display/blizzard.h | 22 ++++++++++++++++++++++
12
hw/arm/xlnx-zcu102.c | 1 +
13
hw/arm/nseries.c | 1 +
13
2 files changed, 1 insertion(+), 1 deletion(-)
14
hw/display/blizzard.c | 2 +-
15
MAINTAINERS | 2 ++
16
5 files changed, 26 insertions(+), 8 deletions(-)
17
create mode 100644 include/hw/display/blizzard.h
18
14
19
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
20
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
21
--- a/include/hw/devices.h
17
--- a/include/hw/arm/xlnx-zynqmp.h
22
+++ b/include/hw/devices.h
18
+++ b/include/hw/arm/xlnx-zynqmp.h
23
@@ -XXX,XX +XXX,XX @@ void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
24
/* stellaris_input.c */
25
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
26
27
-/* blizzard.c */
28
-void *s1d13745_init(qemu_irq gpio_int);
29
-void s1d13745_write(void *opaque, int dc, uint16_t value);
30
-void s1d13745_write_block(void *opaque, int dc,
31
- void *buf, size_t len, int pitch);
32
-uint16_t s1d13745_read(void *opaque, int dc);
33
-
34
/* cbus.c */
35
typedef struct {
36
qemu_irq clk;
37
diff --git a/include/hw/display/blizzard.h b/include/hw/display/blizzard.h
38
new file mode 100644
39
index XXXXXXX..XXXXXXX
40
--- /dev/null
41
+++ b/include/hw/display/blizzard.h
42
@@ -XXX,XX +XXX,XX @@
19
@@ -XXX,XX +XXX,XX @@
43
+/*
20
#ifndef XLNX_ZYNQMP_H
44
+ * Epson S1D13744/S1D13745 (Blizzard/Hailstorm/Tornado) LCD/TV controller.
21
#define XLNX_ZYNQMP_H
45
+ *
22
46
+ * Copyright (C) 2008 Nokia Corporation
23
-#include "hw/arm/boot.h"
47
+ * Written by Andrzej Zaborowski
24
#include "hw/intc/arm_gic.h"
48
+ *
25
#include "hw/net/cadence_gem.h"
49
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
26
#include "hw/char/cadence_uart.h"
50
+ * See the COPYING file in the top-level directory.
27
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
51
+ */
52
+
53
+#ifndef HW_DISPLAY_BLIZZARD_H
54
+#define HW_DISPLAY_BLIZZARD_H
55
+
56
+#include "hw/irq.h"
57
+
58
+void *s1d13745_init(qemu_irq gpio_int);
59
+void s1d13745_write(void *opaque, int dc, uint16_t value);
60
+void s1d13745_write_block(void *opaque, int dc,
61
+ void *buf, size_t len, int pitch);
62
+uint16_t s1d13745_read(void *opaque, int dc);
63
+
64
+#endif
65
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
66
index XXXXXXX..XXXXXXX 100644
28
index XXXXXXX..XXXXXXX 100644
67
--- a/hw/arm/nseries.c
29
--- a/hw/arm/xlnx-zcu102.c
68
+++ b/hw/arm/nseries.c
30
+++ b/hw/arm/xlnx-zcu102.c
69
@@ -XXX,XX +XXX,XX @@
70
#include "hw/boards.h"
71
#include "hw/i2c/i2c.h"
72
#include "hw/devices.h"
73
+#include "hw/display/blizzard.h"
74
#include "hw/misc/tmp105.h"
75
#include "hw/block/flash.h"
76
#include "hw/hw.h"
77
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
78
index XXXXXXX..XXXXXXX 100644
79
--- a/hw/display/blizzard.c
80
+++ b/hw/display/blizzard.c
81
@@ -XXX,XX +XXX,XX @@
31
@@ -XXX,XX +XXX,XX @@
82
#include "qemu/osdep.h"
32
#include "qemu/osdep.h"
83
#include "qemu-common.h"
33
#include "qapi/error.h"
84
#include "ui/console.h"
34
#include "hw/arm/xlnx-zynqmp.h"
85
-#include "hw/devices.h"
35
+#include "hw/arm/boot.h"
86
+#include "hw/display/blizzard.h"
36
#include "hw/boards.h"
87
#include "ui/pixel_ops.h"
37
#include "qemu/error-report.h"
88
38
#include "qemu/log.h"
89
typedef void (*blizzard_fn_t)(uint8_t *, const uint8_t *, unsigned int);
90
diff --git a/MAINTAINERS b/MAINTAINERS
91
index XXXXXXX..XXXXXXX 100644
92
--- a/MAINTAINERS
93
+++ b/MAINTAINERS
94
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
95
L: qemu-arm@nongnu.org
96
S: Odd Fixes
97
F: hw/arm/nseries.c
98
+F: hw/display/blizzard.c
99
F: hw/input/lm832x.c
100
F: hw/input/tsc2005.c
101
F: hw/misc/cbus.c
102
F: hw/timer/twl92230.c
103
+F: include/hw/display/blizzard.h
104
105
Palm
106
M: Andrzej Zaborowski <balrogg@gmail.com>
107
--
39
--
108
2.20.1
40
2.34.1
109
41
110
42
diff view generated by jsdifflib
1
Currently the code in v7m_push_stack() which detects a violation
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
of the v8M stack limit simply returns early if it does so. This
3
is OK for the current integer-only code, but won't work for the
4
floating point handling we're about to add. We need to continue
5
executing the rest of the function so that we check for other
6
exceptions like not having permission to use the FPU and so
7
that we correctly set the FPCCR state if we are doing lazy
8
stacking. Refactor to avoid the early return.
9
2
3
sysbus_mmio_map() and sysbus_connect_irq() should not be
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>
9
Message-id: 20231020130331.50048-2-philmd@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
12
Message-id: 20190416125744.27770-10-peter.maydell@linaro.org
13
---
11
---
14
target/arm/helper.c | 23 ++++++++++++++++++-----
12
hw/sd/pxa2xx_mmci.c | 2 +-
15
1 file changed, 18 insertions(+), 5 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
16
14
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
18
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
17
--- a/hw/sd/pxa2xx_mmci.c
20
+++ b/target/arm/helper.c
18
+++ b/hw/sd/pxa2xx_mmci.c
21
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
19
@@ -XXX,XX +XXX,XX @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
22
* should ignore further stack faults trying to process
20
23
* that derived exception.)
21
dev = qdev_new(TYPE_PXA2XX_MMCI);
24
*/
22
sbd = SYS_BUS_DEVICE(dev);
25
- bool stacked_ok;
23
+ sysbus_realize_and_unref(sbd, &error_fatal);
26
+ bool stacked_ok = true, limitviol = false;
24
sysbus_mmio_map(sbd, 0, base);
27
CPUARMState *env = &cpu->env;
25
sysbus_connect_irq(sbd, 0, irq);
28
uint32_t xpsr = xpsr_read(env);
26
qdev_connect_gpio_out_named(dev, "rx-dma", 0, rx_dma);
29
uint32_t frameptr = env->regs[13];
27
qdev_connect_gpio_out_named(dev, "tx-dma", 0, tx_dma);
30
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
28
- sysbus_realize_and_unref(sbd, &error_fatal);
31
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
29
32
env->v7m.secure);
30
return PXA2XX_MMCI(dev);
33
env->regs[13] = limit;
34
- return true;
35
+ /*
36
+ * We won't try to perform any further memory accesses but
37
+ * we must continue through the following code to check for
38
+ * permission faults during FPU state preservation, and we
39
+ * must update FPCCR if lazy stacking is enabled.
40
+ */
41
+ limitviol = true;
42
+ stacked_ok = false;
43
}
44
}
45
46
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
47
* (which may be taken in preference to the one we started with
48
* if it has higher priority).
49
*/
50
- stacked_ok =
51
+ stacked_ok = stacked_ok &&
52
v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
53
v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
54
v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
55
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
56
v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
57
v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
58
59
- /* Update SP regardless of whether any of the stack accesses failed. */
60
- env->regs[13] = frameptr;
61
+ /*
62
+ * If we broke a stack limit then SP was already updated earlier;
63
+ * otherwise we update SP regardless of whether any of the stack
64
+ * accesses failed or we took some other kind of fault.
65
+ */
66
+ if (!limitviol) {
67
+ env->regs[13] = frameptr;
68
+ }
69
70
return !stacked_ok;
71
}
31
}
72
--
32
--
73
2.20.1
33
2.34.1
74
34
75
35
diff view generated by jsdifflib
1
The M-profile FPCCR.ASPEN bit indicates that automatic floating-point
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
context preservation is enabled. Before executing any floating-point
3
instruction, if FPCCR.ASPEN is set and the CONTROL FPCA/SFPA bits
4
indicate that there is no active floating point context then we
5
must create a new context (by initializing FPSCR and setting
6
FPCA/SFPA to indicate that the context is now active). In the
7
pseudocode this is handled by ExecuteFPCheck().
8
2
9
Implement this with a new TB flag which tracks whether we
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
need to create a new FP context.
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
11
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
diff --git a/hw/sd/pxa2xx_mmci.c b/hw/sd/pxa2xx_mmci.c
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-20-peter.maydell@linaro.org
15
---
16
target/arm/cpu.h | 2 ++
17
target/arm/translate.h | 1 +
18
target/arm/helper.c | 13 +++++++++++++
19
target/arm/translate.c | 29 +++++++++++++++++++++++++++++
20
4 files changed, 45 insertions(+)
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
14
--- a/hw/sd/pxa2xx_mmci.c
25
+++ b/target/arm/cpu.h
15
+++ b/hw/sd/pxa2xx_mmci.c
26
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
16
@@ -XXX,XX +XXX,XX @@ PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
27
FIELD(TBFLAG_A32, VFPEN, 7, 1)
17
qemu_irq irq, qemu_irq rx_dma, qemu_irq tx_dma)
28
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
18
{
29
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
19
DeviceState *dev;
30
+/* For M profile only, set if we must create a new FP context */
20
- SysBusDevice *sbd;
31
+FIELD(TBFLAG_A32, NEW_FP_CTXT_NEEDED, 19, 1)
21
32
/* For M profile only, set if FPCCR.S does not match current security state */
22
- dev = qdev_new(TYPE_PXA2XX_MMCI);
33
FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
23
- sbd = SYS_BUS_DEVICE(dev);
34
/* For M profile only, Handler (ie not Thread) mode */
24
- sysbus_realize_and_unref(sbd, &error_fatal);
35
diff --git a/target/arm/translate.h b/target/arm/translate.h
25
- sysbus_mmio_map(sbd, 0, base);
36
index XXXXXXX..XXXXXXX 100644
26
- sysbus_connect_irq(sbd, 0, irq);
37
--- a/target/arm/translate.h
27
+ dev = sysbus_create_simple(TYPE_PXA2XX_MMCI, base, irq);
38
+++ b/target/arm/translate.h
28
qdev_connect_gpio_out_named(dev, "rx-dma", 0, rx_dma);
39
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
29
qdev_connect_gpio_out_named(dev, "tx-dma", 0, tx_dma);
40
bool v8m_secure; /* true if v8M and we're in Secure mode */
41
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
42
bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
43
+ bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
44
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
45
* so that top level loop can generate correct syndrome information.
46
*/
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 @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
52
flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
53
}
54
55
+ if (arm_feature(env, ARM_FEATURE_M) &&
56
+ (env->v7m.fpccr[env->v7m.secure] & R_V7M_FPCCR_ASPEN_MASK) &&
57
+ (!(env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) ||
58
+ (env->v7m.secure &&
59
+ !(env->v7m.control[M_REG_S] & R_V7M_CONTROL_SFPA_MASK)))) {
60
+ /*
61
+ * ASPEN is set, but FPCA/SFPA indicate that there is no active
62
+ * FP context; we must create a new FP context before executing
63
+ * any FP insn.
64
+ */
65
+ flags = FIELD_DP32(flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED, 1);
66
+ }
67
+
68
*pflags = flags;
69
*cs_base = 0;
70
}
71
diff --git a/target/arm/translate.c b/target/arm/translate.c
72
index XXXXXXX..XXXXXXX 100644
73
--- a/target/arm/translate.c
74
+++ b/target/arm/translate.c
75
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
76
/* Don't need to do this for any further FP insns in this TB */
77
s->v8m_fpccr_s_wrong = false;
78
}
79
+
80
+ if (s->v7m_new_fp_ctxt_needed) {
81
+ /*
82
+ * Create new FP context by updating CONTROL.FPCA, CONTROL.SFPA
83
+ * and the FPSCR.
84
+ */
85
+ TCGv_i32 control, fpscr;
86
+ uint32_t bits = R_V7M_CONTROL_FPCA_MASK;
87
+
88
+ fpscr = load_cpu_field(v7m.fpdscr[s->v8m_secure]);
89
+ gen_helper_vfp_set_fpscr(cpu_env, fpscr);
90
+ tcg_temp_free_i32(fpscr);
91
+ /*
92
+ * We don't need to arrange to end the TB, because the only
93
+ * parts of FPSCR which we cache in the TB flags are the VECLEN
94
+ * and VECSTRIDE, and those don't exist for M-profile.
95
+ */
96
+
97
+ if (s->v8m_secure) {
98
+ bits |= R_V7M_CONTROL_SFPA_MASK;
99
+ }
100
+ control = load_cpu_field(v7m.control[M_REG_S]);
101
+ tcg_gen_ori_i32(control, control, bits);
102
+ store_cpu_field(control, v7m.control[M_REG_S]);
103
+ /* Don't need to do this for any further FP insns in this TB */
104
+ s->v7m_new_fp_ctxt_needed = false;
105
+ }
106
}
107
108
if (extract32(insn, 28, 4) == 0xf) {
109
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
110
regime_is_secure(env, dc->mmu_idx);
111
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
112
dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
113
+ dc->v7m_new_fp_ctxt_needed =
114
+ FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
115
dc->cp_regs = cpu->cp_regs;
116
dc->features = env->features;
117
30
118
--
31
--
119
2.20.1
32
2.34.1
120
33
121
34
diff view generated by jsdifflib
1
Pushing registers to the stack for v7M needs to handle three cases:
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
* the "normal" case where we pend exceptions
3
* an "ignore faults" case where we set FSR bits but
4
do not pend exceptions (this is used when we are
5
handling some kinds of derived exception on exception entry)
6
* a "lazy FP stacking" case, where different FSR bits
7
are set and the exception is pended differently
8
2
9
Implement this by changing the existing flag argument that
3
sysbus_mmio_map() should not be called on unrealized device.
10
tells us whether to ignore faults or not into an enum that
11
specifies which of the 3 modes we should handle.
12
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
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
15
Message-id: 20190416125744.27770-23-peter.maydell@linaro.org
16
---
10
---
17
target/arm/helper.c | 118 +++++++++++++++++++++++++++++---------------
11
hw/pcmcia/pxa2xx.c | 7 ++-----
18
1 file changed, 79 insertions(+), 39 deletions(-)
12
1 file changed, 2 insertions(+), 5 deletions(-)
19
13
20
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
21
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/helper.c
16
--- a/hw/pcmcia/pxa2xx.c
23
+++ b/target/arm/helper.c
17
+++ b/hw/pcmcia/pxa2xx.c
24
@@ -XXX,XX +XXX,XX @@ static bool v7m_cpacr_pass(CPUARMState *env, bool is_secure, bool is_priv)
18
@@ -XXX,XX +XXX,XX @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
25
}
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);
26
}
33
}
27
34
28
+/*
35
static void pxa2xx_pcmcia_initfn(Object *obj)
29
+ * What kind of stack write are we doing? This affects how exceptions
30
+ * generated during the stacking are treated.
31
+ */
32
+typedef enum StackingMode {
33
+ STACK_NORMAL,
34
+ STACK_IGNFAULTS,
35
+ STACK_LAZYFP,
36
+} StackingMode;
37
+
38
static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
39
- ARMMMUIdx mmu_idx, bool ignfault)
40
+ ARMMMUIdx mmu_idx, StackingMode mode)
41
{
42
CPUState *cs = CPU(cpu);
43
CPUARMState *env = &cpu->env;
44
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
45
&attrs, &prot, &page_size, &fi, NULL)) {
46
/* MPU/SAU lookup failed */
47
if (fi.type == ARMFault_QEMU_SFault) {
48
- qemu_log_mask(CPU_LOG_INT,
49
- "...SecureFault with SFSR.AUVIOL during stacking\n");
50
- env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK | R_V7M_SFSR_SFARVALID_MASK;
51
+ if (mode == STACK_LAZYFP) {
52
+ qemu_log_mask(CPU_LOG_INT,
53
+ "...SecureFault with SFSR.LSPERR "
54
+ "during lazy stacking\n");
55
+ env->v7m.sfsr |= R_V7M_SFSR_LSPERR_MASK;
56
+ } else {
57
+ qemu_log_mask(CPU_LOG_INT,
58
+ "...SecureFault with SFSR.AUVIOL "
59
+ "during stacking\n");
60
+ env->v7m.sfsr |= R_V7M_SFSR_AUVIOL_MASK;
61
+ }
62
+ env->v7m.sfsr |= R_V7M_SFSR_SFARVALID_MASK;
63
env->v7m.sfar = addr;
64
exc = ARMV7M_EXCP_SECURE;
65
exc_secure = false;
66
} else {
67
- qemu_log_mask(CPU_LOG_INT, "...MemManageFault with CFSR.MSTKERR\n");
68
- env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
69
+ if (mode == STACK_LAZYFP) {
70
+ qemu_log_mask(CPU_LOG_INT,
71
+ "...MemManageFault with CFSR.MLSPERR\n");
72
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MLSPERR_MASK;
73
+ } else {
74
+ qemu_log_mask(CPU_LOG_INT,
75
+ "...MemManageFault with CFSR.MSTKERR\n");
76
+ env->v7m.cfsr[secure] |= R_V7M_CFSR_MSTKERR_MASK;
77
+ }
78
exc = ARMV7M_EXCP_MEM;
79
exc_secure = secure;
80
}
81
@@ -XXX,XX +XXX,XX @@ static bool v7m_stack_write(ARMCPU *cpu, uint32_t addr, uint32_t value,
82
attrs, &txres);
83
if (txres != MEMTX_OK) {
84
/* BusFault trying to write the data */
85
- qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
86
- env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
87
+ if (mode == STACK_LAZYFP) {
88
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.LSPERR\n");
89
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_LSPERR_MASK;
90
+ } else {
91
+ qemu_log_mask(CPU_LOG_INT, "...BusFault with BFSR.STKERR\n");
92
+ env->v7m.cfsr[M_REG_NS] |= R_V7M_CFSR_STKERR_MASK;
93
+ }
94
exc = ARMV7M_EXCP_BUS;
95
exc_secure = false;
96
goto pend_fault;
97
@@ -XXX,XX +XXX,XX @@ pend_fault:
98
* later if we have two derived exceptions.
99
* The only case when we must not pend the exception but instead
100
* throw it away is if we are doing the push of the callee registers
101
- * and we've already generated a derived exception. Even in this
102
- * case we will still update the fault status registers.
103
+ * and we've already generated a derived exception (this is indicated
104
+ * by the caller passing STACK_IGNFAULTS). Even in this case we will
105
+ * still update the fault status registers.
106
*/
107
- if (!ignfault) {
108
+ switch (mode) {
109
+ case STACK_NORMAL:
110
armv7m_nvic_set_pending_derived(env->nvic, exc, exc_secure);
111
+ break;
112
+ case STACK_LAZYFP:
113
+ armv7m_nvic_set_pending_lazyfp(env->nvic, exc, exc_secure);
114
+ break;
115
+ case STACK_IGNFAULTS:
116
+ break;
117
}
118
return false;
119
}
120
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
121
uint32_t limit;
122
bool want_psp;
123
uint32_t sig;
124
+ StackingMode smode = ignore_faults ? STACK_IGNFAULTS : STACK_NORMAL;
125
126
if (dotailchain) {
127
bool mode = lr & R_V7M_EXCRET_MODE_MASK;
128
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
129
*/
130
sig = v7m_integrity_sig(env, lr);
131
stacked_ok =
132
- v7m_stack_write(cpu, frameptr, sig, mmu_idx, ignore_faults) &&
133
- v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx,
134
- ignore_faults) &&
135
- v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx,
136
- ignore_faults) &&
137
- v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx,
138
- ignore_faults) &&
139
- v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx,
140
- ignore_faults) &&
141
- v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx,
142
- ignore_faults) &&
143
- v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx,
144
- ignore_faults) &&
145
- v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx,
146
- ignore_faults) &&
147
- v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx,
148
- ignore_faults);
149
+ v7m_stack_write(cpu, frameptr, sig, mmu_idx, smode) &&
150
+ v7m_stack_write(cpu, frameptr + 0x8, env->regs[4], mmu_idx, smode) &&
151
+ v7m_stack_write(cpu, frameptr + 0xc, env->regs[5], mmu_idx, smode) &&
152
+ v7m_stack_write(cpu, frameptr + 0x10, env->regs[6], mmu_idx, smode) &&
153
+ v7m_stack_write(cpu, frameptr + 0x14, env->regs[7], mmu_idx, smode) &&
154
+ v7m_stack_write(cpu, frameptr + 0x18, env->regs[8], mmu_idx, smode) &&
155
+ v7m_stack_write(cpu, frameptr + 0x1c, env->regs[9], mmu_idx, smode) &&
156
+ v7m_stack_write(cpu, frameptr + 0x20, env->regs[10], mmu_idx, smode) &&
157
+ v7m_stack_write(cpu, frameptr + 0x24, env->regs[11], mmu_idx, smode);
158
159
/* Update SP regardless of whether any of the stack accesses failed. */
160
*frame_sp_p = frameptr;
161
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
162
* if it has higher priority).
163
*/
164
stacked_ok = stacked_ok &&
165
- v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, false) &&
166
- v7m_stack_write(cpu, frameptr + 4, env->regs[1], mmu_idx, false) &&
167
- v7m_stack_write(cpu, frameptr + 8, env->regs[2], mmu_idx, false) &&
168
- v7m_stack_write(cpu, frameptr + 12, env->regs[3], mmu_idx, false) &&
169
- v7m_stack_write(cpu, frameptr + 16, env->regs[12], mmu_idx, false) &&
170
- v7m_stack_write(cpu, frameptr + 20, env->regs[14], mmu_idx, false) &&
171
- v7m_stack_write(cpu, frameptr + 24, env->regs[15], mmu_idx, false) &&
172
- v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, false);
173
+ v7m_stack_write(cpu, frameptr, env->regs[0], mmu_idx, STACK_NORMAL) &&
174
+ v7m_stack_write(cpu, frameptr + 4, env->regs[1],
175
+ mmu_idx, STACK_NORMAL) &&
176
+ v7m_stack_write(cpu, frameptr + 8, env->regs[2],
177
+ mmu_idx, STACK_NORMAL) &&
178
+ v7m_stack_write(cpu, frameptr + 12, env->regs[3],
179
+ mmu_idx, STACK_NORMAL) &&
180
+ v7m_stack_write(cpu, frameptr + 16, env->regs[12],
181
+ mmu_idx, STACK_NORMAL) &&
182
+ v7m_stack_write(cpu, frameptr + 20, env->regs[14],
183
+ mmu_idx, STACK_NORMAL) &&
184
+ v7m_stack_write(cpu, frameptr + 24, env->regs[15],
185
+ mmu_idx, STACK_NORMAL) &&
186
+ v7m_stack_write(cpu, frameptr + 28, xpsr, mmu_idx, STACK_NORMAL);
187
188
if (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK) {
189
/* FPU is active, try to save its registers */
190
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
191
faddr += 8; /* skip the slot for the FPSCR */
192
}
193
stacked_ok = stacked_ok &&
194
- v7m_stack_write(cpu, faddr, slo, mmu_idx, false) &&
195
- v7m_stack_write(cpu, faddr + 4, shi, mmu_idx, false);
196
+ v7m_stack_write(cpu, faddr, slo,
197
+ mmu_idx, STACK_NORMAL) &&
198
+ v7m_stack_write(cpu, faddr + 4, shi,
199
+ mmu_idx, STACK_NORMAL);
200
}
201
stacked_ok = stacked_ok &&
202
v7m_stack_write(cpu, frameptr + 0x60,
203
- vfp_get_fpscr(env), mmu_idx, false);
204
+ vfp_get_fpscr(env), mmu_idx, STACK_NORMAL);
205
if (cpacr_pass) {
206
for (i = 0; i < ((framesize == 0xa8) ? 32 : 16); i += 2) {
207
*aa32_vfp_dreg(env, i / 2) = 0;
208
--
36
--
209
2.20.1
37
2.34.1
210
38
211
39
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Reviewed-by: Markus Armbruster <armbru@redhat.com>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20190412165416.7977-11-philmd@redhat.com
6
Message-id: 20231020130331.50048-5-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
8
---
9
include/hw/net/ne2000-isa.h | 6 ++++++
9
hw/pcmcia/pxa2xx.c | 4 +---
10
1 file changed, 6 insertions(+)
10
1 file changed, 1 insertion(+), 3 deletions(-)
11
11
12
diff --git a/include/hw/net/ne2000-isa.h b/include/hw/net/ne2000-isa.h
12
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
13
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
14
--- a/include/hw/net/ne2000-isa.h
14
--- a/hw/pcmcia/pxa2xx.c
15
+++ b/include/hw/net/ne2000-isa.h
15
+++ b/hw/pcmcia/pxa2xx.c
16
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@ PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
17
* This work is licensed under the terms of the GNU GPL, version 2 or later.
17
{
18
* See the COPYING file in the top-level directory.
18
DeviceState *dev;
19
*/
19
20
+
20
- dev = qdev_new(TYPE_PXA2XX_PCMCIA);
21
+#ifndef HW_NET_NE2K_ISA_H
21
- sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
22
+#define HW_NET_NE2K_ISA_H
22
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
23
+
23
+ dev = sysbus_create_simple(TYPE_PXA2XX_PCMCIA, base, NULL);
24
#include "hw/hw.h"
24
25
#include "hw/qdev.h"
25
return PXA2XX_PCMCIA(dev);
26
#include "hw/isa/isa.h"
27
@@ -XXX,XX +XXX,XX @@ static inline ISADevice *isa_ne2000_init(ISABus *bus, int base, int irq,
28
}
29
return d;
30
}
26
}
31
+
32
+#endif
33
--
27
--
34
2.20.1
28
2.34.1
35
29
36
30
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
3
Reviewed-by: Thomas Huth <thuth@redhat.com>
4
Reviewed-by: Cédric Le Goater <clg@kaod.org>
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
5
Reviewed-by: Markus Armbruster <armbru@redhat.com>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Message-id: 20231020130331.50048-6-philmd@linaro.org
7
Message-id: 20190412165416.7977-2-philmd@redhat.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
hw/arm/aspeed.c | 13 +++++++++----
9
include/hw/arm/pxa.h | 2 --
11
1 file changed, 9 insertions(+), 4 deletions(-)
10
hw/arm/pxa2xx.c | 12 ++++++++----
11
hw/pcmcia/pxa2xx.c | 10 ----------
12
3 files changed, 8 insertions(+), 16 deletions(-)
12
13
13
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
14
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
14
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
15
--- a/hw/arm/aspeed.c
16
--- a/include/hw/arm/pxa.h
16
+++ b/hw/arm/aspeed.c
17
+++ b/include/hw/arm/pxa.h
17
@@ -XXX,XX +XXX,XX @@
18
@@ -XXX,XX +XXX,XX @@ void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
18
#include "hw/arm/aspeed_soc.h"
19
#define TYPE_PXA2XX_PCMCIA "pxa2xx-pcmcia"
19
#include "hw/boards.h"
20
OBJECT_DECLARE_SIMPLE_TYPE(PXA2xxPCMCIAState, PXA2XX_PCMCIA)
20
#include "hw/i2c/smbus_eeprom.h"
21
21
+#include "hw/misc/pca9552.h"
22
-PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
22
+#include "hw/misc/tmp105.h"
23
- hwaddr base);
23
#include "qemu/log.h"
24
int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card);
24
#include "sysemu/block-backend.h"
25
int pxa2xx_pcmcia_detach(void *opaque);
25
#include "hw/loader.h"
26
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
26
@@ -XXX,XX +XXX,XX @@ static void ast2500_evb_i2c_init(AspeedBoardState *bmc)
27
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
27
eeprom_buf);
28
index XXXXXXX..XXXXXXX 100644
28
29
--- a/hw/arm/pxa2xx.c
29
/* The AST2500 EVB expects a LM75 but a TMP105 is compatible */
30
+++ b/hw/arm/pxa2xx.c
30
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7), "tmp105", 0x4d);
31
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa270_init(unsigned int sdram_size, const char *cpu_type)
31
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 7),
32
sysbus_create_simple("sysbus-ohci", 0x4c000000,
32
+ TYPE_TMP105, 0x4d);
33
qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1));
33
34
34
/* The AST2500 EVB does not have an RTC. Let's pretend that one is
35
- s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
35
* plugged on the I2C bus header */
36
- s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
36
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
37
+ s->pcmcia[0] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
37
AspeedSoCState *soc = &bmc->soc;
38
+ 0x20000000, NULL));
38
uint8_t *eeprom_buf = g_malloc0(8 * 1024);
39
+ s->pcmcia[1] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
39
40
+ 0x30000000, NULL));
40
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), "pca9552", 0x60);
41
41
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 3), TYPE_PCA9552,
42
sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
42
+ 0x60);
43
qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
43
44
@@ -XXX,XX +XXX,XX @@ PXA2xxState *pxa255_init(unsigned int sdram_size)
44
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 4), "tmp423", 0x4c);
45
s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi");
45
i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 5), "tmp423", 0x4c);
46
}
46
47
47
/* The Witherspoon expects a TMP275 but a TMP105 is compatible */
48
- s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000);
48
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), "tmp105", 0x4a);
49
- s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000);
49
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 9), TYPE_TMP105,
50
+ s->pcmcia[0] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
50
+ 0x4a);
51
+ 0x20000000, NULL));
51
52
+ s->pcmcia[1] = PXA2XX_PCMCIA(sysbus_create_simple(TYPE_PXA2XX_PCMCIA,
52
/* The witherspoon board expects Epson RX8900 I2C RTC but a ds1338 is
53
+ 0x30000000, NULL));
53
* good enough */
54
54
@@ -XXX,XX +XXX,XX @@ static void witherspoon_bmc_i2c_init(AspeedBoardState *bmc)
55
sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000,
55
56
qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM));
56
smbus_eeprom_init_one(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), 0x51,
57
diff --git a/hw/pcmcia/pxa2xx.c b/hw/pcmcia/pxa2xx.c
57
eeprom_buf);
58
index XXXXXXX..XXXXXXX 100644
58
- i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), "pca9552",
59
--- a/hw/pcmcia/pxa2xx.c
59
+ i2c_create_slave(aspeed_i2c_get_bus(DEVICE(&soc->i2c), 11), TYPE_PCA9552,
60
+++ b/hw/pcmcia/pxa2xx.c
60
0x60);
61
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_pcmcia_set_irq(void *opaque, int line, int level)
62
qemu_set_irq(s->irq, level);
61
}
63
}
62
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);
63
--
78
--
64
2.20.1
79
2.34.1
65
80
66
81
diff view generated by jsdifflib
1
Add a new helper function which returns the MMU index to use
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
for v7M, where the caller specifies all of the security
3
state, privilege level and whether the execution priority
4
is negative, and reimplement the existing
5
arm_v7m_mmu_idx_for_secstate_and_priv() in terms of it.
6
2
7
We are going to need this for the lazy-FP-stacking code.
3
Factor reset code out of the DeviceRealize() handler.
8
4
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Thomas Huth <thuth@redhat.com>
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
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20190416125744.27770-21-peter.maydell@linaro.org
12
---
10
---
13
target/arm/cpu.h | 7 +++++++
11
hw/arm/pxa2xx_pic.c | 17 ++++++++++++-----
14
target/arm/helper.c | 14 +++++++++++---
12
1 file changed, 12 insertions(+), 5 deletions(-)
15
2 files changed, 18 insertions(+), 3 deletions(-)
16
13
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
18
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
16
--- a/hw/arm/pxa2xx_pic.c
20
+++ b/target/arm/cpu.h
17
+++ b/hw/arm/pxa2xx_pic.c
21
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
18
@@ -XXX,XX +XXX,XX @@ static int pxa2xx_pic_post_load(void *opaque, int version_id)
22
}
23
}
24
25
+/*
26
+ * Return the MMU index for a v7M CPU with all relevant information
27
+ * manually specified.
28
+ */
29
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
30
+ bool secstate, bool priv, bool negpri);
31
+
32
/* Return the MMU index for a v7M CPU in the specified security and
33
* privilege state.
34
*/
35
diff --git a/target/arm/helper.c b/target/arm/helper.c
36
index XXXXXXX..XXXXXXX 100644
37
--- a/target/arm/helper.c
38
+++ b/target/arm/helper.c
39
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
40
return 0;
19
return 0;
41
}
20
}
42
21
43
-ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
22
-DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
44
- bool secstate, bool priv)
23
+static void pxa2xx_pic_reset_hold(Object *obj)
45
+ARMMMUIdx arm_v7m_mmu_idx_all(CPUARMState *env,
46
+ bool secstate, bool priv, bool negpri)
47
{
24
{
48
ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
25
- DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
49
26
- PXA2xxPICState *s = PXA2XX_PIC(dev);
50
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
27
-
51
mmu_idx |= ARM_MMU_IDX_M_PRIV;
28
- s->cpu = cpu;
52
}
29
+ PXA2xxPICState *s = PXA2XX_PIC(obj);
53
30
54
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
31
s->int_pending[0] = 0;
55
+ if (negpri) {
32
s->int_pending[1] = 0;
56
mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
33
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
57
}
34
s->int_enabled[1] = 0;
58
35
s->is_fiq[0] = 0;
59
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
36
s->is_fiq[1] = 0;
60
return mmu_idx;
61
}
62
63
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
64
+ bool secstate, bool priv)
65
+{
66
+ bool negpri = armv7m_nvic_neg_prio_requested(env->nvic, secstate);
67
+
68
+ return arm_v7m_mmu_idx_all(env, secstate, priv, negpri);
69
+}
37
+}
70
+
38
+
71
/* Return the MMU index for a v7M CPU in the specified security state */
39
+DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
72
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
40
+{
41
+ DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
42
+ PXA2xxPICState *s = PXA2XX_PIC(dev);
43
+
44
+ s->cpu = cpu;
45
46
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
47
48
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pxa2xx_pic_regs = {
49
static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
73
{
50
{
51
DeviceClass *dc = DEVICE_CLASS(klass);
52
+ ResettableClass *rc = RESETTABLE_CLASS(klass);
53
54
dc->desc = "PXA2xx PIC";
55
dc->vmsd = &vmstate_pxa2xx_pic_regs;
56
+ rc->phases.hold = pxa2xx_pic_reset_hold;
57
}
58
59
static const TypeInfo pxa2xx_pic_info = {
74
--
60
--
75
2.20.1
61
2.34.1
76
62
77
63
diff view generated by jsdifflib
1
If the floating point extension is present, then the SG instruction
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
must clear the CONTROL_S.SFPA bit. Implement this.
3
2
4
(On a no-FPU system the bit will always be zero, so we don't need
3
QOM objects shouldn't access each other internals fields
5
to make the clearing of the bit conditional on ARM_FEATURE_VFP.)
4
except using the QOM API.
6
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-8-philmd@linaro.org
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-8-peter.maydell@linaro.org
10
---
11
---
11
target/arm/helper.c | 1 +
12
hw/arm/pxa2xx_pic.c | 11 ++++++++++-
12
1 file changed, 1 insertion(+)
13
1 file changed, 10 insertions(+), 1 deletion(-)
13
14
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
17
--- a/hw/arm/pxa2xx_pic.c
17
+++ b/target/arm/helper.c
18
+++ b/hw/arm/pxa2xx_pic.c
18
@@ -XXX,XX +XXX,XX @@ static bool v7m_handle_execute_nsc(ARMCPU *cpu)
19
@@ -XXX,XX +XXX,XX @@
19
qemu_log_mask(CPU_LOG_INT, "...really an SG instruction at 0x%08" PRIx32
20
#include "cpu.h"
20
", executing it\n", env->regs[15]);
21
#include "hw/arm/pxa.h"
21
env->regs[14] &= ~1;
22
#include "hw/sysbus.h"
22
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
23
+#include "hw/qdev-properties.h"
23
switch_v7m_security_state(env, true);
24
#include "migration/vmstate.h"
24
xpsr_write(env, 0, XPSR_IT);
25
#include "qom/object.h"
25
env->regs[15] += 4;
26
#include "target/arm/cpregs.h"
27
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
28
DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
29
PXA2xxPICState *s = PXA2XX_PIC(dev);
30
31
- s->cpu = cpu;
32
+ object_property_set_link(OBJECT(dev), "arm-cpu",
33
+ OBJECT(cpu), &error_abort);
34
35
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
36
37
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pxa2xx_pic_regs = {
38
},
39
};
40
41
+static Property pxa2xx_pic_properties[] = {
42
+ DEFINE_PROP_LINK("arm-cpu", PXA2xxPICState, cpu,
43
+ TYPE_ARM_CPU, ARMCPU *),
44
+ DEFINE_PROP_END_OF_LIST(),
45
+};
46
+
47
static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
48
{
49
DeviceClass *dc = DEVICE_CLASS(klass);
50
ResettableClass *rc = RESETTABLE_CLASS(klass);
51
52
+ device_class_set_props(dc, pxa2xx_pic_properties);
53
dc->desc = "PXA2xx PIC";
54
dc->vmsd = &vmstate_pxa2xx_pic_regs;
55
rc->phases.hold = pxa2xx_pic_reset_hold;
26
--
56
--
27
2.20.1
57
2.34.1
28
58
29
59
diff view generated by jsdifflib
1
The only "system register" that M-profile floating point exposes
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
via the VMRS/VMRS instructions is FPSCR, and it does not have
3
the odd special case for rd==15. Add a check to ensure we only
4
expose FPSCR.
5
2
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-5-peter.maydell@linaro.org
9
---
8
---
10
target/arm/translate.c | 19 +++++++++++++++++--
9
hw/arm/pxa2xx_pic.c | 16 ++++++++++------
11
1 file changed, 17 insertions(+), 2 deletions(-)
10
1 file changed, 10 insertions(+), 6 deletions(-)
12
11
13
diff --git a/target/arm/translate.c b/target/arm/translate.c
12
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
14
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate.c
14
--- a/hw/arm/pxa2xx_pic.c
16
+++ b/target/arm/translate.c
15
+++ b/hw/arm/pxa2xx_pic.c
17
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
16
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_pic_reset_hold(Object *obj)
18
}
17
DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
19
}
18
{
20
} else { /* !dp */
19
DeviceState *dev = qdev_new(TYPE_PXA2XX_PIC);
21
+ bool is_sysreg;
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);
22
+
27
+
23
if ((insn & 0x6f) != 0x00)
28
+ return dev;
24
return 1;
29
+}
25
rn = VFP_SREG_N(insn);
26
+
30
+
27
+ is_sysreg = extract32(insn, 21, 1);
31
+static void pxa2xx_pic_realize(DeviceState *dev, Error **errp)
28
+
32
+{
29
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
33
+ PXA2xxPICState *s = PXA2XX_PIC(dev);
30
+ /*
34
31
+ * The only M-profile VFP vmrs/vmsr sysreg is FPSCR.
35
qdev_init_gpio_in(dev, pxa2xx_pic_set_irq, PXA2XX_PIC_SRCS);
32
+ * Writes to R15 are UNPREDICTABLE; we choose to undef.
36
33
+ */
37
@@ -XXX,XX +XXX,XX @@ DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu)
34
+ if (is_sysreg && (rd == 15 || (rn >> 1) != ARM_VFP_FPSCR)) {
38
memory_region_init_io(&s->iomem, OBJECT(s), &pxa2xx_pic_ops, s,
35
+ return 1;
39
"pxa2xx-pic", 0x00100000);
36
+ }
40
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem);
37
+ }
41
- sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
38
+
42
39
if (insn & ARM_CP_RW_BIT) {
43
/* Enable IC coprocessor access. */
40
/* vfp->arm */
44
- define_arm_cp_regs_with_opaque(cpu, pxa_pic_cp_reginfo, s);
41
- if (insn & (1 << 21)) {
45
-
42
+ if (is_sysreg) {
46
- return dev;
43
/* system register */
47
+ define_arm_cp_regs_with_opaque(s->cpu, pxa_pic_cp_reginfo, s);
44
rn >>= 1;
48
}
45
49
46
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
50
static const VMStateDescription vmstate_pxa2xx_pic_regs = {
47
}
51
@@ -XXX,XX +XXX,XX @@ static void pxa2xx_pic_class_init(ObjectClass *klass, void *data)
48
} else {
52
ResettableClass *rc = RESETTABLE_CLASS(klass);
49
/* arm->vfp */
53
50
- if (insn & (1 << 21)) {
54
device_class_set_props(dc, pxa2xx_pic_properties);
51
+ if (is_sysreg) {
55
+ dc->realize = pxa2xx_pic_realize;
52
rn >>= 1;
56
dc->desc = "PXA2xx PIC";
53
/* system register */
57
dc->vmsd = &vmstate_pxa2xx_pic_regs;
54
switch (rn) {
58
rc->phases.hold = pxa2xx_pic_reset_hold;
55
--
59
--
56
2.20.1
60
2.34.1
57
61
58
62
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
qbus_new(), called in i2c_init_bus(), should not be called
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
on unrealized device.
5
Message-id: 20190412165416.7977-8-philmd@redhat.com
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
11
---
8
include/hw/devices.h | 3 ---
12
hw/arm/pxa2xx.c | 5 +++--
9
include/hw/input/gamepad.h | 19 +++++++++++++++++++
13
1 file changed, 3 insertions(+), 2 deletions(-)
10
hw/arm/stellaris.c | 2 +-
11
hw/input/stellaris_input.c | 2 +-
12
MAINTAINERS | 1 +
13
5 files changed, 22 insertions(+), 5 deletions(-)
14
create mode 100644 include/hw/input/gamepad.h
15
14
16
diff --git a/include/hw/devices.h b/include/hw/devices.h
15
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
17
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
18
--- a/include/hw/devices.h
17
--- a/hw/arm/pxa2xx.c
19
+++ b/include/hw/devices.h
18
+++ b/hw/arm/pxa2xx.c
20
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav);
19
@@ -XXX,XX +XXX,XX @@ PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
21
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
20
qdev_prop_set_uint32(dev, "size", region_size + 1);
22
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
21
qdev_prop_set_uint32(dev, "offset", base & region_size);
23
22
24
-/* stellaris_input.c */
23
+ /* FIXME: Should the slave device really be on a separate bus? */
25
-void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
24
+ i2cbus = i2c_init_bus(dev, "dummy");
26
-
27
#endif
28
diff --git a/include/hw/input/gamepad.h b/include/hw/input/gamepad.h
29
new file mode 100644
30
index XXXXXXX..XXXXXXX
31
--- /dev/null
32
+++ b/include/hw/input/gamepad.h
33
@@ -XXX,XX +XXX,XX @@
34
+/*
35
+ * Gamepad style buttons connected to IRQ/GPIO lines
36
+ *
37
+ * Copyright (c) 2007 CodeSourcery.
38
+ * Written by Paul Brook
39
+ *
40
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
41
+ * See the COPYING file in the top-level directory.
42
+ */
43
+
25
+
44
+#ifndef HW_INPUT_GAMEPAD_H
26
i2c_dev = SYS_BUS_DEVICE(dev);
45
+#define HW_INPUT_GAMEPAD_H
27
sysbus_realize_and_unref(i2c_dev, &error_fatal);
46
+
28
sysbus_mmio_map(i2c_dev, 0, base & ~region_size);
47
+#include "hw/irq.h"
29
sysbus_connect_irq(i2c_dev, 0, irq);
48
+
30
49
+/* stellaris_input.c */
31
s = PXA2XX_I2C(i2c_dev);
50
+void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
32
- /* FIXME: Should the slave device really be on a separate bus? */
51
+
33
- i2cbus = i2c_init_bus(dev, "dummy");
52
+#endif
34
s->slave = PXA2XX_I2C_SLAVE(i2c_slave_create_simple(i2cbus,
53
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
35
TYPE_PXA2XX_I2C_SLAVE,
54
index XXXXXXX..XXXXXXX 100644
36
0));
55
--- a/hw/arm/stellaris.c
56
+++ b/hw/arm/stellaris.c
57
@@ -XXX,XX +XXX,XX @@
58
#include "hw/sysbus.h"
59
#include "hw/ssi/ssi.h"
60
#include "hw/arm/arm.h"
61
-#include "hw/devices.h"
62
#include "qemu/timer.h"
63
#include "hw/i2c/i2c.h"
64
#include "net/net.h"
65
@@ -XXX,XX +XXX,XX @@
66
#include "sysemu/sysemu.h"
67
#include "hw/arm/armv7m.h"
68
#include "hw/char/pl011.h"
69
+#include "hw/input/gamepad.h"
70
#include "hw/watchdog/cmsdk-apb-watchdog.h"
71
#include "hw/misc/unimp.h"
72
#include "cpu.h"
73
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/hw/input/stellaris_input.c
76
+++ b/hw/input/stellaris_input.c
77
@@ -XXX,XX +XXX,XX @@
78
*/
79
#include "qemu/osdep.h"
80
#include "hw/hw.h"
81
-#include "hw/devices.h"
82
+#include "hw/input/gamepad.h"
83
#include "ui/console.h"
84
85
typedef struct {
86
diff --git a/MAINTAINERS b/MAINTAINERS
87
index XXXXXXX..XXXXXXX 100644
88
--- a/MAINTAINERS
89
+++ b/MAINTAINERS
90
@@ -XXX,XX +XXX,XX @@ M: Peter Maydell <peter.maydell@linaro.org>
91
L: qemu-arm@nongnu.org
92
S: Maintained
93
F: hw/*/stellaris*
94
+F: include/hw/input/gamepad.h
95
96
Versatile Express
97
M: Peter Maydell <peter.maydell@linaro.org>
98
--
37
--
99
2.20.1
38
2.34.1
100
39
101
40
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Reviewed-by: Markus Armbruster <armbru@redhat.com>
3
Prefer using a well known local first CPU rather than a global one.
4
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
4
5
Message-id: 20190412165416.7977-12-philmd@redhat.com
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
include/hw/net/lan9118.h | 2 ++
10
hw/arm/bananapi_m2u.c | 2 +-
9
hw/arm/exynos4_boards.c | 3 ++-
11
hw/arm/exynos4_boards.c | 7 ++++---
10
hw/arm/mps2-tz.c | 3 ++-
12
hw/arm/orangepi.c | 2 +-
11
hw/net/lan9118.c | 1 -
13
hw/arm/realview.c | 2 +-
12
4 files changed, 6 insertions(+), 3 deletions(-)
14
hw/arm/xilinx_zynq.c | 2 +-
15
5 files changed, 8 insertions(+), 7 deletions(-)
13
16
14
diff --git a/include/hw/net/lan9118.h b/include/hw/net/lan9118.h
17
diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c
15
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
16
--- a/include/hw/net/lan9118.h
19
--- a/hw/arm/bananapi_m2u.c
17
+++ b/include/hw/net/lan9118.h
20
+++ b/hw/arm/bananapi_m2u.c
18
@@ -XXX,XX +XXX,XX @@
21
@@ -XXX,XX +XXX,XX @@ static void bpim2u_init(MachineState *machine)
19
#include "hw/irq.h"
22
bpim2u_binfo.loader_start = r40->memmap[AW_R40_DEV_SDRAM];
20
#include "net/net.h"
23
bpim2u_binfo.ram_size = machine->ram_size;
21
24
bpim2u_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
22
+#define TYPE_LAN9118 "lan9118"
25
- arm_load_kernel(ARM_CPU(first_cpu), machine, &bpim2u_binfo);
23
+
26
+ arm_load_kernel(&r40->cpus[0], machine, &bpim2u_binfo);
24
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
27
}
25
28
26
#endif
29
static void bpim2u_machine_init(MachineClass *mc)
27
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
30
diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c
28
index XXXXXXX..XXXXXXX 100644
31
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/exynos4_boards.c
32
--- a/hw/arm/exynos4_boards.c
30
+++ b/hw/arm/exynos4_boards.c
33
+++ b/hw/arm/exynos4_boards.c
31
@@ -XXX,XX +XXX,XX @@
34
@@ -XXX,XX +XXX,XX @@ exynos4_boards_init_common(MachineState *machine,
32
#include "hw/arm/arm.h"
35
33
#include "exec/address-spaces.h"
36
static void nuri_init(MachineState *machine)
34
#include "hw/arm/exynos4210.h"
37
{
35
+#include "hw/net/lan9118.h"
38
- exynos4_boards_init_common(machine, EXYNOS4_BOARD_NURI);
36
#include "hw/boards.h"
39
+ Exynos4BoardState *s = exynos4_boards_init_common(machine,
37
40
+ EXYNOS4_BOARD_NURI);
38
#undef DEBUG
41
39
@@ -XXX,XX +XXX,XX @@ static void lan9215_init(uint32_t base, qemu_irq irq)
42
- arm_load_kernel(ARM_CPU(first_cpu), machine, &exynos4_board_binfo);
40
/* This should be a 9215 but the 9118 is close enough */
43
+ arm_load_kernel(s->soc.cpu[0], machine, &exynos4_board_binfo);
41
if (nd_table[0].used) {
44
}
42
qemu_check_nic_model(&nd_table[0], "lan9118");
45
43
- dev = qdev_create(NULL, "lan9118");
46
static void smdkc210_init(MachineState *machine)
44
+ dev = qdev_create(NULL, TYPE_LAN9118);
47
@@ -XXX,XX +XXX,XX @@ static void smdkc210_init(MachineState *machine)
45
qdev_set_nic_properties(dev, &nd_table[0]);
48
46
qdev_prop_set_uint32(dev, "mode_16bit", 1);
49
lan9215_init(SMDK_LAN9118_BASE_ADDR,
47
qdev_init_nofail(dev);
50
qemu_irq_invert(s->soc.irq_table[exynos4210_get_irq(37, 1)]));
48
diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c
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
49
index XXXXXXX..XXXXXXX 100644
57
index XXXXXXX..XXXXXXX 100644
50
--- a/hw/arm/mps2-tz.c
58
--- a/hw/arm/orangepi.c
51
+++ b/hw/arm/mps2-tz.c
59
+++ b/hw/arm/orangepi.c
52
@@ -XXX,XX +XXX,XX @@
60
@@ -XXX,XX +XXX,XX @@ static void orangepi_init(MachineState *machine)
53
#include "hw/arm/armsse.h"
61
orangepi_binfo.loader_start = h3->memmap[AW_H3_DEV_SDRAM];
54
#include "hw/dma/pl080.h"
62
orangepi_binfo.ram_size = machine->ram_size;
55
#include "hw/ssi/pl022.h"
63
orangepi_binfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
56
+#include "hw/net/lan9118.h"
64
- arm_load_kernel(ARM_CPU(first_cpu), machine, &orangepi_binfo);
57
#include "net/net.h"
65
+ arm_load_kernel(&h3->cpus[0], machine, &orangepi_binfo);
58
#include "hw/core/split-irq.h"
66
}
59
67
60
@@ -XXX,XX +XXX,XX @@ static MemoryRegion *make_eth_dev(MPS2TZMachineState *mms, void *opaque,
68
static void orangepi_machine_init(MachineClass *mc)
61
* except that it doesn't support the checksum-offload feature.
69
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
62
*/
63
qemu_check_nic_model(nd, "lan9118");
64
- mms->lan9118 = qdev_create(NULL, "lan9118");
65
+ mms->lan9118 = qdev_create(NULL, TYPE_LAN9118);
66
qdev_set_nic_properties(mms->lan9118, nd);
67
qdev_init_nofail(mms->lan9118);
68
69
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
70
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
71
--- a/hw/net/lan9118.c
71
--- a/hw/arm/realview.c
72
+++ b/hw/net/lan9118.c
72
+++ b/hw/arm/realview.c
73
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_lan9118_packet = {
73
@@ -XXX,XX +XXX,XX @@ static void realview_init(MachineState *machine,
74
}
74
realview_binfo.ram_size = ram_size;
75
};
75
realview_binfo.board_id = realview_board_id[board_type];
76
76
realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);
77
-#define TYPE_LAN9118 "lan9118"
77
- arm_load_kernel(ARM_CPU(first_cpu), machine, &realview_binfo);
78
#define LAN9118(obj) OBJECT_CHECK(lan9118_state, (obj), TYPE_LAN9118)
78
+ arm_load_kernel(cpu, machine, &realview_binfo);
79
79
}
80
typedef struct {
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)
81
--
95
--
82
2.20.1
96
2.34.1
83
97
84
98
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Glenn Miles <milesg@linux.vnet.ibm.com>
2
2
3
No code used the tc6393xb_gpio_in_get() and tc6393xb_gpio_out_set()
3
Testing of the LED state showed that when the LED polarity was
4
functions since their introduction in commit 88d2c950b002. Time to
4
set to GPIO_POLARITY_ACTIVE_LOW and a low logic value was set on
5
remove them.
5
the input GPIO of the LED, the LED was being turn off when it was
6
expected to be turned on.
6
7
7
Suggested-by: Markus Armbruster <armbru@redhat.com>
8
Fixes: ddb67f6402 ("hw/misc/led: Allow connecting from GPIO output")
8
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
9
Signed-off-by: Glenn Miles <milesg@linux.vnet.ibm.com>
9
Message-id: 20190412165416.7977-4-philmd@redhat.com
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
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>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
15
---
13
include/hw/devices.h | 3 ---
16
hw/misc/led.c | 2 +-
14
hw/display/tc6393xb.c | 16 ----------------
17
1 file changed, 1 insertion(+), 1 deletion(-)
15
2 files changed, 19 deletions(-)
16
18
17
diff --git a/include/hw/devices.h b/include/hw/devices.h
19
diff --git a/hw/misc/led.c b/hw/misc/led.c
18
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
19
--- a/include/hw/devices.h
21
--- a/hw/misc/led.c
20
+++ b/include/hw/devices.h
22
+++ b/hw/misc/led.c
21
@@ -XXX,XX +XXX,XX @@ void retu_key_event(void *retu, int state);
23
@@ -XXX,XX +XXX,XX @@ static void led_set_state_gpio_handler(void *opaque, int line, int new_state)
22
typedef struct TC6393xbState TC6393xbState;
24
LEDState *s = LED(opaque);
23
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
25
24
uint32_t base, qemu_irq irq);
26
assert(line == 0);
25
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
27
- led_set_state(s, !!new_state != s->gpio_active_high);
26
- qemu_irq handler);
28
+ led_set_state(s, !!new_state == s->gpio_active_high);
27
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
28
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
29
30
#endif
31
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/hw/display/tc6393xb.c
34
+++ b/hw/display/tc6393xb.c
35
@@ -XXX,XX +XXX,XX @@ struct TC6393xbState {
36
blanked : 1;
37
};
38
39
-qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s)
40
-{
41
- return s->gpio_in;
42
-}
43
-
44
static void tc6393xb_gpio_set(void *opaque, int line, int level)
45
{
46
// TC6393xbState *s = opaque;
47
@@ -XXX,XX +XXX,XX @@ static void tc6393xb_gpio_set(void *opaque, int line, int level)
48
// FIXME: how does the chip reflect the GPIO input level change?
49
}
29
}
50
30
51
-void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
31
static void led_reset(DeviceState *dev)
52
- qemu_irq handler)
53
-{
54
- if (line >= TC6393XB_GPIOS) {
55
- fprintf(stderr, "TC6393xb: no GPIO pin %d\n", line);
56
- return;
57
- }
58
-
59
- s->handler[line] = handler;
60
-}
61
-
62
static void tc6393xb_gpio_handler_update(TC6393xbState *s)
63
{
64
uint32_t level, diff;
65
--
32
--
66
2.20.1
33
2.34.1
67
34
68
35
diff view generated by jsdifflib
1
The M-profile CONTROL register has two bits -- SFPA and FPCA --
1
From: Luc Michel <luc.michel@amd.com>
2
which relate to floating-point support, and should be RES0 otherwise.
3
Handle them correctly in the MSR/MRS register access code.
4
Neither is banked between security states, so they are stored
5
in v7m.control[M_REG_S] regardless of current security state.
6
2
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
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-9-peter.maydell@linaro.org
10
---
10
---
11
target/arm/helper.c | 57 ++++++++++++++++++++++++++++++++++++++-------
11
hw/net/cadence_gem.c | 527 +++++++++++++++++++++----------------------
12
1 file changed, 49 insertions(+), 8 deletions(-)
12
1 file changed, 261 insertions(+), 266 deletions(-)
13
13
14
diff --git a/target/arm/helper.c b/target/arm/helper.c
14
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
15
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/helper.c
16
--- a/hw/net/cadence_gem.c
17
+++ b/target/arm/helper.c
17
+++ b/hw/net/cadence_gem.c
18
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
18
@@ -XXX,XX +XXX,XX @@
19
return xpsr_read(env) & mask;
19
#include "hw/irq.h"
20
break;
20
#include "hw/net/cadence_gem.h"
21
case 20: /* CONTROL */
21
#include "hw/qdev-properties.h"
22
- return env->v7m.control[env->v7m.secure];
22
+#include "hw/registerfields.h"
23
+ {
23
#include "migration/vmstate.h"
24
+ uint32_t value = env->v7m.control[env->v7m.secure];
24
#include "qapi/error.h"
25
+ if (!env->v7m.secure) {
25
#include "qemu/log.h"
26
+ /* SFPA is RAZ/WI from NS; FPCA is stored in the M_REG_S bank */
26
@@ -XXX,XX +XXX,XX @@
27
+ value |= env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK;
27
} \
28
+ }
28
} while (0)
29
+ return value;
29
30
+ }
30
-#define GEM_NWCTRL (0x00000000 / 4) /* Network Control reg */
31
case 0x94: /* CONTROL_NS */
31
-#define GEM_NWCFG (0x00000004 / 4) /* Network Config reg */
32
/* We have to handle this here because unprivileged Secure code
32
-#define GEM_NWSTATUS (0x00000008 / 4) /* Network Status reg */
33
* can read the NS CONTROL register.
33
-#define GEM_USERIO (0x0000000C / 4) /* User IO reg */
34
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(v7m_mrs)(CPUARMState *env, uint32_t reg)
34
-#define GEM_DMACFG (0x00000010 / 4) /* DMA Control reg */
35
if (!env->v7m.secure) {
35
-#define GEM_TXSTATUS (0x00000014 / 4) /* TX Status reg */
36
return 0;
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;
37
}
519
}
38
- return env->v7m.control[M_REG_NS];
520
return GEM_RX_BROADCAST_ACCEPT;
39
+ return env->v7m.control[M_REG_NS] |
521
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
40
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK);
522
41
}
523
/* Accept packets -w- hash match? */
42
524
is_mc = is_multicast_ether_addr(packet);
43
if (el == 0) {
525
- if ((is_mc && (s->regs[GEM_NWCFG] & GEM_NWCFG_MCAST_HASH)) ||
44
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
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)
45
*/
632
*/
46
uint32_t mask = extract32(maskreg, 8, 4);
633
- rxbuf_offset = (s->regs[GEM_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>
47
uint32_t reg = extract32(maskreg, 0, 8);
634
+ rxbuf_offset = (s->regs[R_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>
48
+ int cur_el = arm_current_el(env);
635
GEM_NWCFG_BUFF_OFST_S;
49
636
50
- if (arm_current_el(env) == 0 && reg > 7) {
637
/* The configure size of each receive buffer. Determines how many
51
- /* only xPSR sub-fields may be written by unprivileged */
638
* buffers needed to hold this packet.
52
+ if (cur_el == 0 && reg > 7 && reg != 20) {
639
*/
53
+ /*
640
- rxbufsize = ((s->regs[GEM_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>
54
+ * only xPSR sub-fields and CONTROL.SFPA may be written by
641
+ rxbufsize = ((s->regs[R_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>
55
+ * unprivileged code
642
GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;
56
+ */
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)) {
57
return;
723
return;
58
}
724
}
59
725
60
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
726
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
61
env->v7m.control[M_REG_NS] &= ~R_V7M_CONTROL_NPRIV_MASK;
727
while (tx_desc_get_used(desc) == 0) {
62
env->v7m.control[M_REG_NS] |= val & R_V7M_CONTROL_NPRIV_MASK;
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;
63
}
733
}
64
+ /*
734
print_gem_tx_desc(desc, q);
65
+ * SFPA is RAZ/WI from NS. FPCA is RO if NSACR.CP10 == 0,
735
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
66
+ * RES0 if the FPU is not present, and is stored in the S bank
736
}
67
+ */
737
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
68
+ if (arm_feature(env, ARM_FEATURE_VFP) &&
738
69
+ extract32(env->v7m.nsacr, 10, 1)) {
739
- s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
70
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
740
+ s->regs[R_TXSTATUS] |= GEM_TXSTATUS_TXCMPL;
71
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
741
gem_set_isr(s, q, GEM_INT_TXCMPL);
72
+ }
742
73
return;
743
/* Handle interrupt consequences */
74
case 0x98: /* SP_NS */
744
gem_update_int_status(s);
75
{
745
76
@@ -XXX,XX +XXX,XX @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
746
/* Is checksum offload enabled? */
77
env->v7m.faultmask[env->v7m.secure] = val & 1;
747
- if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
78
break;
748
+ if (s->regs[R_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) {
79
case 20: /* CONTROL */
749
net_checksum_calculate(s->tx_packet, total_bytes, CSUM_ALL);
80
- /* Writing to the SPSEL bit only has an effect if we are in
750
}
81
+ /*
751
82
+ * Writing to the SPSEL bit only has an effect if we are in
752
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
83
* thread mode; other bits can be updated by any privileged code.
753
gem_transmit_updatestats(s, s->tx_packet, total_bytes);
84
* write_v7m_control_spsel() deals with updating the SPSEL bit in
754
85
* env->v7m.control, so we only need update the others.
755
/* Send the packet somewhere */
86
* For v7M, we must just ignore explicit writes to SPSEL in handler
756
- if (s->phy_loop || (s->regs[GEM_NWCTRL] &
87
* mode; for v8M the write is permitted but will have no effect.
757
+ if (s->phy_loop || (s->regs[R_NWCTRL] &
88
+ * All these bits are writes-ignored from non-privileged code,
758
GEM_NWCTRL_LOCALLOOP)) {
89
+ * except for SFPA.
759
qemu_receive_packet(qemu_get_queue(s->nic), s->tx_packet,
90
*/
760
total_bytes);
91
- if (arm_feature(env, ARM_FEATURE_V8) ||
761
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
92
- !arm_v7m_is_handler_mode(env)) {
762
93
+ if (cur_el > 0 && (arm_feature(env, ARM_FEATURE_V8) ||
763
/* read next descriptor */
94
+ !arm_v7m_is_handler_mode(env))) {
764
if (tx_desc_get_wrap(desc)) {
95
write_v7m_control_spsel(env, (val & R_V7M_CONTROL_SPSEL_MASK) != 0);
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)
96
}
774
}
97
- if (arm_feature(env, ARM_FEATURE_M_MAIN)) {
775
98
+ if (cur_el > 0 && arm_feature(env, ARM_FEATURE_M_MAIN)) {
776
if (tx_desc_get_used(desc)) {
99
env->v7m.control[env->v7m.secure] &= ~R_V7M_CONTROL_NPRIV_MASK;
777
- s->regs[GEM_TXSTATUS] |= GEM_TXSTATUS_USED;
100
env->v7m.control[env->v7m.secure] |= val & R_V7M_CONTROL_NPRIV_MASK;
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,
101
}
854
}
102
+ if (arm_feature(env, ARM_FEATURE_VFP)) {
855
break;
103
+ /*
856
104
+ * SFPA is RAZ/WI from NS or if no FPU.
857
- case GEM_TXSTATUS:
105
+ * FPCA is RO if NSACR.CP10 == 0, RES0 if the FPU is not present.
858
+ case R_TXSTATUS:
106
+ * Both are stored in the S bank.
859
gem_update_int_status(s);
107
+ */
860
break;
108
+ if (env->v7m.secure) {
861
- case GEM_RXQBASE:
109
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_SFPA_MASK;
862
+ case R_RXQBASE:
110
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_SFPA_MASK;
863
s->rx_desc_addr[0] = val;
111
+ }
864
break;
112
+ if (cur_el > 0 &&
865
- case GEM_RECEIVE_Q1_PTR ... GEM_RECEIVE_Q7_PTR:
113
+ (env->v7m.secure || !arm_feature(env, ARM_FEATURE_M_SECURITY) ||
866
- s->rx_desc_addr[offset - GEM_RECEIVE_Q1_PTR + 1] = val;
114
+ extract32(env->v7m.nsacr, 10, 1))) {
867
+ case R_RECEIVE_Q1_PTR ... R_RECEIVE_Q7_PTR:
115
+ env->v7m.control[M_REG_S] &= ~R_V7M_CONTROL_FPCA_MASK;
868
+ s->rx_desc_addr[offset - R_RECEIVE_Q1_PTR + 1] = val;
116
+ env->v7m.control[M_REG_S] |= val & R_V7M_CONTROL_FPCA_MASK;
869
break;
117
+ }
870
- case GEM_TXQBASE:
118
+ }
871
+ case R_TXQBASE:
119
break;
872
s->tx_desc_addr[0] = val;
120
default:
873
break;
121
bad_reg:
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
122
--
939
--
123
2.20.1
940
2.34.1
124
125
diff view generated by jsdifflib
1
The M-profile FPCCR.S bit indicates the security status of
1
From: Luc Michel <luc.michel@amd.com>
2
the floating point context. In the pseudocode ExecuteFPCheck()
3
function it is unconditionally set to match the current
4
security state whenever a floating point instruction is
5
executed.
6
2
7
Implement this by adding a new TB flag which tracks whether
3
Describe screening registers fields using the FIELD macros.
8
FPCCR.S is different from the current security state, so
9
that we only need to emit the code to update it in the
10
less-common case when it is not already set correctly.
11
4
12
Note that we will add the handling for the other work done
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
13
by ExecuteFPCheck() in later commits.
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(-)
14
12
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
16
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
17
Message-id: 20190416125744.27770-19-peter.maydell@linaro.org
18
---
19
target/arm/cpu.h | 2 ++
20
target/arm/translate.h | 1 +
21
target/arm/helper.c | 5 +++++
22
target/arm/translate.c | 20 ++++++++++++++++++++
23
4 files changed, 28 insertions(+)
24
25
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
26
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
27
--- a/target/arm/cpu.h
15
--- a/hw/net/cadence_gem.c
28
+++ b/target/arm/cpu.h
16
+++ b/hw/net/cadence_gem.c
29
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
17
@@ -XXX,XX +XXX,XX @@ REG32(INT_Q1_DISABLE, 0x620)
30
FIELD(TBFLAG_A32, VFPEN, 7, 1)
18
REG32(INT_Q7_DISABLE, 0x638)
31
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
19
32
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
20
REG32(SCREENING_TYPE1_REG0, 0x500)
33
+/* For M profile only, set if FPCCR.S does not match current security state */
21
-
34
+FIELD(TBFLAG_A32, FPCCR_S_WRONG, 20, 1)
22
-#define GEM_ST1R_UDP_PORT_MATCH_ENABLE (1 << 29)
35
/* For M profile only, Handler (ie not Thread) mode */
23
-#define GEM_ST1R_DSTC_ENABLE (1 << 28)
36
FIELD(TBFLAG_A32, HANDLER, 21, 1)
24
-#define GEM_ST1R_UDP_PORT_MATCH_SHIFT (12)
37
/* For M profile only, whether we should generate stack-limit checks */
25
-#define GEM_ST1R_UDP_PORT_MATCH_WIDTH (27 - GEM_ST1R_UDP_PORT_MATCH_SHIFT + 1)
38
diff --git a/target/arm/translate.h b/target/arm/translate.h
26
-#define GEM_ST1R_DSTC_MATCH_SHIFT (4)
39
index XXXXXXX..XXXXXXX 100644
27
-#define GEM_ST1R_DSTC_MATCH_WIDTH (11 - GEM_ST1R_DSTC_MATCH_SHIFT + 1)
40
--- a/target/arm/translate.h
28
-#define GEM_ST1R_QUEUE_SHIFT (0)
41
+++ b/target/arm/translate.h
29
-#define GEM_ST1R_QUEUE_WIDTH (3 - GEM_ST1R_QUEUE_SHIFT + 1)
42
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
30
+ FIELD(SCREENING_TYPE1_REG0, QUEUE_NUM, 0, 4)
43
bool v7m_handler_mode;
31
+ FIELD(SCREENING_TYPE1_REG0, DSTC_MATCH, 4, 8)
44
bool v8m_secure; /* true if v8M and we're in Secure mode */
32
+ FIELD(SCREENING_TYPE1_REG0, UDP_PORT_MATCH, 12, 16)
45
bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
33
+ FIELD(SCREENING_TYPE1_REG0, DSTC_ENABLE, 28, 1)
46
+ bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
34
+ FIELD(SCREENING_TYPE1_REG0, UDP_PORT_MATCH_EN, 29, 1)
47
/* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
35
+ FIELD(SCREENING_TYPE1_REG0, DROP_ON_MATCH, 30, 1)
48
* so that top level loop can generate correct syndrome information.
36
49
*/
37
REG32(SCREENING_TYPE2_REG0, 0x540)
50
diff --git a/target/arm/helper.c b/target/arm/helper.c
38
-
51
index XXXXXXX..XXXXXXX 100644
39
-#define GEM_ST2R_COMPARE_A_ENABLE (1 << 18)
52
--- a/target/arm/helper.c
40
-#define GEM_ST2R_COMPARE_A_SHIFT (13)
53
+++ b/target/arm/helper.c
41
-#define GEM_ST2R_COMPARE_WIDTH (17 - GEM_ST2R_COMPARE_A_SHIFT + 1)
54
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
42
-#define GEM_ST2R_ETHERTYPE_ENABLE (1 << 12)
55
flags = FIELD_DP32(flags, TBFLAG_A32, STACKCHECK, 1);
43
-#define GEM_ST2R_ETHERTYPE_INDEX_SHIFT (9)
56
}
44
-#define GEM_ST2R_ETHERTYPE_INDEX_WIDTH (11 - GEM_ST2R_ETHERTYPE_INDEX_SHIFT \
57
45
- + 1)
58
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY) &&
46
-#define GEM_ST2R_QUEUE_SHIFT (0)
59
+ FIELD_EX32(env->v7m.fpccr[M_REG_S], V7M_FPCCR, S) != env->v7m.secure) {
47
-#define GEM_ST2R_QUEUE_WIDTH (3 - GEM_ST2R_QUEUE_SHIFT + 1)
60
+ flags = FIELD_DP32(flags, TBFLAG_A32, FPCCR_S_WRONG, 1);
48
+ FIELD(SCREENING_TYPE2_REG0, QUEUE_NUM, 0, 4)
61
+ }
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)
62
+
71
+
63
*pflags = flags;
72
+REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
64
*cs_base = 0;
73
+ FIELD(TYPE2_COMPARE_0_WORD_1, OFFSET_VALUE, 0, 7)
65
}
74
+ FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET, 7, 2)
66
diff --git a/target/arm/translate.c b/target/arm/translate.c
75
+ FIELD(TYPE2_COMPARE_0_WORD_1, DISABLE_MASK, 9, 1)
67
index XXXXXXX..XXXXXXX 100644
76
+ FIELD(TYPE2_COMPARE_0_WORD_1, COMPARE_VLAN_ID, 10, 1)
68
--- a/target/arm/translate.c
77
69
+++ b/target/arm/translate.c
78
/*****************************************/
70
@@ -XXX,XX +XXX,XX @@ static int disas_vfp_insn(DisasContext *s, uint32_t insn)
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);
71
}
112
}
72
}
113
}
73
114
74
+ if (arm_dc_feature(s, ARM_FEATURE_M)) {
115
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
75
+ /* Handle M-profile lazy FP state mechanics */
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
}
76
+
147
+
77
+ /* Update ownership of FP context: set FPCCR.S to match current state */
148
if (cr_idx > s->num_type2_screeners) {
78
+ if (s->v8m_fpccr_s_wrong) {
149
qemu_log_mask(LOG_GUEST_ERROR, "Out of range compare "
79
+ TCGv_i32 tmp;
150
"register index: %d\n", cr_idx);
80
+
151
}
81
+ tmp = load_cpu_field(v7m.fpccr[M_REG_S]);
152
82
+ if (s->v8m_secure) {
153
cr0 = s->regs[R_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2];
83
+ tcg_gen_ori_i32(tmp, tmp, R_V7M_FPCCR_S_MASK);
154
- cr1 = s->regs[R_TYPE2_COMPARE_0_WORD_0 + cr_idx * 2 + 1];
84
+ } else {
155
- offset = extract32(cr1, GEM_T2CW1_OFFSET_VALUE_SHIFT,
85
+ tcg_gen_andi_i32(tmp, tmp, ~R_V7M_FPCCR_S_MASK);
156
- GEM_T2CW1_OFFSET_VALUE_WIDTH);
86
+ }
157
+ cr1 = s->regs[R_TYPE2_COMPARE_0_WORD_1 + cr_idx * 2];
87
+ store_cpu_field(tmp, v7m.fpccr[M_REG_S]);
158
+ offset = FIELD_EX32(cr1, TYPE2_COMPARE_0_WORD_1, OFFSET_VALUE);
88
+ /* Don't need to do this for any further FP insns in this TB */
159
89
+ s->v8m_fpccr_s_wrong = false;
160
- switch (extract32(cr1, GEM_T2CW1_COMPARE_OFFSET_SHIFT,
90
+ }
161
- GEM_T2CW1_COMPARE_OFFSET_WIDTH)) {
91
+ }
162
+ switch (FIELD_EX32(cr1, TYPE2_COMPARE_0_WORD_1, COMPARE_OFFSET)) {
92
+
163
case 3: /* Skip UDP header */
93
if (extract32(insn, 28, 4) == 0xf) {
164
qemu_log_mask(LOG_UNIMP, "TCP compare offsets"
94
/*
165
"unimplemented - assuming UDP\n");
95
* Encodings with T=1 (Thumb) or unconditional (ARM):
166
@@ -XXX,XX +XXX,XX @@ static int get_queue_from_screen(CadenceGEMState *s, uint8_t *rxbuf_ptr,
96
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
167
}
97
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
168
98
regime_is_secure(env, dc->mmu_idx);
169
rx_cmp = rxbuf_ptr[offset] << 8 | rxbuf_ptr[offset];
99
dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
170
- mask = extract32(cr0, 0, 16);
100
+ dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
171
+ mask = FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, MASK_VALUE);
101
dc->cp_regs = cpu->cp_regs;
172
+ compare = FIELD_EX32(cr0, TYPE2_COMPARE_0_WORD_0, COMPARE_VALUE);
102
dc->features = env->features;
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
}
103
187
104
--
188
--
105
2.20.1
189
2.34.1
106
107
diff view generated by jsdifflib
1
Enforce that for M-profile various FPSCR bits which are RES0 there
1
From: Luc Michel <luc.michel@amd.com>
2
but have defined meanings on A-profile are never settable. This
3
ensures that M-profile code can't enable the A-profile behaviour
4
(notably vector length/stride handling) by accident.
5
2
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
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190416125744.27770-2-peter.maydell@linaro.org
9
---
9
---
10
target/arm/vfp_helper.c | 8 ++++++++
10
hw/net/cadence_gem.c | 53 +++++++++++++++++++++++++++++++++-----------
11
1 file changed, 8 insertions(+)
11
1 file changed, 40 insertions(+), 13 deletions(-)
12
12
13
diff --git a/target/arm/vfp_helper.c b/target/arm/vfp_helper.c
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/vfp_helper.c
15
--- a/hw/net/cadence_gem.c
16
+++ b/target/arm/vfp_helper.c
16
+++ b/hw/net/cadence_gem.c
17
@@ -XXX,XX +XXX,XX @@ void HELPER(vfp_set_fpscr)(CPUARMState *env, uint32_t val)
17
@@ -XXX,XX +XXX,XX @@
18
val &= ~FPCR_FZ16;
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;
19
}
84
}
20
85
21
+ if (arm_feature(env, ARM_FEATURE_M)) {
86
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
22
+ /*
87
while (tx_desc_get_used(desc) == 0) {
23
+ * M profile FPSCR is RES0 for the QC, STRIDE, FZ16, LEN bits
88
24
+ * and also for the trapped-exception-handling bits IxE.
89
/* Do nothing if transmit is not enabled. */
25
+ */
90
- if (!(s->regs[R_NWCTRL] & GEM_NWCTRL_TXENA)) {
26
+ val &= 0xf7c0009f;
91
+ if (!FIELD_EX32(s->regs[R_NWCTRL], NWCTRL, ENABLE_TRANSMIT)) {
27
+ }
92
return;
28
+
93
}
29
/*
94
print_gem_tx_desc(desc, q);
30
* We don't implement trapped exception handling, so the
95
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
31
* trap enable bits, IDE|IXE|UFE|OFE|DZE|IOE are all RAZ/WI (not RES0!)
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);
32
--
125
--
33
2.20.1
126
2.34.1
34
35
diff view generated by jsdifflib
1
We are close to running out of TB flags for AArch32; we could
1
From: Luc Michel <luc.michel@amd.com>
2
start using the cs_base word, but before we do that we can
3
economise on our usage by sharing the same bits for the VFP
4
VECSTRIDE field and the XScale XSCALE_CPAR field. This
5
works because no XScale CPU ever had VFP.
6
2
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
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190416125744.27770-18-peter.maydell@linaro.org
10
---
9
---
11
target/arm/cpu.h | 10 ++++++----
10
hw/net/cadence_gem.c | 60 ++++++++++++++++++++++++++++----------------
12
target/arm/cpu.c | 7 +++++++
11
1 file changed, 39 insertions(+), 21 deletions(-)
13
target/arm/helper.c | 6 +++++-
14
target/arm/translate.c | 9 +++++++--
15
4 files changed, 25 insertions(+), 7 deletions(-)
16
12
17
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
18
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/cpu.h
15
--- a/hw/net/cadence_gem.c
20
+++ b/target/arm/cpu.h
16
+++ b/hw/net/cadence_gem.c
21
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_ANY, BE_DATA, 23, 1)
17
@@ -XXX,XX +XXX,XX @@ REG32(NWCTRL, 0x0) /* Network Control reg */
22
FIELD(TBFLAG_A32, THUMB, 0, 1)
18
FIELD(NWCTRL, IFG_EATS_QAV_CREDIT, 30, 1)
23
FIELD(TBFLAG_A32, VECLEN, 1, 3)
19
24
FIELD(TBFLAG_A32, VECSTRIDE, 4, 2)
20
REG32(NWCFG, 0x4) /* Network Config reg */
25
+/*
21
+ FIELD(NWCFG, SPEED, 0, 1)
26
+ * We store the bottom two bits of the CPAR as TB flags and handle
22
+ FIELD(NWCFG, FULL_DUPLEX, 1, 1)
27
+ * checks on the other bits at runtime. This shares the same bits as
23
+ FIELD(NWCFG, DISCARD_NON_VLAN_FRAMES, 2, 1)
28
+ * VECSTRIDE, which is OK as no XScale CPU has VFP.
24
+ FIELD(NWCFG, JUMBO_FRAMES, 3, 1)
29
+ */
25
+ FIELD(NWCFG, PROMISC, 4, 1)
30
+FIELD(TBFLAG_A32, XSCALE_CPAR, 4, 2)
26
+ FIELD(NWCFG, NO_BROADCAST, 5, 1)
31
/*
27
+ FIELD(NWCFG, MULTICAST_HASH_EN, 6, 1)
32
* Indicates whether cp register reads and writes by guest code should access
28
+ FIELD(NWCFG, UNICAST_HASH_EN, 7, 1)
33
* the secure or nonsecure bank of banked registers; note that this is not
29
+ FIELD(NWCFG, RECV_1536_BYTE_FRAMES, 8, 1)
34
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, NS, 6, 1)
30
+ FIELD(NWCFG, EXTERNAL_ADDR_MATCH_EN, 9, 1)
35
FIELD(TBFLAG_A32, VFPEN, 7, 1)
31
+ FIELD(NWCFG, GIGABIT_MODE_ENABLE, 10, 1)
36
FIELD(TBFLAG_A32, CONDEXEC, 8, 8)
32
+ FIELD(NWCFG, PCS_SELECT, 11, 1)
37
FIELD(TBFLAG_A32, SCTLR_B, 16, 1)
33
+ FIELD(NWCFG, RETRY_TEST, 12, 1)
38
-/* We store the bottom two bits of the CPAR as TB flags and handle
34
+ FIELD(NWCFG, PAUSE_ENABLE, 13, 1)
39
- * checks on the other bits at runtime
35
+ FIELD(NWCFG, RECV_BUF_OFFSET, 14, 2)
40
- */
36
+ FIELD(NWCFG, LEN_ERR_DISCARD, 16, 1)
41
-FIELD(TBFLAG_A32, XSCALE_CPAR, 17, 2)
37
+ FIELD(NWCFG, FCS_REMOVE, 17, 1)
42
/* For M profile only, Handler (ie not Thread) mode */
38
+ FIELD(NWCFG, MDC_CLOCK_DIV, 18, 3)
43
FIELD(TBFLAG_A32, HANDLER, 21, 1)
39
+ FIELD(NWCFG, DATA_BUS_WIDTH, 21, 2)
44
/* For M profile only, whether we should generate stack-limit checks */
40
+ FIELD(NWCFG, DISABLE_COPY_PAUSE_FRAMES, 23, 1)
45
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
41
+ FIELD(NWCFG, RECV_CSUM_OFFLOAD_EN, 24, 1)
46
index XXXXXXX..XXXXXXX 100644
42
+ FIELD(NWCFG, EN_HALF_DUPLEX_RX, 25, 1)
47
--- a/target/arm/cpu.c
43
+ FIELD(NWCFG, IGNORE_RX_FCS, 26, 1)
48
+++ b/target/arm/cpu.c
44
+ FIELD(NWCFG, SGMII_MODE_ENABLE, 27, 1)
49
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
45
+ FIELD(NWCFG, IPG_STRETCH_ENABLE, 28, 1)
50
set_feature(env, ARM_FEATURE_THUMB_DSP);
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;
51
}
87
}
52
88
return size;
53
+ /*
89
}
54
+ * We rely on no XScale CPU having VFP so we can use the same bits in the
90
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
55
+ * TB flags field for VECSTRIDE and XSCALE_CPAR.
91
int i, is_mc;
56
+ */
92
57
+ assert(!(arm_feature(env, ARM_FEATURE_VFP) &&
93
/* Promiscuous mode? */
58
+ arm_feature(env, ARM_FEATURE_XSCALE)));
94
- if (s->regs[R_NWCFG] & GEM_NWCFG_PROMISC) {
59
+
95
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, PROMISC)) {
60
if (arm_feature(env, ARM_FEATURE_V7) &&
96
return GEM_RX_PROMISCUOUS_ACCEPT;
61
!arm_feature(env, ARM_FEATURE_M) &&
97
}
62
!arm_feature(env, ARM_FEATURE_PMSA)) {
98
63
diff --git a/target/arm/helper.c b/target/arm/helper.c
99
if (!memcmp(packet, broadcast_addr, 6)) {
64
index XXXXXXX..XXXXXXX 100644
100
/* Reject broadcast packets? */
65
--- a/target/arm/helper.c
101
- if (s->regs[R_NWCFG] & GEM_NWCFG_BCAST_REJ) {
66
+++ b/target/arm/helper.c
102
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, NO_BROADCAST)) {
67
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
103
return GEM_RX_REJECT;
68
|| arm_el_is_aa64(env, 1) || arm_feature(env, ARM_FEATURE_M)) {
69
flags = FIELD_DP32(flags, TBFLAG_A32, VFPEN, 1);
70
}
104
}
71
- flags = FIELD_DP32(flags, TBFLAG_A32, XSCALE_CPAR, env->cp15.c15_cpar);
105
return GEM_RX_BROADCAST_ACCEPT;
72
+ /* Note that XSCALE_CPAR shares bits with VECSTRIDE */
106
@@ -XXX,XX +XXX,XX @@ static int gem_mac_address_filter(CadenceGEMState *s, const uint8_t *packet)
73
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
107
74
+ flags = FIELD_DP32(flags, TBFLAG_A32,
108
/* Accept packets -w- hash match? */
75
+ XSCALE_CPAR, env->cp15.c15_cpar);
109
is_mc = is_multicast_ether_addr(packet);
76
+ }
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)
77
}
118
}
78
119
79
flags = FIELD_DP32(flags, TBFLAG_ANY, MMUIDX, arm_to_core_mmu_idx(mmu_idx));
120
/* Discard packets with receive length error enabled ? */
80
diff --git a/target/arm/translate.c b/target/arm/translate.c
121
- if (s->regs[R_NWCFG] & GEM_NWCFG_LERR_DISC) {
81
index XXXXXXX..XXXXXXX 100644
122
+ if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, LEN_ERR_DISCARD)) {
82
--- a/target/arm/translate.c
123
unsigned type_len;
83
+++ b/target/arm/translate.c
124
84
@@ -XXX,XX +XXX,XX @@ static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
125
/* Fish the ethertype / length field out of the RX packet */
85
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
126
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
86
dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
127
/*
87
dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
128
* Determine configured receive buffer offset (probably 0)
88
- dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
129
*/
89
- dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
130
- rxbuf_offset = (s->regs[R_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>
90
+ if (arm_feature(env, ARM_FEATURE_XSCALE)) {
131
- GEM_NWCFG_BUFF_OFST_S;
91
+ dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
132
+ rxbuf_offset = FIELD_EX32(s->regs[R_NWCFG], NWCFG, RECV_BUF_OFFSET);
92
+ dc->vec_stride = 0;
133
93
+ } else {
134
/* The configure size of each receive buffer. Determines how many
94
+ dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
135
* buffers needed to hold this packet.
95
+ dc->c15_cpar = 0;
136
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
96
+ }
137
}
97
dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
138
98
dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
139
/* Strip of FCS field ? (usually yes) */
99
regime_is_secure(env, dc->mmu_idx);
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;
100
--
145
--
101
2.20.1
146
2.34.1
102
103
diff view generated by jsdifflib
1
For M-profile the MVFR* ID registers are memory mapped, in the
1
From: Luc Michel <luc.michel@amd.com>
2
range we implement via the NVIC. Allow them to be read.
3
(If the CPU has no FPU, these registers are defined to be RAZ.)
4
2
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
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-3-peter.maydell@linaro.org
8
---
9
---
9
hw/intc/armv7m_nvic.c | 6 ++++++
10
hw/net/cadence_gem.c | 48 ++++++++++++++++++++++++++++----------------
10
1 file changed, 6 insertions(+)
11
1 file changed, 31 insertions(+), 17 deletions(-)
11
12
12
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/hw/intc/armv7m_nvic.c
15
--- a/hw/net/cadence_gem.c
15
+++ b/hw/intc/armv7m_nvic.c
16
+++ b/hw/net/cadence_gem.c
16
@@ -XXX,XX +XXX,XX @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs)
17
@@ -XXX,XX +XXX,XX @@ REG32(NWCFG, 0x4) /* Network Config reg */
17
return 0;
18
18
}
19
REG32(NWSTATUS, 0x8) /* Network Status reg */
19
return cpu->env.v7m.sfar;
20
REG32(USERIO, 0xc) /* User IO reg */
20
+ case 0xf40: /* MVFR0 */
21
+
21
+ return cpu->isar.mvfr0;
22
REG32(DMACFG, 0x10) /* DMA Control reg */
22
+ case 0xf44: /* MVFR1 */
23
+ FIELD(DMACFG, SEND_BCAST_TO_ALL_QS, 31, 1)
23
+ return cpu->isar.mvfr1;
24
+ FIELD(DMACFG, DMA_ADDR_BUS_WIDTH, 30, 1)
24
+ case 0xf48: /* MVFR2 */
25
+ FIELD(DMACFG, TX_BD_EXT_MODE_EN , 29, 1)
25
+ return cpu->isar.mvfr2;
26
+ FIELD(DMACFG, RX_BD_EXT_MODE_EN , 28, 1)
26
default:
27
+ FIELD(DMACFG, FORCE_MAX_AMBA_BURST_TX, 26, 1)
27
bad_offset:
28
+ FIELD(DMACFG, FORCE_MAX_AMBA_BURST_RX, 25, 1)
28
qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset);
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 {
29
--
131
--
30
2.20.1
132
2.34.1
31
32
diff view generated by jsdifflib
1
Normally configure identifies the source path by looking
1
From: Luc Michel <luc.michel@amd.com>
2
at the location where the configure script itself exists.
3
We also provide a --source-path option which lets the user
4
manually override this.
5
2
6
There isn't really an obvious use case for the --source-path
3
Use de FIELD macro to describe the TXSTATUS and RXSTATUS register
7
option, and in commit 927128222b0a91f56c13a in 2017 we
4
fields.
8
accidentally added some logic that looks at $source_path
9
before the command line option that overrides it has been
10
processed.
11
5
12
The fact that nobody complained suggests that there isn't
6
Signed-off-by: Luc Michel <luc.michel@amd.com>
13
any use of this option and we aren't testing it either;
7
Reviewed-by: sai.pavan.boddu@amd.com
14
remove it. This allows us to move the "make $source_path
8
Message-id: 20231017194422.4124691-7-luc.michel@amd.com
15
absolute" logic up so that there is no window in the script
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
where $source_path is set but not yet absolute.
10
---
11
hw/net/cadence_gem.c | 34 +++++++++++++++++++++++++---------
12
1 file changed, 25 insertions(+), 9 deletions(-)
17
13
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
14
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
19
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
15
index XXXXXXX..XXXXXXX 100644
20
Message-id: 20190318134019.23729-1-peter.maydell@linaro.org
16
--- a/hw/net/cadence_gem.c
21
---
17
+++ b/hw/net/cadence_gem.c
22
configure | 10 ++--------
18
@@ -XXX,XX +XXX,XX @@ REG32(DMACFG, 0x10) /* DMA Control reg */
23
1 file changed, 2 insertions(+), 8 deletions(-)
19
#define GEM_DMACFG_RBUFSZ_MUL 64 /* DMA RX Buffer Size multiplier */
24
20
25
diff --git a/configure b/configure
21
REG32(TXSTATUS, 0x14) /* TX Status reg */
26
index XXXXXXX..XXXXXXX 100755
22
+ FIELD(TXSTATUS, TX_USED_BIT_READ_MIDFRAME, 12, 1)
27
--- a/configure
23
+ FIELD(TXSTATUS, TX_FRAME_TOO_LARGE, 11, 1)
28
+++ b/configure
24
+ FIELD(TXSTATUS, TX_DMA_LOCKUP, 10, 1)
29
@@ -XXX,XX +XXX,XX @@ ld_has() {
25
+ FIELD(TXSTATUS, TX_MAC_LOCKUP, 9, 1)
30
26
+ FIELD(TXSTATUS, RESP_NOT_OK, 8, 1)
31
# default parameters
27
+ FIELD(TXSTATUS, LATE_COLLISION, 7, 1)
32
source_path=$(dirname "$0")
28
+ FIELD(TXSTATUS, TRANSMIT_UNDER_RUN, 6, 1)
33
+# make source path absolute
29
+ FIELD(TXSTATUS, TRANSMIT_COMPLETE, 5, 1)
34
+source_path=$(cd "$source_path"; pwd)
30
+ FIELD(TXSTATUS, AMBA_ERROR, 4, 1)
35
cpu=""
31
+ FIELD(TXSTATUS, TRANSMIT_GO, 3, 1)
36
iasl="iasl"
32
+ FIELD(TXSTATUS, RETRY_LIMIT, 2, 1)
37
interp_prefix="/usr/gnemul/qemu-%M"
33
+ FIELD(TXSTATUS, COLLISION, 1, 1)
38
@@ -XXX,XX +XXX,XX @@ for opt do
34
+ FIELD(TXSTATUS, USED_BIT_READ, 0, 1)
39
;;
35
+
40
--cxx=*) CXX="$optarg"
36
REG32(RXQBASE, 0x18) /* RX Q Base address reg */
41
;;
37
REG32(TXQBASE, 0x1c) /* TX Q Base address reg */
42
- --source-path=*) source_path="$optarg"
38
REG32(RXSTATUS, 0x20) /* RX Status reg */
43
- ;;
39
+ FIELD(RXSTATUS, RX_DMA_LOCKUP, 5, 1)
44
--cpu=*) cpu="$optarg"
40
+ FIELD(RXSTATUS, RX_MAC_LOCKUP, 4, 1)
45
;;
41
+ FIELD(RXSTATUS, RESP_NOT_OK, 3, 1)
46
--extra-cflags=*) QEMU_CFLAGS="$QEMU_CFLAGS $optarg"
42
+ FIELD(RXSTATUS, RECEIVE_OVERRUN, 2, 1)
47
@@ -XXX,XX +XXX,XX @@ if test "$debug_info" = "yes"; then
43
+ FIELD(RXSTATUS, FRAME_RECEIVED, 1, 1)
48
LDFLAGS="-g $LDFLAGS"
44
+ FIELD(RXSTATUS, BUF_NOT_AVAILABLE, 0, 1)
49
fi
45
+
50
46
REG32(ISR, 0x24) /* Interrupt Status reg */
51
-# make source path absolute
47
REG32(IER, 0x28) /* Interrupt Enable reg */
52
-source_path=$(cd "$source_path"; pwd)
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 */
53
-
55
-
54
# running configure in the source tree?
56
-#define GEM_RXSTATUS_FRMRCVD 0x00000002 /* Frame received */
55
# we know that's the case if configure is there.
57
-#define GEM_RXSTATUS_NOBUF 0x00000001 /* Buffer unavailable */
56
if test -f "./configure"; then
58
57
@@ -XXX,XX +XXX,XX @@ for opt do
59
/* GEM_ISR GEM_IER GEM_IDR GEM_IMR */
58
;;
60
#define GEM_INT_TXCMPL 0x00000080 /* Transmit Complete */
59
--interp-prefix=*) interp_prefix="$optarg"
61
@@ -XXX,XX +XXX,XX @@ static void gem_get_rx_desc(CadenceGEMState *s, int q)
60
;;
62
/* Descriptor owned by software ? */
61
- --source-path=*)
63
if (rx_desc_get_ownership(s->rx_desc[q]) == 1) {
62
- ;;
64
DB_PRINT("descriptor 0x%" HWADDR_PRIx " owned by sw.\n", desc_addr);
63
--cross-prefix=*)
65
- s->regs[R_RXSTATUS] |= GEM_RXSTATUS_NOBUF;
64
;;
66
+ s->regs[R_RXSTATUS] |= R_RXSTATUS_BUF_NOT_AVAILABLE_MASK;
65
--cc=*)
67
gem_set_isr(s, q, GEM_INT_RXUSED);
66
@@ -XXX,XX +XXX,XX @@ $(echo Available targets: $default_target_list | \
68
/* Handle interrupt consequences */
67
--target-list-exclude=LIST exclude a set of targets from the default target-list
69
gem_update_int_status(s);
68
70
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
69
Advanced options (experts only):
71
/* Count it */
70
- --source-path=PATH path of source code [$source_path]
72
gem_receive_updatestats(s, buf, size);
71
--cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]
73
72
--cc=CC use C compiler CC [$cc]
74
- s->regs[R_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;
73
--iasl=IASL use ACPI compiler IASL [$iasl]
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);
74
--
97
--
75
2.20.1
98
2.34.1
76
77
diff view generated by jsdifflib
1
Correct the decode of the M-profile "coprocessor and
1
From: Luc Michel <luc.michel@amd.com>
2
floating-point instructions" space:
3
* op0 == 0b11 is always unallocated
4
* if the CPU has an FPU then all insns with op1 == 0b101
5
are floating point and go to disas_vfp_insn()
6
2
7
For the moment we leave VLLDM and VLSTM as NOPs; in
3
Use de FIELD macro to describe the IRQ related register fields.
8
a later commit we will fill in the proper implementation
9
for the case where an FPU is present.
10
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
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
13
Message-id: 20190416125744.27770-7-peter.maydell@linaro.org
14
---
9
---
15
target/arm/translate.c | 26 ++++++++++++++++++++++----
10
hw/net/cadence_gem.c | 51 +++++++++++++++++++++++++++++++++-----------
16
1 file changed, 22 insertions(+), 4 deletions(-)
11
1 file changed, 39 insertions(+), 12 deletions(-)
17
12
18
diff --git a/target/arm/translate.c b/target/arm/translate.c
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/translate.c
15
--- a/hw/net/cadence_gem.c
21
+++ b/target/arm/translate.c
16
+++ b/hw/net/cadence_gem.c
22
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ REG32(RXSTATUS, 0x20) /* RX Status reg */
23
case 6: case 7: case 14: case 15:
18
FIELD(RXSTATUS, BUF_NOT_AVAILABLE, 0, 1)
24
/* Coprocessor. */
19
25
if (arm_dc_feature(s, ARM_FEATURE_M)) {
20
REG32(ISR, 0x24) /* Interrupt Status reg */
26
- /* We don't currently implement M profile FP support,
21
+ FIELD(ISR, TX_LOCKUP, 31, 1)
27
- * so this entire space should give a NOCP fault, with
22
+ FIELD(ISR, RX_LOCKUP, 30, 1)
28
- * the exception of the v8M VLLDM and VLSTM insns, which
23
+ FIELD(ISR, TSU_TIMER, 29, 1)
29
- * must be NOPs in Secure state and UNDEF in Nonsecure state.
24
+ FIELD(ISR, WOL, 28, 1)
30
+ /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
25
+ FIELD(ISR, RECV_LPI, 27, 1)
31
+ if (extract32(insn, 24, 2) == 3) {
26
+ FIELD(ISR, TSU_SEC_INCR, 26, 1)
32
+ goto illegal_op; /* op0 = 0b11 : unallocated */
27
+ FIELD(ISR, PTP_PDELAY_RESP_XMIT, 25, 1)
33
+ }
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 */
34
+
56
+
35
+ /*
57
REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
36
+ * Decode VLLDM and VLSTM first: these are nonstandard because:
58
REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
37
+ * * if there is no FPU then these insns must NOP in
59
REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
38
+ * Secure state and UNDEF in Nonsecure state
60
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
39
+ * * if there is an FPU then these insns do not have
61
/*****************************************/
40
+ * the usual behaviour that disas_vfp_insn() provides of
62
41
+ * being controlled by CPACR/NSACR enable bits or the
63
42
+ * lazy-stacking logic.
64
-/* GEM_ISR GEM_IER GEM_IDR GEM_IMR */
43
*/
65
-#define GEM_INT_TXCMPL 0x00000080 /* Transmit Complete */
44
if (arm_dc_feature(s, ARM_FEATURE_V8) &&
66
-#define GEM_INT_AMBA_ERR 0x00000040
45
(insn & 0xffa00f00) == 0xec200a00) {
67
-#define GEM_INT_TXUSED 0x00000008
46
@@ -XXX,XX +XXX,XX @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
68
-#define GEM_INT_RXUSED 0x00000004
47
/* Just NOP since FP support is not implemented */
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);
48
break;
106
break;
49
}
107
}
50
+ if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
108
51
+ ((insn >> 8) & 0xe) == 10) {
109
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
52
+ /* FP, and the CPU supports it */
110
DB_PRINT("TX descriptor next: 0x%08x\n", s->tx_desc_addr[q]);
53
+ if (disas_vfp_insn(s, insn)) {
111
54
+ goto illegal_op;
112
s->regs[R_TXSTATUS] |= R_TXSTATUS_TRANSMIT_COMPLETE_MASK;
55
+ }
113
- gem_set_isr(s, q, GEM_INT_TXCMPL);
56
+ break;
114
+ gem_set_isr(s, q, R_ISR_XMIT_COMPLETE_MASK);
57
+ }
115
58
+
116
/* Handle interrupt consequences */
59
/* All other insns: NOCP */
117
gem_update_int_status(s);
60
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
118
@@ -XXX,XX +XXX,XX @@ static void gem_transmit(CadenceGEMState *s)
61
default_exception_el(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
}
62
--
127
--
63
2.20.1
128
2.34.1
64
65
diff view generated by jsdifflib
1
From: Eric Auger <eric.auger@redhat.com>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
The SMMUNotifierNode struct is not necessary and brings extra
3
Use the FIELD macro to describe the DESCONF6 register fields.
4
complexity so let's remove it. We now directly track the SMMUDevices
5
which have registered IOMMU MR notifiers.
6
4
7
This is inspired from the same transformation on intel-iommu
5
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
done in commit b4a4ba0d68f50f218ee3957b6638dbee32a5eeef
6
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
("intel-iommu: remove IntelIOMMUNotifierNode")
7
Message-id: 20231017194422.4124691-9-luc.michel@amd.com
10
11
Signed-off-by: Eric Auger <eric.auger@redhat.com>
12
Reviewed-by: Peter Xu <peterx@redhat.com>
13
Message-id: 20190409160219.19026-1-eric.auger@redhat.com
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
include/hw/arm/smmu-common.h | 8 ++------
10
hw/net/cadence_gem.c | 4 ++--
17
hw/arm/smmu-common.c | 6 +++---
11
1 file changed, 2 insertions(+), 2 deletions(-)
18
hw/arm/smmuv3.c | 28 +++++++---------------------
19
3 files changed, 12 insertions(+), 30 deletions(-)
20
12
21
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
22
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/arm/smmu-common.h
15
--- a/hw/net/cadence_gem.c
24
+++ b/include/hw/arm/smmu-common.h
16
+++ b/hw/net/cadence_gem.c
25
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUDevice {
17
@@ -XXX,XX +XXX,XX @@ REG32(DESCONF3, 0x288)
26
AddressSpace as;
18
REG32(DESCONF4, 0x28c)
27
uint32_t cfg_cache_hits;
19
REG32(DESCONF5, 0x290)
28
uint32_t cfg_cache_misses;
20
REG32(DESCONF6, 0x294)
29
+ QLIST_ENTRY(SMMUDevice) next;
21
-#define GEM_DESCONF6_64B_MASK (1U << 23)
30
} SMMUDevice;
22
+ FIELD(DESCONF6, DMA_ADDR_64B, 23, 1)
31
23
REG32(DESCONF7, 0x298)
32
-typedef struct SMMUNotifierNode {
24
33
- SMMUDevice *sdev;
25
REG32(INT_Q1_STATUS, 0x400)
34
- QLIST_ENTRY(SMMUNotifierNode) next;
26
@@ -XXX,XX +XXX,XX @@ static void gem_reset(DeviceState *d)
35
-} SMMUNotifierNode;
27
s->regs[R_DESCONF] = 0x02D00111;
36
-
28
s->regs[R_DESCONF2] = 0x2ab10000 | s->jumbo_max_len;
37
typedef struct SMMUPciBus {
29
s->regs[R_DESCONF5] = 0x002f2045;
38
PCIBus *bus;
30
- s->regs[R_DESCONF6] = GEM_DESCONF6_64B_MASK;
39
SMMUDevice *pbdev[0]; /* Parent array is sparse, so dynamically alloc */
31
+ s->regs[R_DESCONF6] = R_DESCONF6_DMA_ADDR_64B_MASK;
40
@@ -XXX,XX +XXX,XX @@ typedef struct SMMUState {
32
s->regs[R_INT_Q1_MASK] = 0x00000CE6;
41
GHashTable *iotlb;
33
s->regs[R_JUMBO_MAX_LEN] = s->jumbo_max_len;
42
SMMUPciBus *smmu_pcibus_by_bus_num[SMMU_PCI_BUS_MAX];
43
PCIBus *pci_bus;
44
- QLIST_HEAD(, SMMUNotifierNode) notifiers_list;
45
+ QLIST_HEAD(, SMMUDevice) devices_with_notifiers;
46
uint8_t bus_num;
47
PCIBus *primary_bus;
48
} SMMUState;
49
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
50
index XXXXXXX..XXXXXXX 100644
51
--- a/hw/arm/smmu-common.c
52
+++ b/hw/arm/smmu-common.c
53
@@ -XXX,XX +XXX,XX @@ inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
54
/* Unmap all notifiers of all mr's */
55
void smmu_inv_notifiers_all(SMMUState *s)
56
{
57
- SMMUNotifierNode *node;
58
+ SMMUDevice *sdev;
59
60
- QLIST_FOREACH(node, &s->notifiers_list, next) {
61
- smmu_inv_notifiers_mr(&node->sdev->iommu);
62
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
63
+ smmu_inv_notifiers_mr(&sdev->iommu);
64
}
65
}
66
67
diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c
68
index XXXXXXX..XXXXXXX 100644
69
--- a/hw/arm/smmuv3.c
70
+++ b/hw/arm/smmuv3.c
71
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_iova(IOMMUMemoryRegion *mr,
72
/* invalidate an asid/iova tuple in all mr's */
73
static void smmuv3_inv_notifiers_iova(SMMUState *s, int asid, dma_addr_t iova)
74
{
75
- SMMUNotifierNode *node;
76
+ SMMUDevice *sdev;
77
78
- QLIST_FOREACH(node, &s->notifiers_list, next) {
79
- IOMMUMemoryRegion *mr = &node->sdev->iommu;
80
+ QLIST_FOREACH(sdev, &s->devices_with_notifiers, next) {
81
+ IOMMUMemoryRegion *mr = &sdev->iommu;
82
IOMMUNotifier *n;
83
84
trace_smmuv3_inv_notifiers_iova(mr->parent_obj.name, asid, iova);
85
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
86
SMMUDevice *sdev = container_of(iommu, SMMUDevice, iommu);
87
SMMUv3State *s3 = sdev->smmu;
88
SMMUState *s = &(s3->smmu_state);
89
- SMMUNotifierNode *node = NULL;
90
- SMMUNotifierNode *next_node = NULL;
91
92
if (new & IOMMU_NOTIFIER_MAP) {
93
int bus_num = pci_bus_num(sdev->bus);
94
@@ -XXX,XX +XXX,XX @@ static void smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu,
95
96
if (old == IOMMU_NOTIFIER_NONE) {
97
trace_smmuv3_notify_flag_add(iommu->parent_obj.name);
98
- node = g_malloc0(sizeof(*node));
99
- node->sdev = sdev;
100
- QLIST_INSERT_HEAD(&s->notifiers_list, node, next);
101
- return;
102
- }
103
-
104
- /* update notifier node with new flags */
105
- QLIST_FOREACH_SAFE(node, &s->notifiers_list, next, next_node) {
106
- if (node->sdev == sdev) {
107
- if (new == IOMMU_NOTIFIER_NONE) {
108
- trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
109
- QLIST_REMOVE(node, next);
110
- g_free(node);
111
- }
112
- return;
113
- }
114
+ QLIST_INSERT_HEAD(&s->devices_with_notifiers, sdev, next);
115
+ } else if (new == IOMMU_NOTIFIER_NONE) {
116
+ trace_smmuv3_notify_flag_del(iommu->parent_obj.name);
117
+ QLIST_REMOVE(sdev, next);
118
}
119
}
120
34
121
--
35
--
122
2.20.1
36
2.34.1
123
37
124
38
diff view generated by jsdifflib
Deleted patch
1
In the stripe8() function we use a variable length array; however
2
we know that the maximum length required is MAX_NUM_BUSSES. Use
3
a fixed-length array and an assert instead.
4
1
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
7
Reviewed-by: Francisco Iglesias <frasse.iglesias@gmail.com>
8
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
9
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
10
Message-id: 20190328152635.2794-1-peter.maydell@linaro.org
11
---
12
hw/ssi/xilinx_spips.c | 6 ++++--
13
1 file changed, 4 insertions(+), 2 deletions(-)
14
15
diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/ssi/xilinx_spips.c
18
+++ b/hw/ssi/xilinx_spips.c
19
@@ -XXX,XX +XXX,XX @@ static void xlnx_zynqmp_qspips_reset(DeviceState *d)
20
21
static inline void stripe8(uint8_t *x, int num, bool dir)
22
{
23
- uint8_t r[num];
24
- memset(r, 0, sizeof(uint8_t) * num);
25
+ uint8_t r[MAX_NUM_BUSSES];
26
int idx[2] = {0, 0};
27
int bit[2] = {0, 7};
28
int d = dir;
29
30
+ assert(num <= MAX_NUM_BUSSES);
31
+ memset(r, 0, sizeof(uint8_t) * num);
32
+
33
for (idx[0] = 0; idx[0] < num; ++idx[0]) {
34
for (bit[0] = 7; bit[0] >= 0; bit[0]--) {
35
r[idx[!d]] |= x[idx[d]] & 1 << bit[d] ? 1 << bit[!d] : 0;
36
--
37
2.20.1
38
39
diff view generated by jsdifflib
1
Handle floating point registers in exception return.
1
From: Luc Michel <luc.michel@amd.com>
2
This corresponds to pseudocode functions ValidateExceptionReturn(),
3
ExceptionReturn(), PopStack() and ConsumeExcStackFrame().
4
2
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
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190416125744.27770-16-peter.maydell@linaro.org
8
---
9
---
9
target/arm/helper.c | 142 +++++++++++++++++++++++++++++++++++++++++++-
10
hw/net/cadence_gem.c | 27 ++++++++++++++-------------
10
1 file changed, 141 insertions(+), 1 deletion(-)
11
1 file changed, 14 insertions(+), 13 deletions(-)
11
12
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
13
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
15
--- a/hw/net/cadence_gem.c
15
+++ b/target/arm/helper.c
16
+++ b/hw/net/cadence_gem.c
16
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
17
@@ -XXX,XX +XXX,XX @@ REG32(IDR, 0x2c) /* Interrupt Disable reg */
17
bool rettobase = false;
18
REG32(IMR, 0x30) /* Interrupt Mask reg */
18
bool exc_secure = false;
19
19
bool return_to_secure;
20
REG32(PHYMNTNC, 0x34) /* Phy Maintenance reg */
20
+ bool ftype;
21
+ FIELD(PHYMNTNC, DATA, 0, 16)
21
+ bool restore_s16_s31;
22
+ FIELD(PHYMNTNC, REG_ADDR, 18, 5)
22
23
+ FIELD(PHYMNTNC, PHY_ADDR, 23, 5)
23
/* If we're not in Handler mode then jumps to magic exception-exit
24
+ FIELD(PHYMNTNC, OP, 28, 2)
24
* addresses don't have magic behaviour. However for the v8M
25
+ FIELD(PHYMNTNC, ST, 30, 2)
25
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
26
+#define MDIO_OP_READ 0x3
26
excret);
27
+#define MDIO_OP_WRITE 0x2
27
}
28
29
+ ftype = excret & R_V7M_EXCRET_FTYPE_MASK;
30
+
28
+
31
+ if (!arm_feature(env, ARM_FEATURE_VFP) && !ftype) {
29
REG32(RXPAUSE, 0x38) /* RX Pause Time reg */
32
+ qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero FTYPE in exception "
30
REG32(TXPAUSE, 0x3c) /* TX Pause Time reg */
33
+ "exit PC value 0x%" PRIx32 " is UNPREDICTABLE "
31
REG32(TXPARTIALSF, 0x40) /* TX Partial Store and Forward */
34
+ "if FPU not present\n",
32
@@ -XXX,XX +XXX,XX @@ REG32(TYPE2_COMPARE_0_WORD_1, 0x704)
35
+ excret);
33
36
+ ftype = true;
34
37
+ }
35
38
+
36
-#define GEM_PHYMNTNC_OP_R 0x20000000 /* read operation */
39
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
37
-#define GEM_PHYMNTNC_OP_W 0x10000000 /* write operation */
40
/* EXC_RETURN.ES validation check (R_SMFL). We must do this before
38
-#define GEM_PHYMNTNC_ADDR 0x0F800000 /* Address bits */
41
* we pick which FAULTMASK to clear.
39
-#define GEM_PHYMNTNC_ADDR_SHFT 23
42
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
40
-#define GEM_PHYMNTNC_REG 0x007C0000 /* register bits */
43
*/
41
-#define GEM_PHYMNTNC_REG_SHIFT 18
44
write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure);
42
-
45
43
/* Marvell PHY definitions */
46
+ /*
44
#define BOARD_PHY_ADDRESS 0 /* PHY address we will emulate a device at */
47
+ * Clear scratch FP values left in caller saved registers; this
45
48
+ * must happen before any kind of tail chaining.
46
@@ -XXX,XX +XXX,XX @@ static uint64_t gem_read(void *opaque, hwaddr offset, unsigned size)
49
+ */
47
/* The interrupts get updated at the end of the function. */
50
+ if ((env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_CLRONRET_MASK) &&
48
break;
51
+ (env->v7m.control[M_REG_S] & R_V7M_CONTROL_FPCA_MASK)) {
49
case R_PHYMNTNC:
52
+ if (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK) {
50
- if (retval & GEM_PHYMNTNC_OP_R) {
53
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
51
+ if (FIELD_EX32(retval, PHYMNTNC, OP) == MDIO_OP_READ) {
54
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
52
uint32_t phy_addr, reg_num;
55
+ qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing "
53
56
+ "stackframe: error during lazy state deactivation\n");
54
- phy_addr = (retval & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
57
+ v7m_exception_taken(cpu, excret, true, false);
55
+ phy_addr = FIELD_EX32(retval, PHYMNTNC, PHY_ADDR);
58
+ return;
56
if (phy_addr == s->phy_addr) {
59
+ } else {
57
- reg_num = (retval & GEM_PHYMNTNC_REG) >> GEM_PHYMNTNC_REG_SHIFT;
60
+ /* Clear s0..s15 and FPSCR */
58
+ reg_num = FIELD_EX32(retval, PHYMNTNC, REG_ADDR);
61
+ int i;
59
retval &= 0xFFFF0000;
62
+
60
retval |= gem_phy_read(s, reg_num);
63
+ for (i = 0; i < 16; i += 2) {
61
} else {
64
+ *aa32_vfp_dreg(env, i / 2) = 0;
62
@@ -XXX,XX +XXX,XX @@ static void gem_write(void *opaque, hwaddr offset, uint64_t val,
65
+ }
63
s->sar_active[(offset - R_SPADDR1HI) / 2] = true;
66
+ vfp_set_fpscr(env, 0);
64
break;
67
+ }
65
case R_PHYMNTNC:
68
+ }
66
- if (val & GEM_PHYMNTNC_OP_W) {
69
+
67
+ if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_WRITE) {
70
if (sfault) {
68
uint32_t phy_addr, reg_num;
71
env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK;
69
72
armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
70
- phy_addr = (val & GEM_PHYMNTNC_ADDR) >> GEM_PHYMNTNC_ADDR_SHFT;
73
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
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);
74
}
76
}
75
}
77
}
76
77
+ if (!ftype) {
78
+ /* FP present and we need to handle it */
79
+ if (!return_to_secure &&
80
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_LSPACT_MASK)) {
81
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false);
82
+ env->v7m.sfsr |= R_V7M_SFSR_LSERR_MASK;
83
+ qemu_log_mask(CPU_LOG_INT,
84
+ "...taking SecureFault on existing stackframe: "
85
+ "Secure LSPACT set but exception return is "
86
+ "not to secure state\n");
87
+ v7m_exception_taken(cpu, excret, true, false);
88
+ return;
89
+ }
90
+
91
+ restore_s16_s31 = return_to_secure &&
92
+ (env->v7m.fpccr[M_REG_S] & R_V7M_FPCCR_TS_MASK);
93
+
94
+ if (env->v7m.fpccr[return_to_secure] & R_V7M_FPCCR_LSPACT_MASK) {
95
+ /* State in FPU is still valid, just clear LSPACT */
96
+ env->v7m.fpccr[return_to_secure] &= ~R_V7M_FPCCR_LSPACT_MASK;
97
+ } else {
98
+ int i;
99
+ uint32_t fpscr;
100
+ bool cpacr_pass, nsacr_pass;
101
+
102
+ cpacr_pass = v7m_cpacr_pass(env, return_to_secure,
103
+ return_to_priv);
104
+ nsacr_pass = return_to_secure ||
105
+ extract32(env->v7m.nsacr, 10, 1);
106
+
107
+ if (!cpacr_pass) {
108
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE,
109
+ return_to_secure);
110
+ env->v7m.cfsr[return_to_secure] |= R_V7M_CFSR_NOCP_MASK;
111
+ qemu_log_mask(CPU_LOG_INT,
112
+ "...taking UsageFault on existing "
113
+ "stackframe: CPACR.CP10 prevents unstacking "
114
+ "FP regs\n");
115
+ v7m_exception_taken(cpu, excret, true, false);
116
+ return;
117
+ } else if (!nsacr_pass) {
118
+ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, true);
119
+ env->v7m.cfsr[M_REG_S] |= R_V7M_CFSR_INVPC_MASK;
120
+ qemu_log_mask(CPU_LOG_INT,
121
+ "...taking Secure UsageFault on existing "
122
+ "stackframe: NSACR.CP10 prevents unstacking "
123
+ "FP regs\n");
124
+ v7m_exception_taken(cpu, excret, true, false);
125
+ return;
126
+ }
127
+
128
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
129
+ uint32_t slo, shi;
130
+ uint64_t dn;
131
+ uint32_t faddr = frameptr + 0x20 + 4 * i;
132
+
133
+ if (i >= 16) {
134
+ faddr += 8; /* Skip the slot for the FPSCR */
135
+ }
136
+
137
+ pop_ok = pop_ok &&
138
+ v7m_stack_read(cpu, &slo, faddr, mmu_idx) &&
139
+ v7m_stack_read(cpu, &shi, faddr + 4, mmu_idx);
140
+
141
+ if (!pop_ok) {
142
+ break;
143
+ }
144
+
145
+ dn = (uint64_t)shi << 32 | slo;
146
+ *aa32_vfp_dreg(env, i / 2) = dn;
147
+ }
148
+ pop_ok = pop_ok &&
149
+ v7m_stack_read(cpu, &fpscr, frameptr + 0x60, mmu_idx);
150
+ if (pop_ok) {
151
+ vfp_set_fpscr(env, fpscr);
152
+ }
153
+ if (!pop_ok) {
154
+ /*
155
+ * These regs are 0 if security extension present;
156
+ * otherwise merely UNKNOWN. We zero always.
157
+ */
158
+ for (i = 0; i < (restore_s16_s31 ? 32 : 16); i += 2) {
159
+ *aa32_vfp_dreg(env, i / 2) = 0;
160
+ }
161
+ vfp_set_fpscr(env, 0);
162
+ }
163
+ }
164
+ }
165
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
166
+ V7M_CONTROL, FPCA, !ftype);
167
+
168
/* Commit to consuming the stack frame */
169
frameptr += 0x20;
170
+ if (!ftype) {
171
+ frameptr += 0x48;
172
+ if (restore_s16_s31) {
173
+ frameptr += 0x40;
174
+ }
175
+ }
176
/* Undo stack alignment (the SPREALIGN bit indicates that the original
177
* pre-exception SP was not 8-aligned and we added a padding word to
178
* align it, so we undo this by ORing in the bit that increases it
179
@@ -XXX,XX +XXX,XX @@ static void do_v7m_exception_exit(ARMCPU *cpu)
180
*frame_sp_p = frameptr;
181
}
182
/* This xpsr_write() will invalidate frame_sp_p as it may switch stack */
183
- xpsr_write(env, xpsr, ~XPSR_SPREALIGN);
184
+ xpsr_write(env, xpsr, ~(XPSR_SPREALIGN | XPSR_SFPA));
185
+
186
+ if (env->v7m.secure) {
187
+ bool sfpa = xpsr & XPSR_SFPA;
188
+
189
+ env->v7m.control[M_REG_S] = FIELD_DP32(env->v7m.control[M_REG_S],
190
+ V7M_CONTROL, SFPA, sfpa);
191
+ }
192
193
/* The restored xPSR exception field will be zero if we're
194
* resuming in Thread mode. If that doesn't match what the
195
--
78
--
196
2.20.1
79
2.34.1
197
198
diff view generated by jsdifflib
1
In the v7M architecture, if an exception is generated in the process
1
From: Luc Michel <luc.michel@amd.com>
2
of doing the lazy stacking of FP registers, the handling of
3
possible escalation to HardFault is treated differently to the normal
4
approach: it works based on the saved information about exception
5
readiness that was stored in the FPCCR when the stack frame was
6
created. Provide a new function armv7m_nvic_set_pending_lazyfp()
7
which pends exceptions during lazy stacking, and implements
8
this logic.
9
2
10
This corresponds to the pseudocode TakePreserveFPException().
3
The MDIO access is done only on a write to the PHYMNTNC register. A
4
subsequent read is used to retrieve the result but does not trigger an
5
MDIO access by itself.
11
6
7
Refactor the PHY access logic to perform all accesses (MDIO reads and
8
writes) at PHYMNTNC write time.
9
10
Signed-off-by: Luc Michel <luc.michel@amd.com>
11
Reviewed-by: sai.pavan.boddu@amd.com
12
Message-id: 20231017194422.4124691-11-luc.michel@amd.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
14
Message-id: 20190416125744.27770-22-peter.maydell@linaro.org
15
---
14
---
16
target/arm/cpu.h | 12 ++++++
15
hw/net/cadence_gem.c | 56 ++++++++++++++++++++++++++------------------
17
hw/intc/armv7m_nvic.c | 96 +++++++++++++++++++++++++++++++++++++++++++
16
1 file changed, 33 insertions(+), 23 deletions(-)
18
2 files changed, 108 insertions(+)
19
17
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
21
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
20
--- a/hw/net/cadence_gem.c
23
+++ b/target/arm/cpu.h
21
+++ b/hw/net/cadence_gem.c
24
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending(void *opaque, int irq, bool secure);
22
@@ -XXX,XX +XXX,XX @@ static void gem_phy_write(CadenceGEMState *s, unsigned reg_num, uint16_t val)
25
* a different exception).
23
s->phy_regs[reg_num] = val;
26
*/
27
void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure);
28
+/**
29
+ * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending
30
+ * @opaque: the NVIC
31
+ * @irq: the exception number to mark pending
32
+ * @secure: false for non-banked exceptions or for the nonsecure
33
+ * version of a banked exception, true for the secure version of a banked
34
+ * exception.
35
+ *
36
+ * Similar to armv7m_nvic_set_pending(), but specifically for exceptions
37
+ * generated in the course of lazy stacking of FP registers.
38
+ */
39
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure);
40
/**
41
* armv7m_nvic_get_pending_irq_info: return highest priority pending
42
* exception, and whether it targets Secure state
43
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/hw/intc/armv7m_nvic.c
46
+++ b/hw/intc/armv7m_nvic.c
47
@@ -XXX,XX +XXX,XX @@ void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure)
48
do_armv7m_nvic_set_pending(opaque, irq, secure, true);
49
}
24
}
50
25
51
+void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure)
26
+static void gem_handle_phy_access(CadenceGEMState *s)
52
+{
27
+{
53
+ /*
28
+ uint32_t val = s->regs[R_PHYMNTNC];
54
+ * Pend an exception during lazy FP stacking. This differs
29
+ uint32_t phy_addr, reg_num;
55
+ * from the usual exception pending because the logic for
56
+ * whether we should escalate depends on the saved context
57
+ * in the FPCCR register, not on the current state of the CPU/NVIC.
58
+ */
59
+ NVICState *s = (NVICState *)opaque;
60
+ bool banked = exc_is_banked(irq);
61
+ VecInfo *vec;
62
+ bool targets_secure;
63
+ bool escalate = false;
64
+ /*
65
+ * We will only look at bits in fpccr if this is a banked exception
66
+ * (in which case 'secure' tells us whether it is the S or NS version).
67
+ * All the bits for the non-banked exceptions are in fpccr_s.
68
+ */
69
+ uint32_t fpccr_s = s->cpu->env.v7m.fpccr[M_REG_S];
70
+ uint32_t fpccr = s->cpu->env.v7m.fpccr[secure];
71
+
30
+
72
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
31
+ phy_addr = FIELD_EX32(val, PHYMNTNC, PHY_ADDR);
73
+ assert(!secure || banked);
74
+
32
+
75
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
33
+ if (phy_addr != s->phy_addr) {
76
+
34
+ /* no phy at this address */
77
+ targets_secure = banked ? secure : exc_targets_secure(s, irq);
35
+ if (FIELD_EX32(val, PHYMNTNC, OP) == MDIO_OP_READ) {
78
+
36
+ s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA, 0xffff);
79
+ switch (irq) {
80
+ case ARMV7M_EXCP_DEBUG:
81
+ if (!(fpccr_s & R_V7M_FPCCR_MONRDY_MASK)) {
82
+ /* Ignore DebugMonitor exception */
83
+ return;
84
+ }
37
+ }
85
+ break;
38
+ return;
86
+ case ARMV7M_EXCP_MEM:
87
+ escalate = !(fpccr & R_V7M_FPCCR_MMRDY_MASK);
88
+ break;
89
+ case ARMV7M_EXCP_USAGE:
90
+ escalate = !(fpccr & R_V7M_FPCCR_UFRDY_MASK);
91
+ break;
92
+ case ARMV7M_EXCP_BUS:
93
+ escalate = !(fpccr_s & R_V7M_FPCCR_BFRDY_MASK);
94
+ break;
95
+ case ARMV7M_EXCP_SECURE:
96
+ escalate = !(fpccr_s & R_V7M_FPCCR_SFRDY_MASK);
97
+ break;
98
+ default:
99
+ g_assert_not_reached();
100
+ }
39
+ }
101
+
40
+
102
+ if (escalate) {
41
+ reg_num = FIELD_EX32(val, PHYMNTNC, REG_ADDR);
103
+ /*
104
+ * Escalate to HardFault: faults that initially targeted Secure
105
+ * continue to do so, even if HF normally targets NonSecure.
106
+ */
107
+ irq = ARMV7M_EXCP_HARD;
108
+ if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY) &&
109
+ (targets_secure ||
110
+ !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK))) {
111
+ vec = &s->sec_vectors[irq];
112
+ } else {
113
+ vec = &s->vectors[irq];
114
+ }
115
+ }
116
+
42
+
117
+ if (!vec->enabled ||
43
+ switch (FIELD_EX32(val, PHYMNTNC, OP)) {
118
+ nvic_exec_prio(s) <= exc_group_prio(s, vec->prio, secure)) {
44
+ case MDIO_OP_READ:
119
+ if (!(fpccr_s & R_V7M_FPCCR_HFRDY_MASK)) {
45
+ s->regs[R_PHYMNTNC] = FIELD_DP32(val, PHYMNTNC, DATA,
120
+ /*
46
+ gem_phy_read(s, reg_num));
121
+ * We want to escalate to HardFault but the context the
47
+ break;
122
+ * FP state belongs to prevents the exception pre-empting.
123
+ */
124
+ cpu_abort(&s->cpu->parent_obj,
125
+ "Lockup: can't escalate to HardFault during "
126
+ "lazy FP register stacking\n");
127
+ }
128
+ }
129
+
48
+
130
+ if (escalate) {
49
+ case MDIO_OP_WRITE:
131
+ s->cpu->env.v7m.hfsr |= R_V7M_HFSR_FORCED_MASK;
50
+ gem_phy_write(s, reg_num, val);
132
+ }
51
+ break;
133
+ if (!vec->pending) {
52
+
134
+ vec->pending = 1;
53
+ default:
135
+ /*
54
+ break; /* only clause 22 operations are supported */
136
+ * We do not call nvic_irq_update(), because we know our caller
137
+ * is going to handle causing us to take the exception by
138
+ * raising EXCP_LAZYFP, so raising the IRQ line would be
139
+ * pointless extra work. We just need to recompute the
140
+ * priorities so that armv7m_nvic_can_take_pending_exception()
141
+ * returns the right answer.
142
+ */
143
+ nvic_recompute_state(s);
144
+ }
55
+ }
145
+}
56
+}
146
+
57
+
147
/* Make pending IRQ active. */
58
/*
148
void armv7m_nvic_acknowledge_irq(void *opaque)
59
* gem_read32:
149
{
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
150
--
99
--
151
2.20.1
100
2.34.1
152
153
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Luc Michel <luc.michel@amd.com>
2
2
3
This device is used by both ARM (BCM2836, for raspi2) and AArch64
3
The CRC was stored in an unsigned variable in gem_receive. Change it for
4
(BCM2837, for raspi3) targets, and is not CPU-specific.
4
a uint32_t to ensure we have the correct variable size here.
5
Move it to common object, so we build it once for all targets.
6
5
7
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Luc Michel <luc.michel@amd.com>
8
Message-id: 20190427133028.12874-1-philmd@redhat.com
7
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: sai.pavan.boddu@amd.com
9
Message-id: 20231017194422.4124691-12-luc.michel@amd.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
11
---
12
hw/dma/Makefile.objs | 2 +-
12
hw/net/cadence_gem.c | 2 +-
13
1 file changed, 1 insertion(+), 1 deletion(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
14
14
15
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
15
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
16
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
17
--- a/hw/dma/Makefile.objs
17
--- a/hw/net/cadence_gem.c
18
+++ b/hw/dma/Makefile.objs
18
+++ b/hw/net/cadence_gem.c
19
@@ -XXX,XX +XXX,XX @@ common-obj-$(CONFIG_XLNX_ZYNQMP_ARM) += xlnx-zdma.o
19
@@ -XXX,XX +XXX,XX @@ static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)
20
20
if (FIELD_EX32(s->regs[R_NWCFG], NWCFG, FCS_REMOVE)) {
21
obj-$(CONFIG_OMAP) += omap_dma.o soc_dma.o
21
rxbuf_ptr = (void *)buf;
22
obj-$(CONFIG_PXA2XX) += pxa2xx_dma.o
22
} else {
23
-obj-$(CONFIG_RASPI) += bcm2835_dma.o
23
- unsigned crc_val;
24
+common-obj-$(CONFIG_RASPI) += bcm2835_dma.o
24
+ uint32_t crc_val;
25
26
if (size > MAX_FRAME_SIZE - sizeof(crc_val)) {
27
size = MAX_FRAME_SIZE - sizeof(crc_val);
25
--
28
--
26
2.20.1
29
2.34.1
27
30
28
31
diff view generated by jsdifflib