1
A largish pull request: the big things are Richard's PAuth work
1
Some arm patches; my to-review queue is by no means empty, but
2
and Aaron's PMU emulation improvements.
2
this is a big enough set of patches to be getting on with...
3
3
4
thanks
5
-- PMM
4
-- PMM
6
5
6
The following changes since commit cb9c6a8e5ad6a1f0ce164d352e3102df46986e22:
7
7
8
The following changes since commit 681d61362d3f766a00806b89d6581869041f73cb:
8
.gitlab-ci.d/windows: Work-around timeout and OpenGL problems of the MSYS2 jobs (2023-01-04 18:58:33 +0000)
9
10
Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging (2019-01-17 12:48:42 +0000)
11
9
12
are available in the Git repository at:
10
are available in the Git repository at:
13
11
14
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20190118
12
https://git.linaro.org/people/pmaydell/qemu-arm.git tags/pull-target-arm-20230105
15
13
16
for you to fetch changes up to 2a0ed2804e2c77a1c4e255f05ab739618e05c85d:
14
for you to fetch changes up to 93c9678de9dc7d2e68f9e8477da072bac30ef132:
17
15
18
tests/libqtest: Introduce qtest_init_with_serial() (2019-01-18 14:17:38 +0000)
16
hw/net: Fix read of uninitialized memory in imx_fec. (2023-01-05 15:33:00 +0000)
19
17
20
----------------------------------------------------------------
18
----------------------------------------------------------------
21
target-arm queue:
19
target-arm queue:
22
* hw/char/stm32f2xx_usart: Do not update data register when device is disabled
20
* Implement AArch32 ARMv8-R support
23
* hw/arm/virt-acpi-build: Set COHACC override flag in IORT SMMUv3 node
21
* Add Cortex-R52 CPU
24
* target/arm: Allow Aarch32 exception return to switch from Mon->Hyp
22
* fix handling of HLT semihosting in system mode
25
* ftgmac100: implement the new MDIO interface on Aspeed SoC
23
* hw/timer/ixm_epit: cleanup and fix bug in compare handling
26
* implement the ARMv8.3-PAuth extension
24
* target/arm: Coding style fixes
27
* improve emulation of the ARM PMU
25
* target/arm: Clean up includes
26
* nseries: minor code cleanups
27
* target/arm: align exposed ID registers with Linux
28
* hw/arm/smmu-common: remove unnecessary inlines
29
* i.MX7D: Handle GPT timers
30
* i.MX7D: Connect IRQs to GPIO devices
31
* i.MX6UL: Add a specific GPT timer instance
32
* hw/net: Fix read of uninitialized memory in imx_fec
28
33
29
----------------------------------------------------------------
34
----------------------------------------------------------------
30
Aaron Lindsay (13):
35
Alex Bennée (1):
31
migration: Add post_save function to VMStateDescription
36
target/arm: fix handling of HLT semihosting in system mode
32
target/arm: Reorganize PMCCNTR accesses
33
target/arm: Swap PMU values before/after migrations
34
target/arm: Filter cycle counter based on PMCCFILTR_EL0
35
target/arm: Allow AArch32 access for PMCCFILTR
36
target/arm: Implement PMOVSSET
37
target/arm: Define FIELDs for ID_DFR0
38
target/arm: Make PMCEID[01]_EL0 64 bit registers, add PMCEID[23]
39
target/arm: Add array for supported PMU events, generate PMCEID[01]_EL0
40
target/arm: Finish implementation of PM[X]EVCNTR and PM[X]EVTYPER
41
target/arm: PMU: Add instruction and cycle events
42
target/arm: PMU: Set PMCR.N to 4
43
target/arm: Implement PMSWINC
44
37
45
Alexander Graf (1):
38
Axel Heider (8):
46
target/arm: Allow Aarch32 exception return to switch from Mon->Hyp
39
hw/timer/imx_epit: improve comments
40
hw/timer/imx_epit: cleanup CR defines
41
hw/timer/imx_epit: define SR_OCIF
42
hw/timer/imx_epit: update interrupt state on CR write access
43
hw/timer/imx_epit: hard reset initializes CR with 0
44
hw/timer/imx_epit: factor out register write handlers
45
hw/timer/imx_epit: remove explicit fields cnt and freq
46
hw/timer/imx_epit: fix compare timer handling
47
47
48
Cédric Le Goater (1):
48
Claudio Fontana (1):
49
ftgmac100: implement the new MDIO interface on Aspeed SoC
49
target/arm: cleanup cpu includes
50
50
51
Eric Auger (1):
51
Fabiano Rosas (5):
52
hw/arm/virt-acpi-build: Set COHACC override flag in IORT SMMUv3 node
52
target/arm: Fix checkpatch comment style warnings in helper.c
53
target/arm: Fix checkpatch space errors in helper.c
54
target/arm: Fix checkpatch brace errors in helper.c
55
target/arm: Remove unused includes from m_helper.c
56
target/arm: Remove unused includes from helper.c
53
57
54
Julia Suvorova (1):
58
Jean-Christophe Dubois (4):
55
tests/libqtest: Introduce qtest_init_with_serial()
59
i.MX7D: Connect GPT timers to IRQ
60
i.MX7D: Compute clock frequency for the fixed frequency clocks.
61
i.MX6UL: Add a specific GPT timer instance for the i.MX6UL
62
i.MX7D: Connect IRQs to GPIO devices.
56
63
57
Philippe Mathieu-Daudé (1):
64
Peter Maydell (1):
58
hw/char/stm32f2xx_usart: Do not update data register when device is disabled
65
target/arm:Set lg_page_size to 0 if either S1 or S2 asks for it
59
66
60
Richard Henderson (31):
67
Philippe Mathieu-Daudé (5):
61
target/arm: Add state for the ARMv8.3-PAuth extension
68
hw/input/tsc2xxx: Constify set_transform()'s MouseTransformInfo arg
62
target/arm: Add SCTLR bits through ARMv8.5
69
hw/arm/nseries: Constify various read-only arrays
63
target/arm: Add PAuth active bit to tbflags
70
hw/arm/nseries: Silent -Wmissing-field-initializers warning
64
target/arm: Introduce raise_exception_ra
71
hw/arm/smmu-common: Reduce smmu_inv_notifiers_mr() scope
65
target/arm: Add PAuth helpers
72
hw/arm/smmu-common: Avoid using inlined functions with external linkage
66
target/arm: Decode PAuth within system hint space
67
target/arm: Rearrange decode in disas_data_proc_1src
68
target/arm: Decode PAuth within disas_data_proc_1src
69
target/arm: Decode PAuth within disas_data_proc_2src
70
target/arm: Move helper_exception_return to helper-a64.c
71
target/arm: Add new_pc argument to helper_exception_return
72
target/arm: Rearrange decode in disas_uncond_b_reg
73
target/arm: Decode PAuth within disas_uncond_b_reg
74
target/arm: Decode Load/store register (pac)
75
target/arm: Move cpu_mmu_index out of line
76
target/arm: Introduce arm_mmu_idx
77
target/arm: Introduce arm_stage1_mmu_idx
78
target/arm: Create ARMVAParameters and helpers
79
target/arm: Merge TBFLAG_AA_TB{0, 1} to TBII
80
target/arm: Export aa64_va_parameters to internals.h
81
target/arm: Add aa64_va_parameters_both
82
target/arm: Decode TBID from TCR
83
target/arm: Reuse aa64_va_parameters for setting tbflags
84
target/arm: Implement pauth_strip
85
target/arm: Implement pauth_auth
86
target/arm: Implement pauth_addpac
87
target/arm: Implement pauth_computepac
88
target/arm: Add PAuth system registers
89
target/arm: Enable PAuth for -cpu max
90
target/arm: Enable PAuth for user-only
91
target/arm: Tidy TBI handling in gen_a64_set_pc
92
73
93
target/arm/Makefile.objs | 1 +
74
Stephen Longfield (1):
94
include/hw/acpi/acpi-defs.h | 2 +
75
hw/net: Fix read of uninitialized memory in imx_fec.
95
include/migration/vmstate.h | 1 +
96
target/arm/cpu.h | 244 +++++----
97
target/arm/helper-a64.h | 14 +
98
target/arm/helper.h | 1 -
99
target/arm/internals.h | 77 +++
100
target/arm/translate.h | 5 +-
101
tests/libqtest.h | 11 +
102
hw/arm/virt-acpi-build.c | 1 +
103
hw/char/stm32f2xx_usart.c | 3 +-
104
hw/net/ftgmac100.c | 80 ++-
105
migration/vmstate.c | 13 +-
106
target/arm/cpu.c | 19 +-
107
target/arm/cpu64.c | 68 ++-
108
target/arm/helper-a64.c | 155 ++++++
109
target/arm/helper.c | 1222 +++++++++++++++++++++++++++++++++----------
110
target/arm/machine.c | 24 +
111
target/arm/op_helper.c | 174 +-----
112
target/arm/pauth_helper.c | 497 ++++++++++++++++++
113
target/arm/translate-a64.c | 537 ++++++++++++++++---
114
tests/libqtest.c | 26 +
115
docs/devel/migration.rst | 9 +-
116
23 files changed, 2552 insertions(+), 632 deletions(-)
117
create mode 100644 target/arm/pauth_helper.c
118
76
77
Tobias Röhmel (7):
78
target/arm: Don't add all MIDR aliases for cores that implement PMSA
79
target/arm: Make RVBAR available for all ARMv8 CPUs
80
target/arm: Make stage_2_format for cache attributes optional
81
target/arm: Enable TTBCR_EAE for ARMv8-R AArch32
82
target/arm: Add PMSAv8r registers
83
target/arm: Add PMSAv8r functionality
84
target/arm: Add ARM Cortex-R52 CPU
85
86
Zhuojia Shen (1):
87
target/arm: align exposed ID registers with Linux
88
89
include/hw/arm/fsl-imx7.h | 20 +
90
include/hw/arm/smmu-common.h | 3 -
91
include/hw/input/tsc2xxx.h | 4 +-
92
include/hw/timer/imx_epit.h | 8 +-
93
include/hw/timer/imx_gpt.h | 1 +
94
target/arm/cpu.h | 6 +
95
target/arm/internals.h | 4 +
96
hw/arm/fsl-imx6ul.c | 2 +-
97
hw/arm/fsl-imx7.c | 41 +-
98
hw/arm/nseries.c | 28 +-
99
hw/arm/smmu-common.c | 15 +-
100
hw/input/tsc2005.c | 2 +-
101
hw/input/tsc210x.c | 3 +-
102
hw/misc/imx6ul_ccm.c | 6 -
103
hw/misc/imx7_ccm.c | 49 ++-
104
hw/net/imx_fec.c | 8 +-
105
hw/timer/imx_epit.c | 376 +++++++++-------
106
hw/timer/imx_gpt.c | 25 ++
107
target/arm/cpu.c | 35 +-
108
target/arm/cpu64.c | 6 -
109
target/arm/cpu_tcg.c | 42 ++
110
target/arm/debug_helper.c | 3 +
111
target/arm/helper.c | 871 +++++++++++++++++++++++++++++---------
112
target/arm/m_helper.c | 16 -
113
target/arm/machine.c | 28 ++
114
target/arm/ptw.c | 152 +++++--
115
target/arm/tlb_helper.c | 4 +
116
target/arm/translate.c | 2 +-
117
tests/tcg/aarch64/sysregs.c | 24 +-
118
tests/tcg/aarch64/Makefile.target | 7 +-
119
30 files changed, 1330 insertions(+), 461 deletions(-)
120
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
In get_phys_addr_twostage() we set the lg_page_size of the result to
2
the maximum of the stage 1 and stage 2 page sizes. This works for
3
the case where we do want to create a TLB entry, because we know the
4
common TLB code only creates entries of the TARGET_PAGE_SIZE and
5
asking for a size larger than that only means that invalidations
6
invalidate the whole larger area. However, if lg_page_size is
7
smaller than TARGET_PAGE_SIZE this effectively means "don't create a
8
TLB entry"; in this case if either S1 or S2 said "this covers less
9
than a page and can't go in a TLB" then the final result also should
10
be marked that way. Set the resulting page size to 0 if either
11
stage asked for a less-than-a-page entry, and expand the comment
12
to explain what's going on.
2
13
3
In some cases it may be helpful to modify state before saving it for
14
This has no effect for VMSA because currently the VMSA lookup always
4
migration, and then modify the state back after it has been saved. The
15
returns results that cover at least TARGET_PAGE_SIZE; however when we
5
existing pre_save function provides half of this functionality. This
16
add v8R support it will reuse this code path, and for v8R the S1 and
6
patch adds a post_save function to provide the second half.
17
S2 results can be smaller than TARGET_PAGE_SIZE.
7
18
8
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
11
Message-id: 20181211151945.29137-2-aaron@os.amperecomputing.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
19
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Message-id: 20221212142708.610090-1-peter.maydell@linaro.org
13
---
22
---
14
include/migration/vmstate.h | 1 +
23
target/arm/ptw.c | 16 +++++++++++++---
15
migration/vmstate.c | 13 ++++++++++++-
24
1 file changed, 13 insertions(+), 3 deletions(-)
16
docs/devel/migration.rst | 9 +++++++--
17
3 files changed, 20 insertions(+), 3 deletions(-)
18
25
19
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
26
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
index XXXXXXX..XXXXXXX 100644
27
index XXXXXXX..XXXXXXX 100644
21
--- a/include/migration/vmstate.h
28
--- a/target/arm/ptw.c
22
+++ b/include/migration/vmstate.h
29
+++ b/target/arm/ptw.c
23
@@ -XXX,XX +XXX,XX @@ struct VMStateDescription {
30
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
24
int (*pre_load)(void *opaque);
25
int (*post_load)(void *opaque, int version_id);
26
int (*pre_save)(void *opaque);
27
+ int (*post_save)(void *opaque);
28
bool (*needed)(void *opaque);
29
const VMStateField *fields;
30
const VMStateDescription **subsections;
31
diff --git a/migration/vmstate.c b/migration/vmstate.c
32
index XXXXXXX..XXXXXXX 100644
33
--- a/migration/vmstate.c
34
+++ b/migration/vmstate.c
35
@@ -XXX,XX +XXX,XX @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
36
if (ret) {
37
error_report("Save of field %s/%s failed",
38
vmsd->name, field->name);
39
+ if (vmsd->post_save) {
40
+ vmsd->post_save(opaque);
41
+ }
42
return ret;
43
}
44
45
@@ -XXX,XX +XXX,XX @@ int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd,
46
json_end_array(vmdesc);
47
}
31
}
48
32
49
- return vmstate_subsection_save(f, vmsd, opaque, vmdesc);
33
/*
50
+ ret = vmstate_subsection_save(f, vmsd, opaque, vmdesc);
34
- * Use the maximum of the S1 & S2 page size, so that invalidation
51
+
35
- * of pages > TARGET_PAGE_SIZE works correctly.
52
+ if (vmsd->post_save) {
36
+ * If either S1 or S2 returned a result smaller than TARGET_PAGE_SIZE,
53
+ int ps_ret = vmsd->post_save(opaque);
37
+ * this means "don't put this in the TLB"; in this case, return a
54
+ if (!ret) {
38
+ * result with lg_page_size == 0 to achieve that. Otherwise,
55
+ ret = ps_ret;
39
+ * use the maximum of the S1 & S2 page size, so that invalidation
56
+ }
40
+ * of pages > TARGET_PAGE_SIZE works correctly. (This works even though
57
+ }
41
+ * we know the combined result permissions etc only cover the minimum
58
+ return ret;
42
+ * of the S1 and S2 page size, because we know that the common TLB code
59
}
43
+ * never actually creates TLB entries bigger than TARGET_PAGE_SIZE,
60
44
+ * and passing a larger page size value only affects invalidations.)
61
static const VMStateDescription *
45
*/
62
diff --git a/docs/devel/migration.rst b/docs/devel/migration.rst
46
- if (result->f.lg_page_size < s1_lgpgsz) {
63
index XXXXXXX..XXXXXXX 100644
47
+ if (result->f.lg_page_size < TARGET_PAGE_BITS ||
64
--- a/docs/devel/migration.rst
48
+ s1_lgpgsz < TARGET_PAGE_BITS) {
65
+++ b/docs/devel/migration.rst
49
+ result->f.lg_page_size = 0;
66
@@ -XXX,XX +XXX,XX @@ The functions to do that are inside a vmstate definition, and are called:
50
+ } else if (result->f.lg_page_size < s1_lgpgsz) {
67
51
result->f.lg_page_size = s1_lgpgsz;
68
This function is called before we save the state of one device.
52
}
69
53
70
-Example: You can look at hpet.c, that uses the three function to
71
-massage the state that is transferred.
72
+- ``int (*post_save)(void *opaque);``
73
+
74
+ This function is called after we save the state of one device
75
+ (even upon failure, unless the call to pre_save returned an error).
76
+
77
+Example: You can look at hpet.c, that uses the first three functions
78
+to massage the state that is transferred.
79
80
The ``VMSTATE_WITH_TMP`` macro may be useful when the migration
81
data doesn't match the stored device data well; it allows an
82
--
54
--
83
2.20.1
55
2.25.1
84
85
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
3
Cores with PMSA have the MPUIR register which has the
4
same encoding as the MIDR alias with opc2=4. So we only
5
add that alias if we are not realizing a core that
6
implements PMSA.
7
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Message-id: 20181211151945.29137-6-aaron@os.amperecomputing.com
11
Message-id: 20221206102504.165775-2-tobias.roehmel@rwth-aachen.de
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
---
13
---
9
target/arm/helper.c | 27 ++++++++++++++++++++++++++-
14
target/arm/helper.c | 13 +++++++++----
10
1 file changed, 26 insertions(+), 1 deletion(-)
15
1 file changed, 9 insertions(+), 4 deletions(-)
11
16
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/helper.c
19
--- a/target/arm/helper.c
15
+++ b/target/arm/helper.c
20
+++ b/target/arm/helper.c
16
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
21
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
17
PMXEVTYPER_M | PMXEVTYPER_MT | \
22
.access = PL1_R, .type = ARM_CP_NO_RAW, .resetvalue = cpu->midr,
18
PMXEVTYPER_EVTCOUNT)
23
.fieldoffset = offsetof(CPUARMState, cp15.c0_cpuid),
19
24
.readfn = midr_read },
20
+#define PMCCFILTR 0xf8000000
25
- /* crn = 0 op1 = 0 crm = 0 op2 = 4,7 : AArch32 aliases of MIDR */
21
+#define PMCCFILTR_M PMXEVTYPER_M
26
- { .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
22
+#define PMCCFILTR_EL0 (PMCCFILTR | PMCCFILTR_M)
27
- .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
23
+
28
- .access = PL1_R, .resetvalue = cpu->midr },
24
static inline uint32_t pmu_num_counters(CPUARMState *env)
29
+ /* crn = 0 op1 = 0 crm = 0 op2 = 7 : AArch32 aliases of MIDR */
25
{
30
{ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
26
return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
31
.cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 7,
27
@@ -XXX,XX +XXX,XX @@ static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
32
.access = PL1_R, .resetvalue = cpu->midr },
28
uint64_t value)
33
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
29
{
34
.accessfn = access_aa64_tid1,
30
pmccntr_op_start(env);
35
.type = ARM_CP_CONST, .resetvalue = cpu->revidr },
31
- env->cp15.pmccfiltr_el0 = value & 0xfc000000;
36
};
32
+ env->cp15.pmccfiltr_el0 = value & PMCCFILTR_EL0;
37
+ ARMCPRegInfo id_v8_midr_alias_cp_reginfo = {
33
pmccntr_op_finish(env);
38
+ .name = "MIDR", .type = ARM_CP_ALIAS | ARM_CP_CONST,
34
}
39
+ .cp = 15, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 4,
35
40
+ .access = PL1_R, .resetvalue = cpu->midr
36
+static void pmccfiltr_write_a32(CPUARMState *env, const ARMCPRegInfo *ri,
41
+ };
37
+ uint64_t value)
42
ARMCPRegInfo id_cp_reginfo[] = {
38
+{
43
/* These are common to v8 and pre-v8 */
39
+ pmccntr_op_start(env);
44
{ .name = "CTR",
40
+ /* M is not accessible from AArch32 */
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
41
+ env->cp15.pmccfiltr_el0 = (env->cp15.pmccfiltr_el0 & PMCCFILTR_M) |
46
}
42
+ (value & PMCCFILTR);
47
if (arm_feature(env, ARM_FEATURE_V8)) {
43
+ pmccntr_op_finish(env);
48
define_arm_cp_regs(cpu, id_v8_midr_cp_reginfo);
44
+}
49
+ if (!arm_feature(env, ARM_FEATURE_PMSA)) {
45
+
50
+ define_one_arm_cp_reg(cpu, &id_v8_midr_alias_cp_reginfo);
46
+static uint64_t pmccfiltr_read_a32(CPUARMState *env, const ARMCPRegInfo *ri)
51
+ }
47
+{
52
} else {
48
+ /* M is not visible in AArch32 */
53
define_arm_cp_regs(cpu, id_pre_v8_midr_cp_reginfo);
49
+ return env->cp15.pmccfiltr_el0 & PMCCFILTR;
54
}
50
+}
51
+
52
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
53
uint64_t value)
54
{
55
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
56
.readfn = pmccntr_read, .writefn = pmccntr_write,
57
.raw_readfn = raw_read, .raw_writefn = raw_write, },
58
#endif
59
+ { .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
60
+ .writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
61
+ .access = PL0_RW, .accessfn = pmreg_access,
62
+ .type = ARM_CP_ALIAS | ARM_CP_IO,
63
+ .resetvalue = 0, },
64
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
65
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
66
.writefn = pmccfiltr_write, .raw_writefn = raw_write,
67
--
55
--
68
2.20.1
56
2.25.1
69
57
70
58
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
This commit doesn't add any supported events, but provides the framework
3
RVBAR shadows RVBAR_ELx where x is the highest exception
4
for adding them. We store the pm_event structs in a simple array, and
4
level if the highest EL is not EL3. This patch also allows
5
provide the mapping from the event numbers to array indexes in the
5
ARMv8 CPUs to change the reset address with
6
supported_event_map array. Because the value of PMCEID[01] depends upon
6
the rvbar property.
7
which events are supported at runtime, generate it dynamically.
8
7
9
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20181211151945.29137-10-aaron@os.amperecomputing.com
10
Message-id: 20221206102504.165775-3-tobias.roehmel@rwth-aachen.de
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
12
---
14
target/arm/cpu.h | 10 ++++++++
13
target/arm/cpu.c | 6 +++++-
15
target/arm/cpu.c | 19 +++++++++------
14
target/arm/helper.c | 21 ++++++++++++++-------
16
target/arm/cpu64.c | 4 ----
15
2 files changed, 19 insertions(+), 8 deletions(-)
17
target/arm/helper.c | 57 +++++++++++++++++++++++++++++++++++++++++++++
18
4 files changed, 79 insertions(+), 11 deletions(-)
19
16
20
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
index XXXXXXX..XXXXXXX 100644
22
--- a/target/arm/cpu.h
23
+++ b/target/arm/cpu.h
24
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
25
void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
26
void pmu_post_el_change(ARMCPU *cpu, void *ignored);
27
28
+/*
29
+ * get_pmceid
30
+ * @env: CPUARMState
31
+ * @which: which PMCEID register to return (0 or 1)
32
+ *
33
+ * Return the PMCEID[01]_EL0 register values corresponding to the counters
34
+ * which are supported given the current configuration
35
+ */
36
+uint64_t get_pmceid(CPUARMState *env, unsigned which);
37
+
38
/* SCTLR bit meanings. Several bits have been reused in newer
39
* versions of the architecture; in that case we define constants
40
* for both old and new bit meanings. Code which tests against those
41
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
42
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/cpu.c
19
--- a/target/arm/cpu.c
44
+++ b/target/arm/cpu.c
20
+++ b/target/arm/cpu.c
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
21
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
46
22
env->cp15.cpacr_el1 = FIELD_DP64(env->cp15.cpacr_el1,
47
if (!cpu->has_pmu) {
23
CPACR, CP11, 3);
48
unset_feature(env, ARM_FEATURE_PMU);
24
#endif
49
+ }
25
+ if (arm_feature(env, ARM_FEATURE_V8)) {
50
+ if (arm_feature(env, ARM_FEATURE_PMU)) {
26
+ env->cp15.rvbar = cpu->rvbar_prop;
51
+ cpu->pmceid0 = get_pmceid(&cpu->env, 0);
27
+ env->regs[15] = cpu->rvbar_prop;
52
+ cpu->pmceid1 = get_pmceid(&cpu->env, 1);
53
+
54
+ if (!kvm_enabled()) {
55
+ arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
56
+ arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
57
+ }
28
+ }
58
+ } else {
59
cpu->id_aa64dfr0 &= ~0xf00;
60
- } else if (!kvm_enabled()) {
61
- arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
62
- arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
63
+ cpu->pmceid0 = 0;
64
+ cpu->pmceid1 = 0;
65
}
29
}
66
30
67
if (!arm_feature(env, ARM_FEATURE_EL2)) {
31
#if defined(CONFIG_USER_ONLY)
68
@@ -XXX,XX +XXX,XX @@ static void cortex_a7_initfn(Object *obj)
32
@@ -XXX,XX +XXX,XX @@ void arm_cpu_post_init(Object *obj)
69
cpu->id_pfr0 = 0x00001131;
33
qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property);
70
cpu->id_pfr1 = 0x00011011;
34
}
71
cpu->id_dfr0 = 0x02010555;
35
72
- cpu->pmceid0 = 0x00000000;
36
- if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
73
- cpu->pmceid1 = 0x00000000;
37
+ if (arm_feature(&cpu->env, ARM_FEATURE_V8)) {
74
cpu->id_afr0 = 0x00000000;
38
object_property_add_uint64_ptr(obj, "rvbar",
75
cpu->id_mmfr0 = 0x10101105;
39
&cpu->rvbar_prop,
76
cpu->id_mmfr1 = 0x40000000;
40
OBJ_PROP_FLAG_READWRITE);
77
@@ -XXX,XX +XXX,XX @@ static void cortex_a15_initfn(Object *obj)
78
cpu->id_pfr0 = 0x00001131;
79
cpu->id_pfr1 = 0x00011011;
80
cpu->id_dfr0 = 0x02010555;
81
- cpu->pmceid0 = 0x0000000;
82
- cpu->pmceid1 = 0x00000000;
83
cpu->id_afr0 = 0x00000000;
84
cpu->id_mmfr0 = 0x10201105;
85
cpu->id_mmfr1 = 0x20000000;
86
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/target/arm/cpu64.c
89
+++ b/target/arm/cpu64.c
90
@@ -XXX,XX +XXX,XX @@ static void aarch64_a57_initfn(Object *obj)
91
cpu->isar.id_isar6 = 0;
92
cpu->isar.id_aa64pfr0 = 0x00002222;
93
cpu->id_aa64dfr0 = 0x10305106;
94
- cpu->pmceid0 = 0x00000000;
95
- cpu->pmceid1 = 0x00000000;
96
cpu->isar.id_aa64isar0 = 0x00011120;
97
cpu->isar.id_aa64mmfr0 = 0x00001124;
98
cpu->dbgdidr = 0x3516d000;
99
@@ -XXX,XX +XXX,XX @@ static void aarch64_a72_initfn(Object *obj)
100
cpu->isar.id_isar5 = 0x00011121;
101
cpu->isar.id_aa64pfr0 = 0x00002222;
102
cpu->id_aa64dfr0 = 0x10305106;
103
- cpu->pmceid0 = 0x00000000;
104
- cpu->pmceid1 = 0x00000000;
105
cpu->isar.id_aa64isar0 = 0x00011120;
106
cpu->isar.id_aa64mmfr0 = 0x00001124;
107
cpu->dbgdidr = 0x3516d000;
108
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
diff --git a/target/arm/helper.c b/target/arm/helper.c
109
index XXXXXXX..XXXXXXX 100644
42
index XXXXXXX..XXXXXXX 100644
110
--- a/target/arm/helper.c
43
--- a/target/arm/helper.c
111
+++ b/target/arm/helper.c
44
+++ b/target/arm/helper.c
112
@@ -XXX,XX +XXX,XX @@ static inline uint64_t pmu_counter_mask(CPUARMState *env)
45
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
113
return (1 << 31) | ((1 << pmu_num_counters(env)) - 1);
46
if (!arm_feature(env, ARM_FEATURE_EL3) &&
114
}
47
!arm_feature(env, ARM_FEATURE_EL2)) {
115
48
ARMCPRegInfo rvbar = {
116
+typedef struct pm_event {
49
- .name = "RVBAR_EL1", .state = ARM_CP_STATE_AA64,
117
+ uint16_t number; /* PMEVTYPER.evtCount is 16 bits wide */
50
+ .name = "RVBAR_EL1", .state = ARM_CP_STATE_BOTH,
118
+ /* If the event is supported on this CPU (used to generate PMCEID[01]) */
51
.opc0 = 3, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
119
+ bool (*supported)(CPUARMState *);
52
.access = PL1_R,
120
+ /*
53
.fieldoffset = offsetof(CPUARMState, cp15.rvbar),
121
+ * Retrieve the current count of the underlying event. The programmed
54
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
122
+ * counters hold a difference from the return value from this function
55
}
123
+ */
56
/* RVBAR_EL2 is only implemented if EL2 is the highest EL */
124
+ uint64_t (*get_count)(CPUARMState *);
57
if (!arm_feature(env, ARM_FEATURE_EL3)) {
125
+} pm_event;
58
- ARMCPRegInfo rvbar = {
126
+
59
- .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
127
+static const pm_event pm_events[] = {
60
- .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
128
+};
61
- .access = PL2_R,
129
+
62
- .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
130
+/*
63
+ ARMCPRegInfo rvbar[] = {
131
+ * Note: Before increasing MAX_EVENT_ID beyond 0x3f into the 0x40xx range of
64
+ {
132
+ * events (i.e. the statistical profiling extension), this implementation
65
+ .name = "RVBAR_EL2", .state = ARM_CP_STATE_AA64,
133
+ * should first be updated to something sparse instead of the current
66
+ .opc0 = 3, .opc1 = 4, .crn = 12, .crm = 0, .opc2 = 1,
134
+ * supported_event_map[] array.
67
+ .access = PL2_R,
135
+ */
68
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
136
+#define MAX_EVENT_ID 0x0
69
+ },
137
+#define UNSUPPORTED_EVENT UINT16_MAX
70
+ { .name = "RVBAR", .type = ARM_CP_ALIAS,
138
+static uint16_t supported_event_map[MAX_EVENT_ID + 1];
71
+ .cp = 15, .opc1 = 0, .crn = 12, .crm = 0, .opc2 = 1,
139
+
72
+ .access = PL2_R,
140
+/*
73
+ .fieldoffset = offsetof(CPUARMState, cp15.rvbar),
141
+ * Called upon initialization to build PMCEID0_EL0 or PMCEID1_EL0 (indicated by
74
+ },
142
+ * 'which'). We also use it to build a map of ARM event numbers to indices in
75
};
143
+ * our pm_events array.
76
- define_one_arm_cp_reg(cpu, &rvbar);
144
+ *
77
+ define_arm_cp_regs(cpu, rvbar);
145
+ * Note: Events in the 0x40XX range are not currently supported.
78
}
146
+ */
79
}
147
+uint64_t get_pmceid(CPUARMState *env, unsigned which)
80
148
+{
149
+ uint64_t pmceid = 0;
150
+ unsigned int i;
151
+
152
+ assert(which <= 1);
153
+
154
+ for (i = 0; i < ARRAY_SIZE(supported_event_map); i++) {
155
+ supported_event_map[i] = UNSUPPORTED_EVENT;
156
+ }
157
+
158
+ for (i = 0; i < ARRAY_SIZE(pm_events); i++) {
159
+ const pm_event *cnt = &pm_events[i];
160
+ assert(cnt->number <= MAX_EVENT_ID);
161
+ /* We do not currently support events in the 0x40xx range */
162
+ assert(cnt->number <= 0x3f);
163
+
164
+ if ((cnt->number & 0x20) == (which << 6) &&
165
+ cnt->supported(env)) {
166
+ pmceid |= (1 << (cnt->number & 0x1f));
167
+ supported_event_map[cnt->number] = i;
168
+ }
169
+ }
170
+ return pmceid;
171
+}
172
+
173
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
174
bool isread)
175
{
176
--
81
--
177
2.20.1
82
2.25.1
178
83
179
84
diff view generated by jsdifflib
1
From: Julia Suvorova <jusual@mail.ru>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Run qtest with a socket that connects QEMU chardev and test code.
3
The v8R PMSAv8 has a two-stage MPU translation process, but, unlike
4
VMSAv8, the stage 2 attributes are in the same format as the stage 1
5
attributes (8-bit MAIR format). Rather than converting the MAIR
6
format to the format used for VMSA stage 2 (bits [5:2] of a VMSA
7
stage 2 descriptor) and then converting back to do the attribute
8
combination, allow combined_attrs_nofwb() to accept s2 attributes
9
that are already in the MAIR format.
4
10
5
Signed-off-by: Julia Suvorova <jusual@mail.ru>
11
We move the assert() to combined_attrs_fwb(), because that function
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
12
really does require a VMSA stage 2 attribute format. (We will never
7
Message-id: 20190117161640.5496-2-jusual@mail.ru
13
get there for v8R, because PMSAv8 does not implement FEAT_S2FWB.)
14
15
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
16
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
17
Message-id: 20221206102504.165775-4-tobias.roehmel@rwth-aachen.de
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
18
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
19
---
10
tests/libqtest.h | 11 +++++++++++
20
target/arm/ptw.c | 10 ++++++++--
11
tests/libqtest.c | 26 ++++++++++++++++++++++++++
21
1 file changed, 8 insertions(+), 2 deletions(-)
12
2 files changed, 37 insertions(+)
13
22
14
diff --git a/tests/libqtest.h b/tests/libqtest.h
23
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
15
index XXXXXXX..XXXXXXX 100644
24
index XXXXXXX..XXXXXXX 100644
16
--- a/tests/libqtest.h
25
--- a/target/arm/ptw.c
17
+++ b/tests/libqtest.h
26
+++ b/target/arm/ptw.c
18
@@ -XXX,XX +XXX,XX @@ QTestState *qtest_init(const char *extra_args);
27
@@ -XXX,XX +XXX,XX @@ static uint8_t combined_attrs_nofwb(uint64_t hcr,
28
{
29
uint8_t s1lo, s2lo, s1hi, s2hi, s2_mair_attrs, ret_attrs;
30
31
- s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
32
+ if (s2.is_s2_format) {
33
+ s2_mair_attrs = convert_stage2_attrs(hcr, s2.attrs);
34
+ } else {
35
+ s2_mair_attrs = s2.attrs;
36
+ }
37
38
s1lo = extract32(s1.attrs, 0, 4);
39
s2lo = extract32(s2_mair_attrs, 0, 4);
40
@@ -XXX,XX +XXX,XX @@ static uint8_t force_cacheattr_nibble_wb(uint8_t attr)
19
*/
41
*/
20
QTestState *qtest_init_without_qmp_handshake(const char *extra_args);
42
static uint8_t combined_attrs_fwb(ARMCacheAttrs s1, ARMCacheAttrs s2)
21
43
{
22
+/**
44
+ assert(s2.is_s2_format && !s1.is_s2_format);
23
+ * qtest_init_with_serial:
24
+ * @extra_args: other arguments to pass to QEMU. CAUTION: these
25
+ * arguments are subject to word splitting and shell evaluation.
26
+ * @sock_fd: pointer to store the socket file descriptor for
27
+ * connection with serial.
28
+ *
29
+ * Returns: #QTestState instance.
30
+ */
31
+QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd);
32
+
45
+
33
/**
46
switch (s2.attrs) {
34
* qtest_quit:
47
case 7:
35
* @s: #QTestState instance to operate on.
48
/* Use stage 1 attributes */
36
diff --git a/tests/libqtest.c b/tests/libqtest.c
49
@@ -XXX,XX +XXX,XX @@ static ARMCacheAttrs combine_cacheattrs(uint64_t hcr,
37
index XXXXXXX..XXXXXXX 100644
50
ARMCacheAttrs ret;
38
--- a/tests/libqtest.c
51
bool tagged = false;
39
+++ b/tests/libqtest.c
52
40
@@ -XXX,XX +XXX,XX @@ QTestState *qtest_initf(const char *fmt, ...)
53
- assert(s2.is_s2_format && !s1.is_s2_format);
41
return s;
54
+ assert(!s1.is_s2_format);
42
}
55
ret.is_s2_format = false;
43
56
44
+QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd)
57
if (s1.attrs == 0xf0) {
45
+{
46
+ int sock_fd_init;
47
+ char *sock_path, sock_dir[] = "/tmp/qtest-serial-XXXXXX";
48
+ QTestState *qts;
49
+
50
+ g_assert(mkdtemp(sock_dir));
51
+ sock_path = g_strdup_printf("%s/sock", sock_dir);
52
+
53
+ sock_fd_init = init_socket(sock_path);
54
+
55
+ qts = qtest_initf("-chardev socket,id=s0,path=%s,nowait "
56
+ "-serial chardev:s0 %s",
57
+ sock_path, extra_args);
58
+
59
+ *sock_fd = socket_accept(sock_fd_init);
60
+
61
+ unlink(sock_path);
62
+ g_free(sock_path);
63
+ rmdir(sock_dir);
64
+
65
+ g_assert(*sock_fd >= 0);
66
+
67
+ return qts;
68
+}
69
+
70
void qtest_quit(QTestState *s)
71
{
72
g_hook_destroy_link(&abrt_hooks, g_hook_find_data(&abrt_hooks, TRUE, s));
73
--
58
--
74
2.20.1
59
2.25.1
75
60
76
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Use TBID in aa64_va_parameters depending on the data parameter.
3
ARMv8-R AArch32 CPUs behave as if TTBCR.EAE is always 1 even
4
This automatically updates all existing users of the function.
4
tough they don't have the TTBCR register.
5
See ARM Architecture Reference Manual Supplement - ARMv8, for the ARMv8-R
6
AArch32 architecture profile Version:A.c section C1.2.
5
7
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-23-richard.henderson@linaro.org
10
Message-id: 20221206102504.165775-5-tobias.roehmel@rwth-aachen.de
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
12
---
11
target/arm/internals.h | 1 +
13
target/arm/internals.h | 4 ++++
12
target/arm/helper.c | 14 +++++++++++---
14
target/arm/debug_helper.c | 3 +++
13
2 files changed, 12 insertions(+), 3 deletions(-)
15
target/arm/tlb_helper.c | 4 ++++
16
3 files changed, 11 insertions(+)
14
17
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
18
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
20
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
21
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
22
@@ -XXX,XX +XXX,XX @@ unsigned int arm_pamax(ARMCPU *cpu);
20
unsigned tsz : 8;
23
static inline bool extended_addresses_enabled(CPUARMState *env)
21
unsigned select : 1;
24
{
22
bool tbi : 1;
25
uint64_t tcr = env->cp15.tcr_el[arm_is_secure(env) ? 3 : 1];
23
+ bool tbid : 1;
26
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
24
bool epd : 1;
27
+ arm_feature(env, ARM_FEATURE_V8)) {
25
bool hpd : 1;
28
+ return true;
26
bool using16k : 1;
29
+ }
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
30
return arm_el_is_aa64(env, 1) ||
31
(arm_feature(env, ARM_FEATURE_LPAE) && (tcr & TTBCR_EAE));
32
}
33
diff --git a/target/arm/debug_helper.c b/target/arm/debug_helper.c
28
index XXXXXXX..XXXXXXX 100644
34
index XXXXXXX..XXXXXXX 100644
29
--- a/target/arm/helper.c
35
--- a/target/arm/debug_helper.c
30
+++ b/target/arm/helper.c
36
+++ b/target/arm/debug_helper.c
31
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
37
@@ -XXX,XX +XXX,XX @@ static uint32_t arm_debug_exception_fsr(CPUARMState *env)
32
{
38
33
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
39
if (target_el == 2 || arm_el_is_aa64(env, target_el)) {
34
uint32_t el = regime_el(env, mmu_idx);
40
using_lpae = true;
35
- bool tbi, epd, hpd, using16k, using64k;
41
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
36
+ bool tbi, tbid, epd, hpd, using16k, using64k;
42
+ arm_feature(env, ARM_FEATURE_V8)) {
37
int select, tsz;
43
+ using_lpae = true;
38
39
/*
40
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
41
using16k = extract32(tcr, 15, 1);
42
if (mmu_idx == ARMMMUIdx_S2NS) {
43
/* VTCR_EL2 */
44
- tbi = hpd = false;
45
+ tbi = tbid = hpd = false;
46
} else {
47
tbi = extract32(tcr, 20, 1);
48
hpd = extract32(tcr, 24, 1);
49
+ tbid = extract32(tcr, 29, 1);
50
}
51
epd = false;
52
} else if (!select) {
53
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
54
using16k = extract32(tcr, 15, 1);
55
tbi = extract64(tcr, 37, 1);
56
hpd = extract64(tcr, 41, 1);
57
+ tbid = extract64(tcr, 51, 1);
58
} else {
44
} else {
59
int tg = extract32(tcr, 30, 2);
45
if (arm_feature(env, ARM_FEATURE_LPAE) &&
60
using16k = tg == 1;
46
(env->cp15.tcr_el[target_el] & TTBCR_EAE)) {
61
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
47
diff --git a/target/arm/tlb_helper.c b/target/arm/tlb_helper.c
62
epd = extract32(tcr, 23, 1);
48
index XXXXXXX..XXXXXXX 100644
63
tbi = extract64(tcr, 38, 1);
49
--- a/target/arm/tlb_helper.c
64
hpd = extract64(tcr, 42, 1);
50
+++ b/target/arm/tlb_helper.c
65
+ tbid = extract64(tcr, 52, 1);
51
@@ -XXX,XX +XXX,XX @@ bool regime_using_lpae_format(CPUARMState *env, ARMMMUIdx mmu_idx)
52
if (el == 2 || arm_el_is_aa64(env, el)) {
53
return true;
66
}
54
}
67
tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
55
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
68
tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
56
+ arm_feature(env, ARM_FEATURE_V8)) {
69
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
57
+ return true;
70
.tsz = tsz,
58
+ }
71
.select = select,
59
if (arm_feature(env, ARM_FEATURE_LPAE)
72
.tbi = tbi,
60
&& (regime_tcr(env, mmu_idx) & TTBCR_EAE)) {
73
+ .tbid = tbid,
61
return true;
74
.epd = epd,
75
.hpd = hpd,
76
.using16k = using16k,
77
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
78
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
79
ARMMMUIdx mmu_idx, bool data)
80
{
81
- return aa64_va_parameters_both(env, va, mmu_idx);
82
+ ARMVAParameters ret = aa64_va_parameters_both(env, va, mmu_idx);
83
+
84
+ /* Present TBI as a composite with TBID. */
85
+ ret.tbi &= (data || !ret.tbid);
86
+ return ret;
87
}
88
89
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
90
--
62
--
91
2.20.1
63
2.25.1
92
64
93
65
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Rename arm_ccnt_enabled to pmu_counter_enabled, and add logic to only
3
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
4
return 'true' if the specified counter is enabled and neither prohibited
4
Message-id: 20221206102504.165775-6-tobias.roehmel@rwth-aachen.de
5
or filtered.
6
7
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
8
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
9
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
11
Message-id: 20181211151945.29137-5-aaron@os.amperecomputing.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
6
---
14
target/arm/cpu.h | 10 ++++-
7
target/arm/cpu.h | 6 +
15
target/arm/cpu.c | 3 ++
8
target/arm/cpu.c | 28 +++-
16
target/arm/helper.c | 96 +++++++++++++++++++++++++++++++++++++++++----
9
target/arm/helper.c | 302 +++++++++++++++++++++++++++++++++++++++++++
17
3 files changed, 101 insertions(+), 8 deletions(-)
10
target/arm/machine.c | 28 ++++
11
4 files changed, 360 insertions(+), 4 deletions(-)
18
12
19
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/target/arm/cpu.h
15
--- a/target/arm/cpu.h
22
+++ b/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
23
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env);
17
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
24
void pmu_op_start(CPUARMState *env);
18
};
25
void pmu_op_finish(CPUARMState *env);
19
uint64_t sctlr_el[4];
26
20
};
27
+/**
21
+ uint64_t vsctlr; /* Virtualization System control register. */
28
+ * Functions to register as EL change hooks for PMU mode filtering
22
uint64_t cpacr_el1; /* Architectural feature access control register */
29
+ */
23
uint64_t cptr_el[4]; /* ARMv8 feature trap registers */
30
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored);
24
uint32_t c1_xscaleauxcr; /* XScale auxiliary control register. */
31
+void pmu_post_el_change(ARMCPU *cpu, void *ignored);
25
@@ -XXX,XX +XXX,XX @@ typedef struct CPUArchState {
32
+
26
*/
33
/* SCTLR bit meanings. Several bits have been reused in newer
27
uint32_t *rbar[M_REG_NUM_BANKS];
34
* versions of the architecture; in that case we define constants
28
uint32_t *rlar[M_REG_NUM_BANKS];
35
* for both old and new bit meanings. Code which tests against those
29
+ uint32_t *hprbar;
36
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
30
+ uint32_t *hprlar;
37
31
uint32_t mair0[M_REG_NUM_BANKS];
38
#define MDCR_EPMAD (1U << 21)
32
uint32_t mair1[M_REG_NUM_BANKS];
39
#define MDCR_EDAD (1U << 20)
33
+ uint32_t hprselr;
40
-#define MDCR_SPME (1U << 17)
34
} pmsav8;
41
+#define MDCR_SPME (1U << 17) /* MDCR_EL3 */
35
42
+#define MDCR_HPMD (1U << 17) /* MDCR_EL2 */
36
/* v8M SAU */
43
#define MDCR_SDD (1U << 16)
37
@@ -XXX,XX +XXX,XX @@ struct ArchCPU {
44
#define MDCR_SPD (3U << 14)
38
bool has_mpu;
45
#define MDCR_TDRA (1U << 11)
39
/* PMSAv7 MPU number of supported regions */
46
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env);
40
uint32_t pmsav7_dregion;
47
#define MDCR_HPME (1U << 7)
41
+ /* PMSAv8 MPU number of supported hyp regions */
48
#define MDCR_TPM (1U << 6)
42
+ uint32_t pmsav8r_hdregion;
49
#define MDCR_TPMCR (1U << 5)
43
/* v8M SAU number of supported regions */
50
+#define MDCR_HPMN (0x1fU)
44
uint32_t sau_sregion;
51
45
52
/* Not all of the MDCR_EL3 bits are present in the 32-bit SDCR */
53
#define SDCR_VALID_MASK (MDCR_EPMAD | MDCR_EDAD | MDCR_SPME | MDCR_SPD)
54
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
46
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
55
index XXXXXXX..XXXXXXX 100644
47
index XXXXXXX..XXXXXXX 100644
56
--- a/target/arm/cpu.c
48
--- a/target/arm/cpu.c
57
+++ b/target/arm/cpu.c
49
+++ b/target/arm/cpu.c
50
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset_hold(Object *obj)
51
sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
52
}
53
}
54
+
55
+ if (cpu->pmsav8r_hdregion > 0) {
56
+ memset(env->pmsav8.hprbar, 0,
57
+ sizeof(*env->pmsav8.hprbar) * cpu->pmsav8r_hdregion);
58
+ memset(env->pmsav8.hprlar, 0,
59
+ sizeof(*env->pmsav8.hprlar) * cpu->pmsav8r_hdregion);
60
+ }
61
+
62
env->pmsav7.rnr[M_REG_NS] = 0;
63
env->pmsav7.rnr[M_REG_S] = 0;
64
env->pmsav8.mair0[M_REG_NS] = 0;
58
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
65
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
59
if (!cpu->has_pmu) {
66
/* MPU can be configured out of a PMSA CPU either by setting has-mpu
60
unset_feature(env, ARM_FEATURE_PMU);
67
* to false or by setting pmsav7-dregion to 0.
61
cpu->id_aa64dfr0 &= ~0xf00;
68
*/
62
+ } else if (!kvm_enabled()) {
69
- if (!cpu->has_mpu) {
63
+ arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
70
- cpu->pmsav7_dregion = 0;
64
+ arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
71
- }
72
- if (cpu->pmsav7_dregion == 0) {
73
+ if (!cpu->has_mpu || cpu->pmsav7_dregion == 0) {
74
cpu->has_mpu = false;
75
+ cpu->pmsav7_dregion = 0;
76
+ cpu->pmsav8r_hdregion = 0;
65
}
77
}
66
78
67
if (!arm_feature(env, ARM_FEATURE_EL2)) {
79
if (arm_feature(env, ARM_FEATURE_PMSA) &&
80
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
81
env->pmsav7.dracr = g_new0(uint32_t, nr);
82
}
83
}
84
+
85
+ if (cpu->pmsav8r_hdregion > 0xff) {
86
+ error_setg(errp, "PMSAv8 MPU EL2 #regions invalid %" PRIu32,
87
+ cpu->pmsav8r_hdregion);
88
+ return;
89
+ }
90
+
91
+ if (cpu->pmsav8r_hdregion) {
92
+ env->pmsav8.hprbar = g_new0(uint32_t,
93
+ cpu->pmsav8r_hdregion);
94
+ env->pmsav8.hprlar = g_new0(uint32_t,
95
+ cpu->pmsav8r_hdregion);
96
+ }
97
}
98
99
if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
68
diff --git a/target/arm/helper.c b/target/arm/helper.c
100
diff --git a/target/arm/helper.c b/target/arm/helper.c
69
index XXXXXXX..XXXXXXX 100644
101
index XXXXXXX..XXXXXXX 100644
70
--- a/target/arm/helper.c
102
--- a/target/arm/helper.c
71
+++ b/target/arm/helper.c
103
+++ b/target/arm/helper.c
72
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
104
@@ -XXX,XX +XXX,XX @@ static void pmsav7_rgnr_write(CPUARMState *env, const ARMCPRegInfo *ri,
73
/* Definitions for the PMU registers */
105
raw_write(env, ri, value);
74
#define PMCRN_MASK 0xf800
75
#define PMCRN_SHIFT 11
76
+#define PMCRDP 0x10
77
#define PMCRD 0x8
78
#define PMCRC 0x4
79
#define PMCRE 0x1
80
81
+#define PMXEVTYPER_P 0x80000000
82
+#define PMXEVTYPER_U 0x40000000
83
+#define PMXEVTYPER_NSK 0x20000000
84
+#define PMXEVTYPER_NSU 0x10000000
85
+#define PMXEVTYPER_NSH 0x08000000
86
+#define PMXEVTYPER_M 0x04000000
87
+#define PMXEVTYPER_MT 0x02000000
88
+#define PMXEVTYPER_EVTCOUNT 0x0000ffff
89
+#define PMXEVTYPER_MASK (PMXEVTYPER_P | PMXEVTYPER_U | PMXEVTYPER_NSK | \
90
+ PMXEVTYPER_NSU | PMXEVTYPER_NSH | \
91
+ PMXEVTYPER_M | PMXEVTYPER_MT | \
92
+ PMXEVTYPER_EVTCOUNT)
93
+
94
static inline uint32_t pmu_num_counters(CPUARMState *env)
95
{
96
return (env->cp15.c9_pmcr & PMCRN_MASK) >> PMCRN_SHIFT;
97
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
98
return pmreg_access(env, ri, isread);
99
}
106
}
100
107
101
-static inline bool arm_ccnt_enabled(CPUARMState *env)
108
+static void prbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
102
+/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
109
+ uint64_t value)
103
+ * the current EL, security state, and register configuration.
110
+{
104
+ */
111
+ ARMCPU *cpu = env_archcpu(env);
105
+static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
112
+
106
{
113
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
107
- /* This does not support checking PMCCFILTR_EL0 register */
114
+ env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
108
+ uint64_t filter;
115
+}
109
+ bool e, p, u, nsk, nsu, nsh, m;
116
+
110
+ bool enabled, prohibited, filtered;
117
+static uint64_t prbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
111
+ bool secure = arm_is_secure(env);
118
+{
112
+ int el = arm_current_el(env);
119
+ return env->pmsav8.rbar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
113
+ uint8_t hpmn = env->cp15.mdcr_el2 & MDCR_HPMN;
120
+}
114
121
+
115
- if (!(env->cp15.c9_pmcr & PMCRE) || !(env->cp15.c9_pmcnten & (1 << 31))) {
122
+static void prlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
116
- return false;
123
+ uint64_t value)
117
+ if (!arm_feature(env, ARM_FEATURE_EL2) ||
124
+{
118
+ (counter < hpmn || counter == 31)) {
125
+ ARMCPU *cpu = env_archcpu(env);
119
+ e = env->cp15.c9_pmcr & PMCRE;
126
+
127
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
128
+ env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]] = value;
129
+}
130
+
131
+static uint64_t prlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
132
+{
133
+ return env->pmsav8.rlar[M_REG_NS][env->pmsav7.rnr[M_REG_NS]];
134
+}
135
+
136
+static void prselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
137
+ uint64_t value)
138
+{
139
+ ARMCPU *cpu = env_archcpu(env);
140
+
141
+ /*
142
+ * Ignore writes that would select not implemented region.
143
+ * This is architecturally UNPREDICTABLE.
144
+ */
145
+ if (value >= cpu->pmsav7_dregion) {
146
+ return;
147
+ }
148
+
149
+ env->pmsav7.rnr[M_REG_NS] = value;
150
+}
151
+
152
+static void hprbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
153
+ uint64_t value)
154
+{
155
+ ARMCPU *cpu = env_archcpu(env);
156
+
157
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
158
+ env->pmsav8.hprbar[env->pmsav8.hprselr] = value;
159
+}
160
+
161
+static uint64_t hprbar_read(CPUARMState *env, const ARMCPRegInfo *ri)
162
+{
163
+ return env->pmsav8.hprbar[env->pmsav8.hprselr];
164
+}
165
+
166
+static void hprlar_write(CPUARMState *env, const ARMCPRegInfo *ri,
167
+ uint64_t value)
168
+{
169
+ ARMCPU *cpu = env_archcpu(env);
170
+
171
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
172
+ env->pmsav8.hprlar[env->pmsav8.hprselr] = value;
173
+}
174
+
175
+static uint64_t hprlar_read(CPUARMState *env, const ARMCPRegInfo *ri)
176
+{
177
+ return env->pmsav8.hprlar[env->pmsav8.hprselr];
178
+}
179
+
180
+static void hprenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
181
+ uint64_t value)
182
+{
183
+ uint32_t n;
184
+ uint32_t bit;
185
+ ARMCPU *cpu = env_archcpu(env);
186
+
187
+ /* Ignore writes to unimplemented regions */
188
+ int rmax = MIN(cpu->pmsav8r_hdregion, 32);
189
+ value &= MAKE_64BIT_MASK(0, rmax);
190
+
191
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
192
+
193
+ /* Register alias is only valid for first 32 indexes */
194
+ for (n = 0; n < rmax; ++n) {
195
+ bit = extract32(value, n, 1);
196
+ env->pmsav8.hprlar[n] = deposit32(
197
+ env->pmsav8.hprlar[n], 0, 1, bit);
198
+ }
199
+}
200
+
201
+static uint64_t hprenr_read(CPUARMState *env, const ARMCPRegInfo *ri)
202
+{
203
+ uint32_t n;
204
+ uint32_t result = 0x0;
205
+ ARMCPU *cpu = env_archcpu(env);
206
+
207
+ /* Register alias is only valid for first 32 indexes */
208
+ for (n = 0; n < MIN(cpu->pmsav8r_hdregion, 32); ++n) {
209
+ if (env->pmsav8.hprlar[n] & 0x1) {
210
+ result |= (0x1 << n);
211
+ }
212
+ }
213
+ return result;
214
+}
215
+
216
+static void hprselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
217
+ uint64_t value)
218
+{
219
+ ARMCPU *cpu = env_archcpu(env);
220
+
221
+ /*
222
+ * Ignore writes that would select not implemented region.
223
+ * This is architecturally UNPREDICTABLE.
224
+ */
225
+ if (value >= cpu->pmsav8r_hdregion) {
226
+ return;
227
+ }
228
+
229
+ env->pmsav8.hprselr = value;
230
+}
231
+
232
+static void pmsav8r_regn_write(CPUARMState *env, const ARMCPRegInfo *ri,
233
+ uint64_t value)
234
+{
235
+ ARMCPU *cpu = env_archcpu(env);
236
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
237
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
238
+
239
+ tlb_flush(CPU(cpu)); /* Mappings may have changed - purge! */
240
+
241
+ if (ri->opc1 & 4) {
242
+ if (index >= cpu->pmsav8r_hdregion) {
243
+ return;
244
+ }
245
+ if (ri->opc2 & 0x1) {
246
+ env->pmsav8.hprlar[index] = value;
247
+ } else {
248
+ env->pmsav8.hprbar[index] = value;
249
+ }
120
+ } else {
250
+ } else {
121
+ e = env->cp15.mdcr_el2 & MDCR_HPME;
251
+ if (index >= cpu->pmsav7_dregion) {
122
+ }
252
+ return;
123
+ enabled = e && (env->cp15.c9_pmcnten & (1 << counter));
253
+ }
124
+
254
+ if (ri->opc2 & 0x1) {
125
+ if (!secure) {
255
+ env->pmsav8.rlar[M_REG_NS][index] = value;
126
+ if (el == 2 && (counter < hpmn || counter == 31)) {
127
+ prohibited = env->cp15.mdcr_el2 & MDCR_HPMD;
128
+ } else {
256
+ } else {
129
+ prohibited = false;
257
+ env->pmsav8.rbar[M_REG_NS][index] = value;
258
+ }
259
+ }
260
+}
261
+
262
+static uint64_t pmsav8r_regn_read(CPUARMState *env, const ARMCPRegInfo *ri)
263
+{
264
+ ARMCPU *cpu = env_archcpu(env);
265
+ uint8_t index = (extract32(ri->opc0, 0, 1) << 4) |
266
+ (extract32(ri->crm, 0, 3) << 1) | extract32(ri->opc2, 2, 1);
267
+
268
+ if (ri->opc1 & 4) {
269
+ if (index >= cpu->pmsav8r_hdregion) {
270
+ return 0x0;
271
+ }
272
+ if (ri->opc2 & 0x1) {
273
+ return env->pmsav8.hprlar[index];
274
+ } else {
275
+ return env->pmsav8.hprbar[index];
130
+ }
276
+ }
131
+ } else {
277
+ } else {
132
+ prohibited = arm_feature(env, ARM_FEATURE_EL3) &&
278
+ if (index >= cpu->pmsav7_dregion) {
133
+ (env->cp15.mdcr_el3 & MDCR_SPME);
279
+ return 0x0;
280
+ }
281
+ if (ri->opc2 & 0x1) {
282
+ return env->pmsav8.rlar[M_REG_NS][index];
283
+ } else {
284
+ return env->pmsav8.rbar[M_REG_NS][index];
285
+ }
286
+ }
287
+}
288
+
289
+static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
290
+ { .name = "PRBAR",
291
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 0,
292
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
293
+ .accessfn = access_tvm_trvm,
294
+ .readfn = prbar_read, .writefn = prbar_write },
295
+ { .name = "PRLAR",
296
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 3, .opc2 = 1,
297
+ .access = PL1_RW, .type = ARM_CP_NO_RAW,
298
+ .accessfn = access_tvm_trvm,
299
+ .readfn = prlar_read, .writefn = prlar_write },
300
+ { .name = "PRSELR", .resetvalue = 0,
301
+ .cp = 15, .opc1 = 0, .crn = 6, .crm = 2, .opc2 = 1,
302
+ .access = PL1_RW, .accessfn = access_tvm_trvm,
303
+ .writefn = prselr_write,
304
+ .fieldoffset = offsetof(CPUARMState, pmsav7.rnr[M_REG_NS]) },
305
+ { .name = "HPRBAR", .resetvalue = 0,
306
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 0,
307
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
308
+ .readfn = hprbar_read, .writefn = hprbar_write },
309
+ { .name = "HPRLAR",
310
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 3, .opc2 = 1,
311
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
312
+ .readfn = hprlar_read, .writefn = hprlar_write },
313
+ { .name = "HPRSELR", .resetvalue = 0,
314
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 2, .opc2 = 1,
315
+ .access = PL2_RW,
316
+ .writefn = hprselr_write,
317
+ .fieldoffset = offsetof(CPUARMState, pmsav8.hprselr) },
318
+ { .name = "HPRENR",
319
+ .cp = 15, .opc1 = 4, .crn = 6, .crm = 1, .opc2 = 1,
320
+ .access = PL2_RW, .type = ARM_CP_NO_RAW,
321
+ .readfn = hprenr_read, .writefn = hprenr_write },
322
+};
323
+
324
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
325
/* Reset for all these registers is handled in arm_cpu_reset(),
326
* because the PMSAv7 is also used by M-profile CPUs, which do
327
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
328
.access = PL1_R, .type = ARM_CP_CONST,
329
.resetvalue = cpu->pmsav7_dregion << 8
330
};
331
+ /* HMPUIR is specific to PMSA V8 */
332
+ ARMCPRegInfo id_hmpuir_reginfo = {
333
+ .name = "HMPUIR",
334
+ .cp = 15, .opc1 = 4, .crn = 0, .crm = 0, .opc2 = 4,
335
+ .access = PL2_R, .type = ARM_CP_CONST,
336
+ .resetvalue = cpu->pmsav8r_hdregion
337
+ };
338
static const ARMCPRegInfo crn0_wi_reginfo = {
339
.name = "CRN0_WI", .cp = 15, .crn = 0, .crm = CP_ANY,
340
.opc1 = CP_ANY, .opc2 = CP_ANY, .access = PL1_W,
341
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
342
define_arm_cp_regs(cpu, id_cp_reginfo);
343
if (!arm_feature(env, ARM_FEATURE_PMSA)) {
344
define_one_arm_cp_reg(cpu, &id_tlbtr_reginfo);
345
+ } else if (arm_feature(env, ARM_FEATURE_PMSA) &&
346
+ arm_feature(env, ARM_FEATURE_V8)) {
347
+ uint32_t i = 0;
348
+ char *tmp_string;
349
+
350
+ define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
351
+ define_one_arm_cp_reg(cpu, &id_hmpuir_reginfo);
352
+ define_arm_cp_regs(cpu, pmsav8r_cp_reginfo);
353
+
354
+ /* Register alias is only valid for first 32 indexes */
355
+ for (i = 0; i < MIN(cpu->pmsav7_dregion, 32); ++i) {
356
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
357
+ uint8_t opc1 = extract32(i, 4, 1);
358
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
359
+
360
+ tmp_string = g_strdup_printf("PRBAR%u", i);
361
+ ARMCPRegInfo tmp_prbarn_reginfo = {
362
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
363
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
364
+ .access = PL1_RW, .resetvalue = 0,
365
+ .accessfn = access_tvm_trvm,
366
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
367
+ };
368
+ define_one_arm_cp_reg(cpu, &tmp_prbarn_reginfo);
369
+ g_free(tmp_string);
370
+
371
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
372
+ tmp_string = g_strdup_printf("PRLAR%u", i);
373
+ ARMCPRegInfo tmp_prlarn_reginfo = {
374
+ .name = tmp_string, .type = ARM_CP_ALIAS | ARM_CP_NO_RAW,
375
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
376
+ .access = PL1_RW, .resetvalue = 0,
377
+ .accessfn = access_tvm_trvm,
378
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
379
+ };
380
+ define_one_arm_cp_reg(cpu, &tmp_prlarn_reginfo);
381
+ g_free(tmp_string);
382
+ }
383
+
384
+ /* Register alias is only valid for first 32 indexes */
385
+ for (i = 0; i < MIN(cpu->pmsav8r_hdregion, 32); ++i) {
386
+ uint8_t crm = 0b1000 | extract32(i, 1, 3);
387
+ uint8_t opc1 = 0b100 | extract32(i, 4, 1);
388
+ uint8_t opc2 = extract32(i, 0, 1) << 2;
389
+
390
+ tmp_string = g_strdup_printf("HPRBAR%u", i);
391
+ ARMCPRegInfo tmp_hprbarn_reginfo = {
392
+ .name = tmp_string,
393
+ .type = ARM_CP_NO_RAW,
394
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
395
+ .access = PL2_RW, .resetvalue = 0,
396
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
397
+ };
398
+ define_one_arm_cp_reg(cpu, &tmp_hprbarn_reginfo);
399
+ g_free(tmp_string);
400
+
401
+ opc2 = extract32(i, 0, 1) << 2 | 0x1;
402
+ tmp_string = g_strdup_printf("HPRLAR%u", i);
403
+ ARMCPRegInfo tmp_hprlarn_reginfo = {
404
+ .name = tmp_string,
405
+ .type = ARM_CP_NO_RAW,
406
+ .cp = 15, .opc1 = opc1, .crn = 6, .crm = crm, .opc2 = opc2,
407
+ .access = PL2_RW, .resetvalue = 0,
408
+ .writefn = pmsav8r_regn_write, .readfn = pmsav8r_regn_read
409
+ };
410
+ define_one_arm_cp_reg(cpu, &tmp_hprlarn_reginfo);
411
+ g_free(tmp_string);
412
+ }
413
} else if (arm_feature(env, ARM_FEATURE_V7)) {
414
define_one_arm_cp_reg(cpu, &id_mpuir_reginfo);
415
}
416
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
417
sctlr.type |= ARM_CP_SUPPRESS_TB_END;
418
}
419
define_one_arm_cp_reg(cpu, &sctlr);
420
+
421
+ if (arm_feature(env, ARM_FEATURE_PMSA) &&
422
+ arm_feature(env, ARM_FEATURE_V8)) {
423
+ ARMCPRegInfo vsctlr = {
424
+ .name = "VSCTLR", .state = ARM_CP_STATE_AA32,
425
+ .cp = 15, .opc1 = 4, .crn = 2, .crm = 0, .opc2 = 0,
426
+ .access = PL2_RW, .resetvalue = 0x0,
427
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.vsctlr),
428
+ };
429
+ define_one_arm_cp_reg(cpu, &vsctlr);
430
+ }
134
}
431
}
135
432
136
- return true;
433
if (cpu_isar_feature(aa64_lor, cpu)) {
137
+ if (prohibited && counter == 31) {
434
diff --git a/target/arm/machine.c b/target/arm/machine.c
138
+ prohibited = env->cp15.c9_pmcr & PMCRDP;
435
index XXXXXXX..XXXXXXX 100644
139
+ }
436
--- a/target/arm/machine.c
140
+
437
+++ b/target/arm/machine.c
141
+ /* TODO Remove assert, set filter to correct PMEVTYPER */
438
@@ -XXX,XX +XXX,XX @@ static bool pmsav8_needed(void *opaque)
142
+ assert(counter == 31);
439
arm_feature(env, ARM_FEATURE_V8);
143
+ filter = env->cp15.pmccfiltr_el0;
144
+
145
+ p = filter & PMXEVTYPER_P;
146
+ u = filter & PMXEVTYPER_U;
147
+ nsk = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSK);
148
+ nsu = arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_NSU);
149
+ nsh = arm_feature(env, ARM_FEATURE_EL2) && (filter & PMXEVTYPER_NSH);
150
+ m = arm_el_is_aa64(env, 1) &&
151
+ arm_feature(env, ARM_FEATURE_EL3) && (filter & PMXEVTYPER_M);
152
+
153
+ if (el == 0) {
154
+ filtered = secure ? u : u != nsu;
155
+ } else if (el == 1) {
156
+ filtered = secure ? p : p != nsk;
157
+ } else if (el == 2) {
158
+ filtered = !nsh;
159
+ } else { /* EL3 */
160
+ filtered = m != p;
161
+ }
162
+
163
+ return enabled && !prohibited && !filtered;
164
}
440
}
165
+
441
166
/*
442
+static bool pmsav8r_needed(void *opaque)
167
* Ensure c15_ccnt is the guest-visible count so that operations such as
443
+{
168
* enabling/disabling the counter or filtering, modifying the count itself,
444
+ ARMCPU *cpu = opaque;
169
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
445
+ CPUARMState *env = &cpu->env;
170
cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
446
+
171
ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
447
+ return arm_feature(env, ARM_FEATURE_PMSA) &&
172
448
+ arm_feature(env, ARM_FEATURE_V8) &&
173
- if (arm_ccnt_enabled(env)) {
449
+ !arm_feature(env, ARM_FEATURE_M);
174
+ if (pmu_counter_enabled(env, 31)) {
450
+}
175
uint64_t eff_cycles = cycles;
451
+
176
if (env->cp15.c9_pmcr & PMCRD) {
452
+static const VMStateDescription vmstate_pmsav8r = {
177
/* Increment once every 64 processor clock cycles */
453
+ .name = "cpu/pmsav8/pmsav8r",
178
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_start(CPUARMState *env)
454
+ .version_id = 1,
179
*/
455
+ .minimum_version_id = 1,
180
void pmccntr_op_finish(CPUARMState *env)
456
+ .needed = pmsav8r_needed,
181
{
457
+ .fields = (VMStateField[]) {
182
- if (arm_ccnt_enabled(env)) {
458
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprbar, ARMCPU,
183
+ if (pmu_counter_enabled(env, 31)) {
459
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
184
uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
460
+ VMSTATE_VARRAY_UINT32(env.pmsav8.hprlar, ARMCPU,
185
461
+ pmsav8r_hdregion, 0, vmstate_info_uint32, uint32_t),
186
if (env->cp15.c9_pmcr & PMCRD) {
462
+ VMSTATE_END_OF_LIST()
187
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env)
463
+ },
188
pmccntr_op_finish(env);
464
+};
189
}
465
+
190
466
static const VMStateDescription vmstate_pmsav8 = {
191
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
467
.name = "cpu/pmsav8",
192
+{
468
.version_id = 1,
193
+ pmu_op_start(&cpu->env);
469
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_pmsav8 = {
194
+}
470
VMSTATE_UINT32(env.pmsav8.mair0[M_REG_NS], ARMCPU),
195
+
471
VMSTATE_UINT32(env.pmsav8.mair1[M_REG_NS], ARMCPU),
196
+void pmu_post_el_change(ARMCPU *cpu, void *ignored)
472
VMSTATE_END_OF_LIST()
197
+{
473
+ },
198
+ pmu_op_finish(&cpu->env);
474
+ .subsections = (const VMStateDescription * []) {
199
+}
475
+ &vmstate_pmsav8r,
200
+
476
+ NULL
201
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
477
}
202
uint64_t value)
478
};
203
{
479
204
@@ -XXX,XX +XXX,XX @@ void pmu_op_finish(CPUARMState *env)
205
{
206
}
207
208
+void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
209
+{
210
+}
211
+
212
+void pmu_post_el_change(ARMCPU *cpu, void *ignored)
213
+{
214
+}
215
+
216
#endif
217
218
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
219
--
480
--
220
2.20.1
481
2.25.1
221
482
222
483
diff view generated by jsdifflib
1
From: Cédric Le Goater <clg@kaod.org>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
The PHY behind the MAC of an Aspeed SoC can be controlled using two
3
Add PMSAv8r translation.
4
different MDC/MDIO interfaces. The same registers PHYCR (MAC60) and
4
5
PHYDATA (MAC64) are involved but they have a different layout.
5
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
6
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
BIT31 of the Feature Register (MAC40) controls which MDC/MDIO
7
Message-id: 20221206102504.165775-7-tobias.roehmel@rwth-aachen.de
8
interface is active.
9
10
Signed-off-by: Cédric Le Goater <clg@kaod.org>
11
Reviewed-by: Andrew Jeffery <andrew@aj.id.au>
12
Reviewed-by: Joel Stanley <joel@jms.id.au>
13
Message-id: 20190111125759.31577-1-clg@kaod.org
14
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
15
---
9
---
16
hw/net/ftgmac100.c | 80 +++++++++++++++++++++++++++++++++++++++-------
10
target/arm/ptw.c | 126 ++++++++++++++++++++++++++++++++++++++---------
17
1 file changed, 68 insertions(+), 12 deletions(-)
11
1 file changed, 104 insertions(+), 22 deletions(-)
18
12
19
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
13
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
20
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
21
--- a/hw/net/ftgmac100.c
15
--- a/target/arm/ptw.c
22
+++ b/hw/net/ftgmac100.c
16
+++ b/target/arm/ptw.c
23
@@ -XXX,XX +XXX,XX @@
17
@@ -XXX,XX +XXX,XX @@ static bool pmsav7_use_background_region(ARMCPU *cpu, ARMMMUIdx mmu_idx,
24
#define FTGMAC100_PHYDATA_MIIWDATA(x) ((x) & 0xffff)
18
25
#define FTGMAC100_PHYDATA_MIIRDATA(x) (((x) >> 16) & 0xffff)
19
if (arm_feature(env, ARM_FEATURE_M)) {
26
20
return env->v7m.mpu_ctrl[is_secure] & R_V7M_MPU_CTRL_PRIVDEFENA_MASK;
27
+/*
21
- } else {
28
+ * PHY control register - New MDC/MDIO interface
22
- return regime_sctlr(env, mmu_idx) & SCTLR_BR;
29
+ */
23
}
30
+#define FTGMAC100_PHYCR_NEW_DATA(x) (((x) >> 16) & 0xffff)
24
+
31
+#define FTGMAC100_PHYCR_NEW_FIRE (1 << 15)
25
+ if (mmu_idx == ARMMMUIdx_Stage2) {
32
+#define FTGMAC100_PHYCR_NEW_ST_22 (1 << 12)
26
+ return false;
33
+#define FTGMAC100_PHYCR_NEW_OP(x) (((x) >> 10) & 3)
27
+ }
34
+#define FTGMAC100_PHYCR_NEW_OP_WRITE 0x1
28
+
35
+#define FTGMAC100_PHYCR_NEW_OP_READ 0x2
29
+ return regime_sctlr(env, mmu_idx) & SCTLR_BR;
36
+#define FTGMAC100_PHYCR_NEW_DEV(x) (((x) >> 5) & 0x1f)
37
+#define FTGMAC100_PHYCR_NEW_REG(x) ((x) & 0x1f)
38
+
39
/*
40
* Feature Register
41
*/
42
@@ -XXX,XX +XXX,XX @@ static void phy_reset(FTGMAC100State *s)
43
s->phy_int = 0;
44
}
30
}
45
31
46
-static uint32_t do_phy_read(FTGMAC100State *s, int reg)
32
static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
47
+static uint16_t do_phy_read(FTGMAC100State *s, uint8_t reg)
33
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_pmsav7(CPUARMState *env, uint32_t address,
48
{
34
return !(result->f.prot & (1 << access_type));
49
- uint32_t val;
50
+ uint16_t val;
51
52
switch (reg) {
53
case MII_BMCR: /* Basic Control */
54
@@ -XXX,XX +XXX,XX @@ static uint32_t do_phy_read(FTGMAC100State *s, int reg)
55
MII_BMCR_FD | MII_BMCR_CTST)
56
#define MII_ANAR_MASK 0x2d7f
57
58
-static void do_phy_write(FTGMAC100State *s, int reg, uint32_t val)
59
+static void do_phy_write(FTGMAC100State *s, uint8_t reg, uint16_t val)
60
{
61
switch (reg) {
62
case MII_BMCR: /* Basic Control */
63
@@ -XXX,XX +XXX,XX @@ static void do_phy_write(FTGMAC100State *s, int reg, uint32_t val)
64
}
65
}
35
}
66
36
67
+static void do_phy_new_ctl(FTGMAC100State *s)
37
+static uint32_t *regime_rbar(CPUARMState *env, ARMMMUIdx mmu_idx,
38
+ uint32_t secure)
68
+{
39
+{
69
+ uint8_t reg;
40
+ if (regime_el(env, mmu_idx) == 2) {
70
+ uint16_t data;
41
+ return env->pmsav8.hprbar;
71
+
42
+ } else {
72
+ if (!(s->phycr & FTGMAC100_PHYCR_NEW_ST_22)) {
43
+ return env->pmsav8.rbar[secure];
73
+ qemu_log_mask(LOG_UNIMP, "%s: unsupported ST code\n", __func__);
44
+ }
74
+ return;
75
+ }
76
+
77
+ /* Nothing to do */
78
+ if (!(s->phycr & FTGMAC100_PHYCR_NEW_FIRE)) {
79
+ return;
80
+ }
81
+
82
+ reg = FTGMAC100_PHYCR_NEW_REG(s->phycr);
83
+ data = FTGMAC100_PHYCR_NEW_DATA(s->phycr);
84
+
85
+ switch (FTGMAC100_PHYCR_NEW_OP(s->phycr)) {
86
+ case FTGMAC100_PHYCR_NEW_OP_WRITE:
87
+ do_phy_write(s, reg, data);
88
+ break;
89
+ case FTGMAC100_PHYCR_NEW_OP_READ:
90
+ s->phydata = do_phy_read(s, reg) & 0xffff;
91
+ break;
92
+ default:
93
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid OP code %08x\n",
94
+ __func__, s->phycr);
95
+ }
96
+
97
+ s->phycr &= ~FTGMAC100_PHYCR_NEW_FIRE;
98
+}
45
+}
99
+
46
+
100
+static void do_phy_ctl(FTGMAC100State *s)
47
+static uint32_t *regime_rlar(CPUARMState *env, ARMMMUIdx mmu_idx,
48
+ uint32_t secure)
101
+{
49
+{
102
+ uint8_t reg = FTGMAC100_PHYCR_REG(s->phycr);
50
+ if (regime_el(env, mmu_idx) == 2) {
103
+
51
+ return env->pmsav8.hprlar;
104
+ if (s->phycr & FTGMAC100_PHYCR_MIIWR) {
52
+ } else {
105
+ do_phy_write(s, reg, s->phydata & 0xffff);
53
+ return env->pmsav8.rlar[secure];
106
+ s->phycr &= ~FTGMAC100_PHYCR_MIIWR;
107
+ } else if (s->phycr & FTGMAC100_PHYCR_MIIRD) {
108
+ s->phydata = do_phy_read(s, reg) << 16;
109
+ s->phycr &= ~FTGMAC100_PHYCR_MIIRD;
110
+ } else {
111
+ qemu_log_mask(LOG_GUEST_ERROR, "%s: no OP code %08x\n",
112
+ __func__, s->phycr);
113
+ }
54
+ }
114
+}
55
+}
115
+
56
+
116
static int ftgmac100_read_bd(FTGMAC100Desc *bd, dma_addr_t addr)
57
bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
117
{
58
MMUAccessType access_type, ARMMMUIdx mmu_idx,
118
if (dma_memory_read(&address_space_memory, addr, bd, sizeof(*bd))) {
59
bool secure, GetPhysAddrResult *result,
119
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
60
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
120
uint64_t value, unsigned size)
61
bool hit = false;
121
{
62
uint32_t addr_page_base = address & TARGET_PAGE_MASK;
122
FTGMAC100State *s = FTGMAC100(opaque);
63
uint32_t addr_page_limit = addr_page_base + (TARGET_PAGE_SIZE - 1);
123
- int reg;
64
+ int region_counter;
124
65
+
125
switch (addr & 0xff) {
66
+ if (regime_el(env, mmu_idx) == 2) {
126
case FTGMAC100_ISR: /* Interrupt status */
67
+ region_counter = cpu->pmsav8r_hdregion;
127
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
68
+ } else {
128
break;
69
+ region_counter = cpu->pmsav7_dregion;
129
70
+ }
130
case FTGMAC100_PHYCR: /* PHY Device control */
71
131
- reg = FTGMAC100_PHYCR_REG(value);
72
result->f.lg_page_size = TARGET_PAGE_BITS;
132
s->phycr = value;
73
result->f.phys_addr = address;
133
- if (value & FTGMAC100_PHYCR_MIIWR) {
74
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
134
- do_phy_write(s, reg, s->phydata & 0xffff);
75
*mregion = -1;
135
- s->phycr &= ~FTGMAC100_PHYCR_MIIWR;
76
}
136
+ if (s->revr & FTGMAC100_REVR_NEW_MDIO_INTERFACE) {
77
137
+ do_phy_new_ctl(s);
78
+ if (mmu_idx == ARMMMUIdx_Stage2) {
138
} else {
79
+ fi->stage2 = true;
139
- s->phydata = do_phy_read(s, reg) << 16;
80
+ }
140
- s->phycr &= ~FTGMAC100_PHYCR_MIIRD;
81
+
141
+ do_phy_ctl(s);
82
/*
142
}
83
* Unlike the ARM ARM pseudocode, we don't need to check whether this
143
break;
84
* was an exception vector read from the vector table (which is always
144
case FTGMAC100_PHYDATA:
85
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
145
@@ -XXX,XX +XXX,XX @@ static void ftgmac100_write(void *opaque, hwaddr addr,
86
hit = true;
146
s->dblac = value;
87
}
147
break;
88
148
case FTGMAC100_REVR: /* Feature Register */
89
- for (n = (int)cpu->pmsav7_dregion - 1; n >= 0; n--) {
149
- /* TODO: Only Old MDIO interface is supported */
90
+ uint32_t bitmask;
150
- s->revr = value & ~FTGMAC100_REVR_NEW_MDIO_INTERFACE;
91
+ if (arm_feature(env, ARM_FEATURE_M)) {
151
+ s->revr = value;
92
+ bitmask = 0x1f;
152
break;
93
+ } else {
153
case FTGMAC100_FEAR1: /* Feature Register 1 */
94
+ bitmask = 0x3f;
154
s->fear1 = value;
95
+ fi->level = 0;
96
+ }
97
+
98
+ for (n = region_counter - 1; n >= 0; n--) {
99
/* region search */
100
/*
101
- * Note that the base address is bits [31:5] from the register
102
- * with bits [4:0] all zeroes, but the limit address is bits
103
- * [31:5] from the register with bits [4:0] all ones.
104
+ * Note that the base address is bits [31:x] from the register
105
+ * with bits [x-1:0] all zeroes, but the limit address is bits
106
+ * [31:x] from the register with bits [x:0] all ones. Where x is
107
+ * 5 for Cortex-M and 6 for Cortex-R
108
*/
109
- uint32_t base = env->pmsav8.rbar[secure][n] & ~0x1f;
110
- uint32_t limit = env->pmsav8.rlar[secure][n] | 0x1f;
111
+ uint32_t base = regime_rbar(env, mmu_idx, secure)[n] & ~bitmask;
112
+ uint32_t limit = regime_rlar(env, mmu_idx, secure)[n] | bitmask;
113
114
- if (!(env->pmsav8.rlar[secure][n] & 0x1)) {
115
+ if (!(regime_rlar(env, mmu_idx, secure)[n] & 0x1)) {
116
/* Region disabled */
117
continue;
118
}
119
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
120
* PMSAv7 where highest-numbered-region wins)
121
*/
122
fi->type = ARMFault_Permission;
123
- fi->level = 1;
124
+ if (arm_feature(env, ARM_FEATURE_M)) {
125
+ fi->level = 1;
126
+ }
127
return true;
128
}
129
130
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
131
}
132
133
if (!hit) {
134
- /* background fault */
135
- fi->type = ARMFault_Background;
136
+ if (arm_feature(env, ARM_FEATURE_M)) {
137
+ fi->type = ARMFault_Background;
138
+ } else {
139
+ fi->type = ARMFault_Permission;
140
+ }
141
return true;
142
}
143
144
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
145
/* hit using the background region */
146
get_phys_addr_pmsav7_default(env, mmu_idx, address, &result->f.prot);
147
} else {
148
- uint32_t ap = extract32(env->pmsav8.rbar[secure][matchregion], 1, 2);
149
- uint32_t xn = extract32(env->pmsav8.rbar[secure][matchregion], 0, 1);
150
+ uint32_t matched_rbar = regime_rbar(env, mmu_idx, secure)[matchregion];
151
+ uint32_t matched_rlar = regime_rlar(env, mmu_idx, secure)[matchregion];
152
+ uint32_t ap = extract32(matched_rbar, 1, 2);
153
+ uint32_t xn = extract32(matched_rbar, 0, 1);
154
bool pxn = false;
155
156
if (arm_feature(env, ARM_FEATURE_V8_1M)) {
157
- pxn = extract32(env->pmsav8.rlar[secure][matchregion], 4, 1);
158
+ pxn = extract32(matched_rlar, 4, 1);
159
}
160
161
if (m_is_system_region(env, address)) {
162
@@ -XXX,XX +XXX,XX @@ bool pmsav8_mpu_lookup(CPUARMState *env, uint32_t address,
163
xn = 1;
164
}
165
166
- result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
167
+ if (regime_el(env, mmu_idx) == 2) {
168
+ result->f.prot = simple_ap_to_rw_prot_is_user(ap,
169
+ mmu_idx != ARMMMUIdx_E2);
170
+ } else {
171
+ result->f.prot = simple_ap_to_rw_prot(env, mmu_idx, ap);
172
+ }
173
+
174
+ if (!arm_feature(env, ARM_FEATURE_M)) {
175
+ uint8_t attrindx = extract32(matched_rlar, 1, 3);
176
+ uint64_t mair = env->cp15.mair_el[regime_el(env, mmu_idx)];
177
+ uint8_t sh = extract32(matched_rlar, 3, 2);
178
+
179
+ if (regime_sctlr(env, mmu_idx) & SCTLR_WXN &&
180
+ result->f.prot & PAGE_WRITE && mmu_idx != ARMMMUIdx_Stage2) {
181
+ xn = 0x1;
182
+ }
183
+
184
+ if ((regime_el(env, mmu_idx) == 1) &&
185
+ regime_sctlr(env, mmu_idx) & SCTLR_UWXN && ap == 0x1) {
186
+ pxn = 0x1;
187
+ }
188
+
189
+ result->cacheattrs.is_s2_format = false;
190
+ result->cacheattrs.attrs = extract64(mair, attrindx * 8, 8);
191
+ result->cacheattrs.shareability = sh;
192
+ }
193
+
194
if (result->f.prot && !xn && !(pxn && !is_user)) {
195
result->f.prot |= PAGE_EXEC;
196
}
197
- /*
198
- * We don't need to look the attribute up in the MAIR0/MAIR1
199
- * registers because that only tells us about cacheability.
200
- */
201
+
202
if (mregion) {
203
*mregion = matchregion;
204
}
205
}
206
207
fi->type = ARMFault_Permission;
208
- fi->level = 1;
209
+ if (arm_feature(env, ARM_FEATURE_M)) {
210
+ fi->level = 1;
211
+ }
212
return !(result->f.prot & (1 << access_type));
213
}
214
215
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_twostage(CPUARMState *env, S1Translate *ptw,
216
cacheattrs1 = result->cacheattrs;
217
memset(result, 0, sizeof(*result));
218
219
- ret = get_phys_addr_lpae(env, ptw, ipa, access_type, is_el0, result, fi);
220
+ if (arm_feature(env, ARM_FEATURE_PMSA)) {
221
+ ret = get_phys_addr_pmsav8(env, ipa, access_type,
222
+ ptw->in_mmu_idx, is_secure, result, fi);
223
+ } else {
224
+ ret = get_phys_addr_lpae(env, ptw, ipa, access_type,
225
+ is_el0, result, fi);
226
+ }
227
fi->s2addr = ipa;
228
229
/* Combine the S1 and S2 perms. */
155
--
230
--
156
2.20.1
231
2.25.1
157
232
158
233
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
2
2
3
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
3
All constants are taken from the ARM Cortex-R52 Processor TRM Revision: r1p3
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
4
5
Message-id: 20181211151945.29137-14-aaron@os.amperecomputing.com
5
Signed-off-by: Tobias Röhmel <tobias.roehmel@rwth-aachen.de>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20221206102504.165775-8-tobias.roehmel@rwth-aachen.de
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
9
---
8
target/arm/helper.c | 39 +++++++++++++++++++++++++++++++++++++--
10
target/arm/cpu_tcg.c | 42 ++++++++++++++++++++++++++++++++++++++++++
9
1 file changed, 37 insertions(+), 2 deletions(-)
11
1 file changed, 42 insertions(+)
10
12
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
12
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
15
--- a/target/arm/cpu_tcg.c
14
+++ b/target/arm/helper.c
16
+++ b/target/arm/cpu_tcg.c
15
@@ -XXX,XX +XXX,XX @@ static bool event_always_supported(CPUARMState *env)
17
@@ -XXX,XX +XXX,XX @@ static void cortex_r5_initfn(Object *obj)
16
return true;
18
define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
17
}
19
}
18
20
19
+static uint64_t swinc_get_count(CPUARMState *env)
21
+static void cortex_r52_initfn(Object *obj)
20
+{
22
+{
21
+ /*
23
+ ARMCPU *cpu = ARM_CPU(obj);
22
+ * SW_INCR events are written directly to the pmevcntr's by writes to
24
+
23
+ * PMSWINC, so there is no underlying count maintained by the PMU itself
25
+ set_feature(&cpu->env, ARM_FEATURE_V8);
24
+ */
26
+ set_feature(&cpu->env, ARM_FEATURE_EL2);
25
+ return 0;
27
+ set_feature(&cpu->env, ARM_FEATURE_PMSA);
28
+ set_feature(&cpu->env, ARM_FEATURE_NEON);
29
+ set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
30
+ cpu->midr = 0x411fd133; /* r1p3 */
31
+ cpu->revidr = 0x00000000;
32
+ cpu->reset_fpsid = 0x41034023;
33
+ cpu->isar.mvfr0 = 0x10110222;
34
+ cpu->isar.mvfr1 = 0x12111111;
35
+ cpu->isar.mvfr2 = 0x00000043;
36
+ cpu->ctr = 0x8144c004;
37
+ cpu->reset_sctlr = 0x30c50838;
38
+ cpu->isar.id_pfr0 = 0x00000131;
39
+ cpu->isar.id_pfr1 = 0x10111001;
40
+ cpu->isar.id_dfr0 = 0x03010006;
41
+ cpu->id_afr0 = 0x00000000;
42
+ cpu->isar.id_mmfr0 = 0x00211040;
43
+ cpu->isar.id_mmfr1 = 0x40000000;
44
+ cpu->isar.id_mmfr2 = 0x01200000;
45
+ cpu->isar.id_mmfr3 = 0xf0102211;
46
+ cpu->isar.id_mmfr4 = 0x00000010;
47
+ cpu->isar.id_isar0 = 0x02101110;
48
+ cpu->isar.id_isar1 = 0x13112111;
49
+ cpu->isar.id_isar2 = 0x21232142;
50
+ cpu->isar.id_isar3 = 0x01112131;
51
+ cpu->isar.id_isar4 = 0x00010142;
52
+ cpu->isar.id_isar5 = 0x00010001;
53
+ cpu->isar.dbgdidr = 0x77168000;
54
+ cpu->clidr = (1 << 27) | (1 << 24) | 0x3;
55
+ cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
56
+ cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
57
+
58
+ cpu->pmsav7_dregion = 16;
59
+ cpu->pmsav8r_hdregion = 16;
26
+}
60
+}
27
+
61
+
28
/*
62
static void cortex_r5f_initfn(Object *obj)
29
* Return the underlying cycle count for the PMU cycle counters. If we're in
30
* usermode, simply return 0.
31
@@ -XXX,XX +XXX,XX @@ static uint64_t instructions_get_count(CPUARMState *env)
32
#endif
33
34
static const pm_event pm_events[] = {
35
+ { .number = 0x000, /* SW_INCR */
36
+ .supported = event_always_supported,
37
+ .get_count = swinc_get_count,
38
+ },
39
#ifndef CONFIG_USER_ONLY
40
{ .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
41
.supported = instructions_supported,
42
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
43
pmu_op_finish(env);
44
}
45
46
+static void pmswinc_write(CPUARMState *env, const ARMCPRegInfo *ri,
47
+ uint64_t value)
48
+{
49
+ unsigned int i;
50
+ for (i = 0; i < pmu_num_counters(env); i++) {
51
+ /* Increment a counter's count iff: */
52
+ if ((value & (1 << i)) && /* counter's bit is set */
53
+ /* counter is enabled and not filtered */
54
+ pmu_counter_enabled(env, i) &&
55
+ /* counter is SW_INCR */
56
+ (env->cp15.c14_pmevtyper[i] & PMXEVTYPER_EVTCOUNT) == 0x0) {
57
+ pmevcntr_op_start(env, i);
58
+ env->cp15.c14_pmevcntr[i]++;
59
+ pmevcntr_op_finish(env, i);
60
+ }
61
+ }
62
+}
63
+
64
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
65
{
63
{
66
uint64_t ret;
64
ARMCPU *cpu = ARM_CPU(obj);
67
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
65
@@ -XXX,XX +XXX,XX @@ static const ARMCPUInfo arm_tcg_cpus[] = {
68
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
66
.class_init = arm_v7m_class_init },
69
.writefn = pmovsr_write,
67
{ .name = "cortex-r5", .initfn = cortex_r5_initfn },
70
.raw_writefn = raw_write },
68
{ .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
71
- /* Unimplemented so WI. */
69
+ { .name = "cortex-r52", .initfn = cortex_r52_initfn },
72
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
70
{ .name = "ti925t", .initfn = ti925t_initfn },
73
- .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
71
{ .name = "sa1100", .initfn = sa1100_initfn },
74
+ .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
72
{ .name = "sa1110", .initfn = sa1110_initfn },
75
+ .writefn = pmswinc_write },
76
+ { .name = "PMSWINC_EL0", .state = ARM_CP_STATE_AA64,
77
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 4,
78
+ .access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NO_RAW,
79
+ .writefn = pmswinc_write },
80
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
81
.access = PL0_RW, .type = ARM_CP_ALIAS,
82
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
83
--
73
--
84
2.20.1
74
2.25.1
85
75
86
76
diff view generated by jsdifflib
1
From: Alexander Graf <agraf@suse.de>
1
From: Alex Bennée <alex.bennee@linaro.org>
2
2
3
In U-boot, we switch from S-SVC -> Mon -> Hyp mode when we want to
3
The check semihosting_enabled() wants to know if the guest is
4
enter Hyp mode. The change into Hyp mode is done by doing an
4
currently in user mode. Unlike the other cases the test was inverted
5
exception return from Mon. This doesn't work with current QEMU.
5
causing us to block semihosting calls in non-EL0 modes.
6
6
7
The problem is that in bad_mode_switch() we refuse to allow
7
Cc: qemu-stable@nongnu.org
8
the change of mode.
8
Fixes: 19b26317e9 (target/arm: Honour -semihosting-config userspace=on)
9
9
Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
10
Note that bad_mode_switch() is used to do validation for two situations:
11
12
(1) changes to mode by instructions writing to CPSR.M
13
(ie not exception take/return) -- this corresponds to the
14
Armv8 Arm ARM pseudocode Arch32.WriteModeByInstr
15
(2) changes to mode by exception return
16
17
Attempting to enter or leave Hyp mode via case (1) is forbidden in
18
v8 and UNPREDICTABLE in v7, and QEMU is correct to disallow it
19
there. However, we're already doing that check at the top of the
20
bad_mode_switch() function, so if that passes then we should allow
21
the case (2) exception return mode changes to switch into Hyp mode.
22
23
We want to test whether we're trying to return to the nonexistent
24
"secure Hyp" mode, so we need to look at arm_is_secure_below_el3()
25
rather than arm_is_secure(), since the latter is always true if
26
we're in Mon (EL3).
27
28
Signed-off-by: Alexander Graf <agraf@suse.de>
29
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
30
Message-id: 20190109152430.32359-1-agraf@suse.de
31
[PMM: rewrote commit message]
32
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
33
---
12
---
34
target/arm/helper.c | 2 +-
13
target/arm/translate.c | 2 +-
35
1 file changed, 1 insertion(+), 1 deletion(-)
14
1 file changed, 1 insertion(+), 1 deletion(-)
36
15
37
diff --git a/target/arm/helper.c b/target/arm/helper.c
16
diff --git a/target/arm/translate.c b/target/arm/translate.c
38
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
39
--- a/target/arm/helper.c
18
--- a/target/arm/translate.c
40
+++ b/target/arm/helper.c
19
+++ b/target/arm/translate.c
41
@@ -XXX,XX +XXX,XX @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
20
@@ -XXX,XX +XXX,XX @@ static inline void gen_hlt(DisasContext *s, int imm)
42
return 0;
21
* semihosting, to provide some semblance of security
43
case ARM_CPU_MODE_HYP:
22
* (and for consistency with our 32-bit semihosting).
44
return !arm_feature(env, ARM_FEATURE_EL2)
23
*/
45
- || arm_current_el(env) < 2 || arm_is_secure(env);
24
- if (semihosting_enabled(s->current_el != 0) &&
46
+ || arm_current_el(env) < 2 || arm_is_secure_below_el3(env);
25
+ if (semihosting_enabled(s->current_el == 0) &&
47
case ARM_CPU_MODE_MON:
26
(imm == (s->thumb ? 0x3c : 0xf000))) {
48
return arm_current_el(env) < 3;
27
gen_exception_internal_insn(s, EXCP_SEMIHOST);
49
default:
28
return;
50
--
29
--
51
2.20.1
30
2.25.1
52
31
53
32
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Fix typos, add background information
4
5
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-29-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
---
8
target/arm/helper.c | 70 +++++++++++++++++++++++++++++++++++++++++++++
9
hw/timer/imx_epit.c | 20 ++++++++++++++++----
9
1 file changed, 70 insertions(+)
10
1 file changed, 16 insertions(+), 4 deletions(-)
10
11
11
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
12
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/helper.c
14
--- a/hw/timer/imx_epit.c
14
+++ b/target/arm/helper.c
15
+++ b/hw/timer/imx_epit.c
15
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_lor_other(CPUARMState *env,
16
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
16
return access_lor_ns(env);
17
}
17
}
18
}
18
19
19
+#ifdef TARGET_AARCH64
20
+/*
20
+static CPAccessResult access_pauth(CPUARMState *env, const ARMCPRegInfo *ri,
21
+ * This is called both on hardware (device) reset and software reset.
21
+ bool isread)
22
+ */
22
+{
23
static void imx_epit_reset(DeviceState *dev)
23
+ int el = arm_current_el(env);
24
+
25
+ if (el < 2 &&
26
+ arm_feature(env, ARM_FEATURE_EL2) &&
27
+ !(arm_hcr_el2_eff(env) & HCR_APK)) {
28
+ return CP_ACCESS_TRAP_EL2;
29
+ }
30
+ if (el < 3 &&
31
+ arm_feature(env, ARM_FEATURE_EL3) &&
32
+ !(env->cp15.scr_el3 & SCR_APK)) {
33
+ return CP_ACCESS_TRAP_EL3;
34
+ }
35
+ return CP_ACCESS_OK;
36
+}
37
+
38
+static const ARMCPRegInfo pauth_reginfo[] = {
39
+ { .name = "APDAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
40
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 0,
41
+ .access = PL1_RW, .accessfn = access_pauth,
42
+ .fieldoffset = offsetof(CPUARMState, apda_key.lo) },
43
+ { .name = "APDAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
44
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 1,
45
+ .access = PL1_RW, .accessfn = access_pauth,
46
+ .fieldoffset = offsetof(CPUARMState, apda_key.hi) },
47
+ { .name = "APDBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
48
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 2,
49
+ .access = PL1_RW, .accessfn = access_pauth,
50
+ .fieldoffset = offsetof(CPUARMState, apdb_key.lo) },
51
+ { .name = "APDBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
52
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 2, .opc2 = 3,
53
+ .access = PL1_RW, .accessfn = access_pauth,
54
+ .fieldoffset = offsetof(CPUARMState, apdb_key.hi) },
55
+ { .name = "APGAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
56
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 0,
57
+ .access = PL1_RW, .accessfn = access_pauth,
58
+ .fieldoffset = offsetof(CPUARMState, apga_key.lo) },
59
+ { .name = "APGAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
60
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 3, .opc2 = 1,
61
+ .access = PL1_RW, .accessfn = access_pauth,
62
+ .fieldoffset = offsetof(CPUARMState, apga_key.hi) },
63
+ { .name = "APIAKEYLO_EL1", .state = ARM_CP_STATE_AA64,
64
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 0,
65
+ .access = PL1_RW, .accessfn = access_pauth,
66
+ .fieldoffset = offsetof(CPUARMState, apia_key.lo) },
67
+ { .name = "APIAKEYHI_EL1", .state = ARM_CP_STATE_AA64,
68
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 1,
69
+ .access = PL1_RW, .accessfn = access_pauth,
70
+ .fieldoffset = offsetof(CPUARMState, apia_key.hi) },
71
+ { .name = "APIBKEYLO_EL1", .state = ARM_CP_STATE_AA64,
72
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 2,
73
+ .access = PL1_RW, .accessfn = access_pauth,
74
+ .fieldoffset = offsetof(CPUARMState, apib_key.lo) },
75
+ { .name = "APIBKEYHI_EL1", .state = ARM_CP_STATE_AA64,
76
+ .opc0 = 3, .opc1 = 0, .crn = 2, .crm = 1, .opc2 = 3,
77
+ .access = PL1_RW, .accessfn = access_pauth,
78
+ .fieldoffset = offsetof(CPUARMState, apib_key.hi) },
79
+ REGINFO_SENTINEL
80
+};
81
+#endif
82
+
83
void register_cp_regs_for_features(ARMCPU *cpu)
84
{
24
{
85
/* Register all the coprocessor registers based on feature bits */
25
IMXEPITState *s = IMX_EPIT(dev);
86
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
26
87
define_one_arm_cp_reg(cpu, &zcr_el3_reginfo);
27
- /*
28
- * Soft reset doesn't touch some bits; hard reset clears them
29
- */
30
+ /* Soft reset doesn't touch some bits; hard reset clears them */
31
s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
32
s->sr = 0;
33
s->lr = EPIT_TIMER_MAX;
34
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
35
ptimer_transaction_begin(s->timer_cmp);
36
ptimer_transaction_begin(s->timer_reload);
37
38
+ /* Update the frequency. Has been done already in case of a reset. */
39
if (!(s->cr & CR_SWR)) {
40
imx_epit_set_freq(s);
88
}
41
}
89
}
42
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
90
+
43
break;
91
+#ifdef TARGET_AARCH64
44
92
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
45
case 1: /* SR - ACK*/
93
+ define_arm_cp_regs(cpu, pauth_reginfo);
46
- /* writing 1 to OCIF clear the OCIF bit */
94
+ }
47
+ /* writing 1 to OCIF clears the OCIF bit */
95
+#endif
48
if (value & 0x01) {
49
s->sr = 0;
50
imx_epit_update_int(s);
51
@@ -XXX,XX +XXX,XX @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
52
0x00001000);
53
sysbus_init_mmio(sbd, &s->iomem);
54
55
+ /*
56
+ * The reload timer keeps running when the peripheral is enabled. It is a
57
+ * kind of wall clock that does not generate any interrupts. The callback
58
+ * needs to be provided, but it does nothing as the ptimer already supports
59
+ * all necessary reloading functionality.
60
+ */
61
s->timer_reload = ptimer_init(imx_epit_reload, s, PTIMER_POLICY_LEGACY);
62
63
+ /*
64
+ * The compare timer is running only when the peripheral configuration is
65
+ * in a state that will generate compare interrupts.
66
+ */
67
s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
96
}
68
}
97
69
98
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu)
99
--
70
--
100
2.20.1
71
2.25.1
101
102
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
This both advertises that we support four counters and enables them
3
remove unused defines, add needed defines
4
because the pmu_num_counters() reads this value from PMCR.
5
4
6
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
5
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20181211151945.29137-13-aaron@os.amperecomputing.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/helper.c | 10 +++++-----
9
include/hw/timer/imx_epit.h | 4 ++--
13
1 file changed, 5 insertions(+), 5 deletions(-)
10
hw/timer/imx_epit.c | 4 ++--
11
2 files changed, 4 insertions(+), 4 deletions(-)
14
12
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
13
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
16
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/helper.c
15
--- a/include/hw/timer/imx_epit.h
18
+++ b/target/arm/helper.c
16
+++ b/include/hw/timer/imx_epit.h
19
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
17
@@ -XXX,XX +XXX,XX @@
20
.access = PL1_W, .type = ARM_CP_NOP },
18
#define CR_OCIEN (1 << 2)
21
/* Performance monitors are implementation defined in v7,
19
#define CR_RLD (1 << 3)
22
* but with an ARM recommended set of registers, which we
20
#define CR_PRESCALE_SHIFT (4)
23
- * follow (although we don't actually implement any counters)
21
-#define CR_PRESCALE_MASK (0xfff)
24
+ * follow.
22
+#define CR_PRESCALE_BITS (12)
25
*
23
#define CR_SWR (1 << 16)
26
* Performance registers fall into three categories:
24
#define CR_IOVW (1 << 17)
27
* (a) always UNDEF in PL0, RW in PL1 (PMINTENSET, PMINTENCLR)
25
#define CR_DBGEN (1 << 18)
28
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
26
@@ -XXX,XX +XXX,XX @@
29
}
27
#define CR_DOZEN (1 << 20)
30
if (arm_feature(env, ARM_FEATURE_V7)) {
28
#define CR_STOPEN (1 << 21)
31
/* v7 performance monitor control register: same implementor
29
#define CR_CLKSRC_SHIFT (24)
32
- * field as main ID register, and we implement only the cycle
30
-#define CR_CLKSRC_MASK (0x3 << CR_CLKSRC_SHIFT)
33
- * count register.
31
+#define CR_CLKSRC_BITS (2)
34
+ * field as main ID register, and we implement four counters in
32
35
+ * addition to the cycle count register.
33
#define EPIT_TIMER_MAX 0XFFFFFFFFUL
36
*/
34
37
- unsigned int i, pmcrn = 0;
35
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
38
+ unsigned int i, pmcrn = 4;
36
index XXXXXXX..XXXXXXX 100644
39
ARMCPRegInfo pmcr = {
37
--- a/hw/timer/imx_epit.c
40
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
38
+++ b/hw/timer/imx_epit.c
41
.access = PL0_RW,
39
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
42
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
40
uint32_t clksrc;
43
.access = PL0_RW, .accessfn = pmreg_access,
41
uint32_t prescaler;
44
.type = ARM_CP_IO,
42
45
.fieldoffset = offsetof(CPUARMState, cp15.c9_pmcr),
43
- clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, 2);
46
- .resetvalue = cpu->midr & 0xff000000,
44
- prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, 12);
47
+ .resetvalue = (cpu->midr & 0xff000000) | (pmcrn << PMCRN_SHIFT),
45
+ clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
48
.writefn = pmcr_write, .raw_writefn = raw_write,
46
+ prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
49
};
47
50
define_one_arm_cp_reg(cpu, &pmcr);
48
s->freq = imx_ccm_get_clock_frequency(s->ccm,
49
imx_epit_clocks[clksrc]) / prescaler;
51
--
50
--
52
2.20.1
51
2.25.1
53
54
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-7-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
5
---
8
target/arm/translate-a64.c | 93 +++++++++++++++++++++++++++++++++-----
6
include/hw/timer/imx_epit.h | 2 ++
9
1 file changed, 81 insertions(+), 12 deletions(-)
7
hw/timer/imx_epit.c | 12 ++++++------
8
2 files changed, 8 insertions(+), 6 deletions(-)
10
9
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
10
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
12
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
12
--- a/include/hw/timer/imx_epit.h
14
+++ b/target/arm/translate-a64.c
13
+++ b/include/hw/timer/imx_epit.h
15
@@ -XXX,XX +XXX,XX @@ static void handle_hint(DisasContext *s, uint32_t insn,
14
@@ -XXX,XX +XXX,XX @@
16
}
15
#define CR_CLKSRC_SHIFT (24)
17
16
#define CR_CLKSRC_BITS (2)
18
switch (selector) {
17
19
- case 0: /* NOP */
18
+#define SR_OCIF (1 << 0)
20
- return;
19
+
21
- case 3: /* WFI */
20
#define EPIT_TIMER_MAX 0XFFFFFFFFUL
22
+ case 0b00000: /* NOP */
21
23
+ break;
22
#define TYPE_IMX_EPIT "imx.epit"
24
+ case 0b00011: /* WFI */
23
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
25
s->base.is_jmp = DISAS_WFI;
24
index XXXXXXX..XXXXXXX 100644
26
- return;
25
--- a/hw/timer/imx_epit.c
27
+ break;
26
+++ b/hw/timer/imx_epit.c
28
+ case 0b00001: /* YIELD */
27
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx_epit_clocks[] = {
29
/* When running in MTTCG we don't generate jumps to the yield and
28
*/
30
* WFE helpers as it won't affect the scheduling of other vCPUs.
29
static void imx_epit_update_int(IMXEPITState *s)
31
* If we wanted to more completely model WFE/SEV so we don't busy
30
{
32
* spin unnecessarily we would need to do something more involved.
31
- if (s->sr && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
33
*/
32
+ if ((s->sr & SR_OCIF) && (s->cr & CR_OCIEN) && (s->cr & CR_EN)) {
34
- case 1: /* YIELD */
33
qemu_irq_raise(s->irq);
35
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
34
} else {
36
s->base.is_jmp = DISAS_YIELD;
35
qemu_irq_lower(s->irq);
36
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
37
break;
38
39
case 1: /* SR - ACK*/
40
- /* writing 1 to OCIF clears the OCIF bit */
41
- if (value & 0x01) {
42
- s->sr = 0;
43
+ /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
44
+ if (value & SR_OCIF) {
45
+ s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
46
imx_epit_update_int(s);
37
}
47
}
38
- return;
48
break;
39
- case 2: /* WFE */
49
@@ -XXX,XX +XXX,XX @@ static void imx_epit_cmp(void *opaque)
40
+ break;
50
IMXEPITState *s = IMX_EPIT(opaque);
41
+ case 0b00010: /* WFE */
51
42
if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
52
DPRINTF("sr was %d\n", s->sr);
43
s->base.is_jmp = DISAS_WFE;
53
-
44
}
54
- s->sr = 1;
45
- return;
55
+ /* Set interrupt status bit SR.OCIF and update the interrupt state */
46
- case 4: /* SEV */
56
+ s->sr |= SR_OCIF;
47
- case 5: /* SEVL */
57
imx_epit_update_int(s);
48
+ break;
49
+ case 0b00100: /* SEV */
50
+ case 0b00101: /* SEVL */
51
/* we treat all as NOP at least for now */
52
- return;
53
+ break;
54
+ case 0b00111: /* XPACLRI */
55
+ if (s->pauth_active) {
56
+ gen_helper_xpaci(cpu_X[30], cpu_env, cpu_X[30]);
57
+ }
58
+ break;
59
+ case 0b01000: /* PACIA1716 */
60
+ if (s->pauth_active) {
61
+ gen_helper_pacia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
62
+ }
63
+ break;
64
+ case 0b01010: /* PACIB1716 */
65
+ if (s->pauth_active) {
66
+ gen_helper_pacib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
67
+ }
68
+ break;
69
+ case 0b01100: /* AUTIA1716 */
70
+ if (s->pauth_active) {
71
+ gen_helper_autia(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
72
+ }
73
+ break;
74
+ case 0b01110: /* AUTIB1716 */
75
+ if (s->pauth_active) {
76
+ gen_helper_autib(cpu_X[17], cpu_env, cpu_X[17], cpu_X[16]);
77
+ }
78
+ break;
79
+ case 0b11000: /* PACIAZ */
80
+ if (s->pauth_active) {
81
+ gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30],
82
+ new_tmp_a64_zero(s));
83
+ }
84
+ break;
85
+ case 0b11001: /* PACIASP */
86
+ if (s->pauth_active) {
87
+ gen_helper_pacia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
88
+ }
89
+ break;
90
+ case 0b11010: /* PACIBZ */
91
+ if (s->pauth_active) {
92
+ gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30],
93
+ new_tmp_a64_zero(s));
94
+ }
95
+ break;
96
+ case 0b11011: /* PACIBSP */
97
+ if (s->pauth_active) {
98
+ gen_helper_pacib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
99
+ }
100
+ break;
101
+ case 0b11100: /* AUTIAZ */
102
+ if (s->pauth_active) {
103
+ gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30],
104
+ new_tmp_a64_zero(s));
105
+ }
106
+ break;
107
+ case 0b11101: /* AUTIASP */
108
+ if (s->pauth_active) {
109
+ gen_helper_autia(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
110
+ }
111
+ break;
112
+ case 0b11110: /* AUTIBZ */
113
+ if (s->pauth_active) {
114
+ gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30],
115
+ new_tmp_a64_zero(s));
116
+ }
117
+ break;
118
+ case 0b11111: /* AUTIBSP */
119
+ if (s->pauth_active) {
120
+ gen_helper_autib(cpu_X[30], cpu_env, cpu_X[30], cpu_X[31]);
121
+ }
122
+ break;
123
default:
124
/* default specified as NOP equivalent */
125
- return;
126
+ break;
127
}
128
}
58
}
129
59
130
--
60
--
131
2.20.1
61
2.25.1
132
133
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
3
The interrupt state can change due to:
4
- reset clears both SR.OCIF and CR.OCIE
5
- write to CR.EN or CR.OCIE
6
7
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Message-id: 20181211151945.29137-9-aaron@os.amperecomputing.com
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
10
---
8
target/arm/cpu.h | 4 ++--
11
hw/timer/imx_epit.c | 16 ++++++++++++----
9
target/arm/helper.c | 19 +++++++++++++++++--
12
1 file changed, 12 insertions(+), 4 deletions(-)
10
2 files changed, 19 insertions(+), 4 deletions(-)
11
13
12
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
13
index XXXXXXX..XXXXXXX 100644
15
index XXXXXXX..XXXXXXX 100644
14
--- a/target/arm/cpu.h
16
--- a/hw/timer/imx_epit.c
15
+++ b/target/arm/cpu.h
17
+++ b/hw/timer/imx_epit.c
16
@@ -XXX,XX +XXX,XX @@ struct ARMCPU {
18
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
17
uint32_t id_pfr0;
19
if (s->cr & CR_SWR) {
18
uint32_t id_pfr1;
20
/* handle the reset */
19
uint32_t id_dfr0;
21
imx_epit_reset(DEVICE(s));
20
- uint32_t pmceid0;
22
- /*
21
- uint32_t pmceid1;
23
- * TODO: could we 'break' here? following operations appear
22
+ uint64_t pmceid0;
24
- * to duplicate the work imx_epit_reset() already did.
23
+ uint64_t pmceid1;
25
- */
24
uint32_t id_afr0;
26
}
25
uint32_t id_mmfr0;
27
26
uint32_t id_mmfr1;
28
+ /*
27
diff --git a/target/arm/helper.c b/target/arm/helper.c
29
+ * The interrupt state can change due to:
28
index XXXXXXX..XXXXXXX 100644
30
+ * - reset clears both SR.OCIF and CR.OCIE
29
--- a/target/arm/helper.c
31
+ * - write to CR.EN or CR.OCIE
30
+++ b/target/arm/helper.c
32
+ */
31
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
33
+ imx_epit_update_int(s);
32
} else {
34
+
33
define_arm_cp_regs(cpu, not_v7_cp_reginfo);
35
+ /*
34
}
36
+ * TODO: could we 'break' here for reset? following operations appear
35
+ if (FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) >= 4 &&
37
+ * to duplicate the work imx_epit_reset() already did.
36
+ FIELD_EX32(cpu->id_dfr0, ID_DFR0, PERFMON) != 0xf) {
38
+ */
37
+ ARMCPRegInfo v81_pmu_regs[] = {
39
+
38
+ { .name = "PMCEID2", .state = ARM_CP_STATE_AA32,
40
ptimer_transaction_begin(s->timer_cmp);
39
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 4,
41
ptimer_transaction_begin(s->timer_reload);
40
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
42
41
+ .resetvalue = extract64(cpu->pmceid0, 32, 32) },
42
+ { .name = "PMCEID3", .state = ARM_CP_STATE_AA32,
43
+ .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 5,
44
+ .access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
45
+ .resetvalue = extract64(cpu->pmceid1, 32, 32) },
46
+ REGINFO_SENTINEL
47
+ };
48
+ define_arm_cp_regs(cpu, v81_pmu_regs);
49
+ }
50
if (arm_feature(env, ARM_FEATURE_V8)) {
51
/* AArch64 ID registers, which all have impdef reset values.
52
* Note that within the ID register ranges the unused slots
53
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
54
{ .name = "PMCEID0", .state = ARM_CP_STATE_AA32,
55
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 6,
56
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
57
- .resetvalue = cpu->pmceid0 },
58
+ .resetvalue = extract64(cpu->pmceid0, 0, 32) },
59
{ .name = "PMCEID0_EL0", .state = ARM_CP_STATE_AA64,
60
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 6,
61
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
62
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
63
{ .name = "PMCEID1", .state = ARM_CP_STATE_AA32,
64
.cp = 15, .opc1 = 0, .crn = 9, .crm = 12, .opc2 = 7,
65
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
66
- .resetvalue = cpu->pmceid1 },
67
+ .resetvalue = extract64(cpu->pmceid1, 0, 32) },
68
{ .name = "PMCEID1_EL0", .state = ARM_CP_STATE_AA64,
69
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 12, .opc2 = 7,
70
.access = PL0_R, .accessfn = pmreg_access, .type = ARM_CP_CONST,
71
--
43
--
72
2.20.1
44
2.25.1
73
74
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Because of the PMU's design, many register accesses have side effects
3
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
4
which are inter-related, meaning that the normal method of saving CP
5
registers can result in inconsistent state. These side-effects are
6
largely handled in pmu_op_start/finish functions which can be called
7
before and after the state is saved/restored. By doing this and adding
8
raw read/write functions for the affected registers, we avoid
9
migration-related inconsistencies.
10
11
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
12
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
13
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
14
Message-id: 20181211151945.29137-4-aaron@os.amperecomputing.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
6
---
17
target/arm/helper.c | 6 ++++--
7
hw/timer/imx_epit.c | 20 ++++++++++++++------
18
target/arm/machine.c | 24 ++++++++++++++++++++++++
8
1 file changed, 14 insertions(+), 6 deletions(-)
19
2 files changed, 28 insertions(+), 2 deletions(-)
20
9
21
diff --git a/target/arm/helper.c b/target/arm/helper.c
10
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
22
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
23
--- a/target/arm/helper.c
12
--- a/hw/timer/imx_epit.c
24
+++ b/target/arm/helper.c
13
+++ b/hw/timer/imx_epit.c
25
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
14
@@ -XXX,XX +XXX,XX @@ static void imx_epit_set_freq(IMXEPITState *s)
26
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 0,
15
/*
27
.access = PL0_RW, .accessfn = pmreg_access_ccntr,
16
* This is called both on hardware (device) reset and software reset.
28
.type = ARM_CP_IO,
17
*/
29
- .readfn = pmccntr_read, .writefn = pmccntr_write, },
18
-static void imx_epit_reset(DeviceState *dev)
30
+ .fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
19
+static void imx_epit_reset(IMXEPITState *s, bool is_hard_reset)
31
+ .readfn = pmccntr_read, .writefn = pmccntr_write,
32
+ .raw_readfn = raw_read, .raw_writefn = raw_write, },
33
#endif
34
{ .name = "PMCCFILTR_EL0", .state = ARM_CP_STATE_AA64,
35
.opc0 = 3, .opc1 = 3, .crn = 14, .crm = 15, .opc2 = 7,
36
- .writefn = pmccfiltr_write,
37
+ .writefn = pmccfiltr_write, .raw_writefn = raw_write,
38
.access = PL0_RW, .accessfn = pmreg_access,
39
.type = ARM_CP_IO,
40
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
41
diff --git a/target/arm/machine.c b/target/arm/machine.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/machine.c
44
+++ b/target/arm/machine.c
45
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
46
{
20
{
47
ARMCPU *cpu = opaque;
21
- IMXEPITState *s = IMX_EPIT(dev);
48
22
-
49
+ if (!kvm_enabled()) {
23
/* Soft reset doesn't touch some bits; hard reset clears them */
50
+ pmu_op_start(&cpu->env);
24
- s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
25
+ if (is_hard_reset) {
26
+ s->cr = 0;
27
+ } else {
28
+ s->cr &= (CR_EN|CR_ENMOD|CR_STOPEN|CR_DOZEN|CR_WAITEN|CR_DBGEN);
51
+ }
29
+ }
52
+
30
s->sr = 0;
53
if (kvm_enabled()) {
31
s->lr = EPIT_TIMER_MAX;
54
if (!write_kvmstate_to_list(cpu)) {
32
s->cmp = 0;
55
/* This should never fail */
33
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
56
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_save(void *opaque)
34
s->cr = value & 0x03ffffff;
57
return 0;
35
if (s->cr & CR_SWR) {
36
/* handle the reset */
37
- imx_epit_reset(DEVICE(s));
38
+ imx_epit_reset(s, false);
39
}
40
41
/*
42
@@ -XXX,XX +XXX,XX @@ static void imx_epit_realize(DeviceState *dev, Error **errp)
43
s->timer_cmp = ptimer_init(imx_epit_cmp, s, PTIMER_POLICY_LEGACY);
58
}
44
}
59
45
60
+static int cpu_post_save(void *opaque)
46
+static void imx_epit_dev_reset(DeviceState *dev)
61
+{
47
+{
62
+ ARMCPU *cpu = opaque;
48
+ IMXEPITState *s = IMX_EPIT(dev);
63
+
49
+ imx_epit_reset(s, true);
64
+ if (!kvm_enabled()) {
65
+ pmu_op_finish(&cpu->env);
66
+ }
67
+
68
+ return 0;
69
+}
50
+}
70
+
51
+
71
static int cpu_pre_load(void *opaque)
52
static void imx_epit_class_init(ObjectClass *klass, void *data)
72
{
53
{
73
ARMCPU *cpu = opaque;
54
DeviceClass *dc = DEVICE_CLASS(klass);
74
@@ -XXX,XX +XXX,XX @@ static int cpu_pre_load(void *opaque)
55
75
*/
56
dc->realize = imx_epit_realize;
76
env->irq_line_state = UINT32_MAX;
57
- dc->reset = imx_epit_reset;
77
58
+ dc->reset = imx_epit_dev_reset;
78
+ if (!kvm_enabled()) {
59
dc->vmsd = &vmstate_imx_timer_epit;
79
+ pmu_op_start(&cpu->env);
60
dc->desc = "i.MX periodic timer";
80
+ }
81
+
82
return 0;
83
}
61
}
84
85
@@ -XXX,XX +XXX,XX @@ static int cpu_post_load(void *opaque, int version_id)
86
hw_breakpoint_update_all(cpu);
87
hw_watchpoint_update_all(cpu);
88
89
+ if (!kvm_enabled()) {
90
+ pmu_op_finish(&cpu->env);
91
+ }
92
+
93
return 0;
94
}
95
96
@@ -XXX,XX +XXX,XX @@ const VMStateDescription vmstate_arm_cpu = {
97
.version_id = 22,
98
.minimum_version_id = 22,
99
.pre_save = cpu_pre_save,
100
+ .post_save = cpu_post_save,
101
.pre_load = cpu_pre_load,
102
.post_load = cpu_post_load,
103
.fields = (VMStateField[]) {
104
--
62
--
105
2.20.1
63
2.25.1
106
107
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
This function is only used by AArch64. Code movement only.
3
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-11-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
6
---
10
target/arm/helper-a64.h | 2 +
7
hw/timer/imx_epit.c | 215 ++++++++++++++++++++++++--------------------
11
target/arm/helper.h | 1 -
8
1 file changed, 117 insertions(+), 98 deletions(-)
12
target/arm/helper-a64.c | 155 ++++++++++++++++++++++++++++++++++++++++
13
target/arm/op_helper.c | 155 ----------------------------------------
14
4 files changed, 157 insertions(+), 156 deletions(-)
15
9
16
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
10
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
17
index XXXXXXX..XXXXXXX 100644
11
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/helper-a64.h
12
--- a/hw/timer/imx_epit.c
19
+++ b/target/arm/helper-a64.h
13
+++ b/hw/timer/imx_epit.c
20
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
14
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
21
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
15
}
22
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
23
24
+DEF_HELPER_1(exception_return, void, env)
25
+
26
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
27
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
28
DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
29
diff --git a/target/arm/helper.h b/target/arm/helper.h
30
index XXXXXXX..XXXXXXX 100644
31
--- a/target/arm/helper.h
32
+++ b/target/arm/helper.h
33
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(get_cp_reg64, i64, env, ptr)
34
35
DEF_HELPER_3(msr_i_pstate, void, env, i32, i32)
36
DEF_HELPER_1(clear_pstate_ss, void, env)
37
-DEF_HELPER_1(exception_return, void, env)
38
39
DEF_HELPER_2(get_r13_banked, i32, env, i32)
40
DEF_HELPER_3(set_r13_banked, void, env, i32, i32)
41
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/target/arm/helper-a64.c
44
+++ b/target/arm/helper-a64.c
45
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(advsimd_f16touinth)(uint32_t a, void *fpstp)
46
return float16_to_uint16(a, fpst);
47
}
16
}
48
17
49
+static int el_from_spsr(uint32_t spsr)
18
+static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
50
+{
19
+{
51
+ /* Return the exception level that this SPSR is requesting a return to,
20
+ uint32_t oldcr = s->cr;
52
+ * or -1 if it is invalid (an illegal return)
21
+
22
+ s->cr = value & 0x03ffffff;
23
+
24
+ if (s->cr & CR_SWR) {
25
+ /* handle the reset */
26
+ imx_epit_reset(s, false);
27
+ }
28
+
29
+ /*
30
+ * The interrupt state can change due to:
31
+ * - reset clears both SR.OCIF and CR.OCIE
32
+ * - write to CR.EN or CR.OCIE
53
+ */
33
+ */
54
+ if (spsr & PSTATE_nRW) {
34
+ imx_epit_update_int(s);
55
+ switch (spsr & CPSR_M) {
35
+
56
+ case ARM_CPU_MODE_USR:
36
+ /*
57
+ return 0;
37
+ * TODO: could we 'break' here for reset? following operations appear
58
+ case ARM_CPU_MODE_HYP:
38
+ * to duplicate the work imx_epit_reset() already did.
59
+ return 2;
39
+ */
60
+ case ARM_CPU_MODE_FIQ:
40
+
61
+ case ARM_CPU_MODE_IRQ:
41
+ ptimer_transaction_begin(s->timer_cmp);
62
+ case ARM_CPU_MODE_SVC:
42
+ ptimer_transaction_begin(s->timer_reload);
63
+ case ARM_CPU_MODE_ABT:
43
+
64
+ case ARM_CPU_MODE_UND:
44
+ /* Update the frequency. Has been done already in case of a reset. */
65
+ case ARM_CPU_MODE_SYS:
45
+ if (!(s->cr & CR_SWR)) {
66
+ return 1;
46
+ imx_epit_set_freq(s);
67
+ case ARM_CPU_MODE_MON:
47
+ }
68
+ /* Returning to Mon from AArch64 is never possible,
48
+
69
+ * so this is an illegal return.
49
+ if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
70
+ */
50
+ if (s->cr & CR_ENMOD) {
71
+ default:
51
+ if (s->cr & CR_RLD) {
72
+ return -1;
52
+ ptimer_set_limit(s->timer_reload, s->lr, 1);
53
+ ptimer_set_limit(s->timer_cmp, s->lr, 1);
54
+ } else {
55
+ ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
56
+ ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
57
+ }
58
+ }
59
+
60
+ imx_epit_reload_compare_timer(s);
61
+ ptimer_run(s->timer_reload, 0);
62
+ if (s->cr & CR_OCIEN) {
63
+ ptimer_run(s->timer_cmp, 0);
64
+ } else {
65
+ ptimer_stop(s->timer_cmp);
66
+ }
67
+ } else if (!(s->cr & CR_EN)) {
68
+ /* stop both timers */
69
+ ptimer_stop(s->timer_reload);
70
+ ptimer_stop(s->timer_cmp);
71
+ } else if (s->cr & CR_OCIEN) {
72
+ if (!(oldcr & CR_OCIEN)) {
73
+ imx_epit_reload_compare_timer(s);
74
+ ptimer_run(s->timer_cmp, 0);
73
+ }
75
+ }
74
+ } else {
76
+ } else {
75
+ if (extract32(spsr, 1, 1)) {
77
+ ptimer_stop(s->timer_cmp);
76
+ /* Return with reserved M[1] bit set */
78
+ }
77
+ return -1;
79
+
78
+ }
80
+ ptimer_transaction_commit(s->timer_cmp);
79
+ if (extract32(spsr, 0, 4) == 1) {
81
+ ptimer_transaction_commit(s->timer_reload);
80
+ /* return to EL0 with M[0] bit set */
82
+}
81
+ return -1;
83
+
82
+ }
84
+static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
83
+ return extract32(spsr, 2, 2);
85
+{
84
+ }
86
+ /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
85
+}
87
+ if (value & SR_OCIF) {
86
+
88
+ s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
87
+void HELPER(exception_return)(CPUARMState *env)
89
+ imx_epit_update_int(s);
88
+{
90
+ }
89
+ int cur_el = arm_current_el(env);
91
+}
90
+ unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
92
+
91
+ uint32_t spsr = env->banked_spsr[spsr_idx];
93
+static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
92
+ int new_el;
94
+{
93
+ bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
95
+ s->lr = value;
94
+
96
+
95
+ aarch64_save_sp(env, cur_el);
97
+ ptimer_transaction_begin(s->timer_cmp);
96
+
98
+ ptimer_transaction_begin(s->timer_reload);
97
+ arm_clear_exclusive(env);
99
+ if (s->cr & CR_RLD) {
98
+
100
+ /* Also set the limit if the LRD bit is set */
99
+ /* We must squash the PSTATE.SS bit to zero unless both of the
101
+ /* If IOVW bit is set then set the timer value */
100
+ * following hold:
102
+ ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
101
+ * 1. debug exceptions are currently disabled
103
+ ptimer_set_limit(s->timer_cmp, s->lr, 0);
102
+ * 2. singlestep will be active in the EL we return to
104
+ } else if (s->cr & CR_IOVW) {
103
+ * We check 1 here and 2 after we've done the pstate/cpsr write() to
105
+ /* If IOVW bit is set then set the timer value */
104
+ * transition to the EL we're going to.
106
+ ptimer_set_count(s->timer_reload, s->lr);
107
+ }
108
+ /*
109
+ * Commit the change to s->timer_reload, so it can propagate. Otherwise
110
+ * the timer interrupt may not fire properly. The commit must happen
111
+ * before calling imx_epit_reload_compare_timer(), which reads
112
+ * s->timer_reload internally again.
105
+ */
113
+ */
106
+ if (arm_generate_debug_exceptions(env)) {
114
+ ptimer_transaction_commit(s->timer_reload);
107
+ spsr &= ~PSTATE_SS;
115
+ imx_epit_reload_compare_timer(s);
108
+ }
116
+ ptimer_transaction_commit(s->timer_cmp);
109
+
117
+}
110
+ new_el = el_from_spsr(spsr);
118
+
111
+ if (new_el == -1) {
119
+static void imx_epit_write_cmp(IMXEPITState *s, uint32_t value)
112
+ goto illegal_return;
120
+{
113
+ }
121
+ s->cmp = value;
114
+ if (new_el > cur_el
122
+
115
+ || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
123
+ ptimer_transaction_begin(s->timer_cmp);
116
+ /* Disallow return to an EL which is unimplemented or higher
124
+ imx_epit_reload_compare_timer(s);
117
+ * than the current one.
125
+ ptimer_transaction_commit(s->timer_cmp);
118
+ */
126
+}
119
+ goto illegal_return;
127
+
120
+ }
128
static void imx_epit_write(void *opaque, hwaddr offset, uint64_t value,
121
+
129
unsigned size)
122
+ if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
130
{
123
+ /* Return to an EL which is configured for a different register width */
131
IMXEPITState *s = IMX_EPIT(opaque);
124
+ goto illegal_return;
132
- uint64_t oldcr;
125
+ }
133
126
+
134
DPRINTF("(%s, value = 0x%08x)\n", imx_epit_reg_name(offset >> 2),
127
+ if (new_el == 2 && arm_is_secure_below_el3(env)) {
135
(uint32_t)value);
128
+ /* Return to the non-existent secure-EL2 */
136
129
+ goto illegal_return;
137
switch (offset >> 2) {
130
+ }
138
case 0: /* CR */
131
+
139
-
132
+ if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
140
- oldcr = s->cr;
133
+ goto illegal_return;
141
- s->cr = value & 0x03ffffff;
134
+ }
142
- if (s->cr & CR_SWR) {
135
+
143
- /* handle the reset */
136
+ qemu_mutex_lock_iothread();
144
- imx_epit_reset(s, false);
137
+ arm_call_pre_el_change_hook(arm_env_get_cpu(env));
145
- }
138
+ qemu_mutex_unlock_iothread();
146
-
139
+
147
- /*
140
+ if (!return_to_aa64) {
148
- * The interrupt state can change due to:
141
+ env->aarch64 = 0;
149
- * - reset clears both SR.OCIF and CR.OCIE
142
+ /* We do a raw CPSR write because aarch64_sync_64_to_32()
150
- * - write to CR.EN or CR.OCIE
143
+ * will sort the register banks out for us, and we've already
151
- */
144
+ * caught all the bad-mode cases in el_from_spsr().
152
- imx_epit_update_int(s);
145
+ */
153
-
146
+ cpsr_write(env, spsr, ~0, CPSRWriteRaw);
154
- /*
147
+ if (!arm_singlestep_active(env)) {
155
- * TODO: could we 'break' here for reset? following operations appear
148
+ env->uncached_cpsr &= ~PSTATE_SS;
156
- * to duplicate the work imx_epit_reset() already did.
149
+ }
157
- */
150
+ aarch64_sync_64_to_32(env);
158
-
151
+
159
- ptimer_transaction_begin(s->timer_cmp);
152
+ if (spsr & CPSR_T) {
160
- ptimer_transaction_begin(s->timer_reload);
153
+ env->regs[15] = env->elr_el[cur_el] & ~0x1;
161
-
154
+ } else {
162
- /* Update the frequency. Has been done already in case of a reset. */
155
+ env->regs[15] = env->elr_el[cur_el] & ~0x3;
163
- if (!(s->cr & CR_SWR)) {
156
+ }
164
- imx_epit_set_freq(s);
157
+ qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
165
- }
158
+ "AArch32 EL%d PC 0x%" PRIx32 "\n",
166
-
159
+ cur_el, new_el, env->regs[15]);
167
- if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
160
+ } else {
168
- if (s->cr & CR_ENMOD) {
161
+ env->aarch64 = 1;
169
- if (s->cr & CR_RLD) {
162
+ pstate_write(env, spsr);
170
- ptimer_set_limit(s->timer_reload, s->lr, 1);
163
+ if (!arm_singlestep_active(env)) {
171
- ptimer_set_limit(s->timer_cmp, s->lr, 1);
164
+ env->pstate &= ~PSTATE_SS;
172
- } else {
165
+ }
173
- ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
166
+ aarch64_restore_sp(env, new_el);
174
- ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
167
+ env->pc = env->elr_el[cur_el];
175
- }
168
+ qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
176
- }
169
+ "AArch64 EL%d PC 0x%" PRIx64 "\n",
177
-
170
+ cur_el, new_el, env->pc);
178
- imx_epit_reload_compare_timer(s);
171
+ }
179
- ptimer_run(s->timer_reload, 0);
172
+ /*
180
- if (s->cr & CR_OCIEN) {
173
+ * Note that cur_el can never be 0. If new_el is 0, then
181
- ptimer_run(s->timer_cmp, 0);
174
+ * el0_a64 is return_to_aa64, else el0_a64 is ignored.
182
- } else {
175
+ */
183
- ptimer_stop(s->timer_cmp);
176
+ aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
184
- }
177
+
185
- } else if (!(s->cr & CR_EN)) {
178
+ qemu_mutex_lock_iothread();
186
- /* stop both timers */
179
+ arm_call_el_change_hook(arm_env_get_cpu(env));
187
- ptimer_stop(s->timer_reload);
180
+ qemu_mutex_unlock_iothread();
188
- ptimer_stop(s->timer_cmp);
181
+
189
- } else if (s->cr & CR_OCIEN) {
182
+ return;
190
- if (!(oldcr & CR_OCIEN)) {
183
+
191
- imx_epit_reload_compare_timer(s);
184
+illegal_return:
192
- ptimer_run(s->timer_cmp, 0);
185
+ /* Illegal return events of various kinds have architecturally
193
- }
186
+ * mandated behaviour:
194
- } else {
187
+ * restore NZCV and DAIF from SPSR_ELx
195
- ptimer_stop(s->timer_cmp);
188
+ * set PSTATE.IL
196
- }
189
+ * restore PC from ELR_ELx
197
-
190
+ * no change to exception level, execution state or stack pointer
198
- ptimer_transaction_commit(s->timer_cmp);
191
+ */
199
- ptimer_transaction_commit(s->timer_reload);
192
+ env->pstate |= PSTATE_IL;
200
+ imx_epit_write_cr(s, (uint32_t)value);
193
+ env->pc = env->elr_el[cur_el];
201
break;
194
+ spsr &= PSTATE_NZCV | PSTATE_DAIF;
202
195
+ spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
203
- case 1: /* SR - ACK*/
196
+ pstate_write(env, spsr);
204
- /* writing 1 to SR.OCIF clears this bit and turns the interrupt off */
197
+ if (!arm_singlestep_active(env)) {
205
- if (value & SR_OCIF) {
198
+ env->pstate &= ~PSTATE_SS;
206
- s->sr = 0; /* SR.OCIF is the only bit in this register anyway */
199
+ }
207
- imx_epit_update_int(s);
200
+ qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
208
- }
201
+ "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
209
+ case 1: /* SR */
202
+}
210
+ imx_epit_write_sr(s, (uint32_t)value);
203
+
211
break;
204
/*
212
205
* Square Root and Reciprocal square root
213
- case 2: /* LR - set ticks */
206
*/
214
- s->lr = value;
207
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
215
-
208
index XXXXXXX..XXXXXXX 100644
216
- ptimer_transaction_begin(s->timer_cmp);
209
--- a/target/arm/op_helper.c
217
- ptimer_transaction_begin(s->timer_reload);
210
+++ b/target/arm/op_helper.c
218
- if (s->cr & CR_RLD) {
211
@@ -XXX,XX +XXX,XX @@ void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
219
- /* Also set the limit if the LRD bit is set */
220
- /* If IOVW bit is set then set the timer value */
221
- ptimer_set_limit(s->timer_reload, s->lr, s->cr & CR_IOVW);
222
- ptimer_set_limit(s->timer_cmp, s->lr, 0);
223
- } else if (s->cr & CR_IOVW) {
224
- /* If IOVW bit is set then set the timer value */
225
- ptimer_set_count(s->timer_reload, s->lr);
226
- }
227
- /*
228
- * Commit the change to s->timer_reload, so it can propagate. Otherwise
229
- * the timer interrupt may not fire properly. The commit must happen
230
- * before calling imx_epit_reload_compare_timer(), which reads
231
- * s->timer_reload internally again.
232
- */
233
- ptimer_transaction_commit(s->timer_reload);
234
- imx_epit_reload_compare_timer(s);
235
- ptimer_transaction_commit(s->timer_cmp);
236
+ case 2: /* LR */
237
+ imx_epit_write_lr(s, (uint32_t)value);
238
break;
239
240
case 3: /* CMP */
241
- s->cmp = value;
242
-
243
- ptimer_transaction_begin(s->timer_cmp);
244
- imx_epit_reload_compare_timer(s);
245
- ptimer_transaction_commit(s->timer_cmp);
246
-
247
+ imx_epit_write_cmp(s, (uint32_t)value);
248
break;
249
250
default:
251
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
252
HWADDR_PRIx "\n", TYPE_IMX_EPIT, __func__, offset);
253
-
254
break;
212
}
255
}
213
}
256
}
214
257
+
215
-static int el_from_spsr(uint32_t spsr)
258
static void imx_epit_cmp(void *opaque)
216
-{
217
- /* Return the exception level that this SPSR is requesting a return to,
218
- * or -1 if it is invalid (an illegal return)
219
- */
220
- if (spsr & PSTATE_nRW) {
221
- switch (spsr & CPSR_M) {
222
- case ARM_CPU_MODE_USR:
223
- return 0;
224
- case ARM_CPU_MODE_HYP:
225
- return 2;
226
- case ARM_CPU_MODE_FIQ:
227
- case ARM_CPU_MODE_IRQ:
228
- case ARM_CPU_MODE_SVC:
229
- case ARM_CPU_MODE_ABT:
230
- case ARM_CPU_MODE_UND:
231
- case ARM_CPU_MODE_SYS:
232
- return 1;
233
- case ARM_CPU_MODE_MON:
234
- /* Returning to Mon from AArch64 is never possible,
235
- * so this is an illegal return.
236
- */
237
- default:
238
- return -1;
239
- }
240
- } else {
241
- if (extract32(spsr, 1, 1)) {
242
- /* Return with reserved M[1] bit set */
243
- return -1;
244
- }
245
- if (extract32(spsr, 0, 4) == 1) {
246
- /* return to EL0 with M[0] bit set */
247
- return -1;
248
- }
249
- return extract32(spsr, 2, 2);
250
- }
251
-}
252
-
253
-void HELPER(exception_return)(CPUARMState *env)
254
-{
255
- int cur_el = arm_current_el(env);
256
- unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
257
- uint32_t spsr = env->banked_spsr[spsr_idx];
258
- int new_el;
259
- bool return_to_aa64 = (spsr & PSTATE_nRW) == 0;
260
-
261
- aarch64_save_sp(env, cur_el);
262
-
263
- arm_clear_exclusive(env);
264
-
265
- /* We must squash the PSTATE.SS bit to zero unless both of the
266
- * following hold:
267
- * 1. debug exceptions are currently disabled
268
- * 2. singlestep will be active in the EL we return to
269
- * We check 1 here and 2 after we've done the pstate/cpsr write() to
270
- * transition to the EL we're going to.
271
- */
272
- if (arm_generate_debug_exceptions(env)) {
273
- spsr &= ~PSTATE_SS;
274
- }
275
-
276
- new_el = el_from_spsr(spsr);
277
- if (new_el == -1) {
278
- goto illegal_return;
279
- }
280
- if (new_el > cur_el
281
- || (new_el == 2 && !arm_feature(env, ARM_FEATURE_EL2))) {
282
- /* Disallow return to an EL which is unimplemented or higher
283
- * than the current one.
284
- */
285
- goto illegal_return;
286
- }
287
-
288
- if (new_el != 0 && arm_el_is_aa64(env, new_el) != return_to_aa64) {
289
- /* Return to an EL which is configured for a different register width */
290
- goto illegal_return;
291
- }
292
-
293
- if (new_el == 2 && arm_is_secure_below_el3(env)) {
294
- /* Return to the non-existent secure-EL2 */
295
- goto illegal_return;
296
- }
297
-
298
- if (new_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
299
- goto illegal_return;
300
- }
301
-
302
- qemu_mutex_lock_iothread();
303
- arm_call_pre_el_change_hook(arm_env_get_cpu(env));
304
- qemu_mutex_unlock_iothread();
305
-
306
- if (!return_to_aa64) {
307
- env->aarch64 = 0;
308
- /* We do a raw CPSR write because aarch64_sync_64_to_32()
309
- * will sort the register banks out for us, and we've already
310
- * caught all the bad-mode cases in el_from_spsr().
311
- */
312
- cpsr_write(env, spsr, ~0, CPSRWriteRaw);
313
- if (!arm_singlestep_active(env)) {
314
- env->uncached_cpsr &= ~PSTATE_SS;
315
- }
316
- aarch64_sync_64_to_32(env);
317
-
318
- if (spsr & CPSR_T) {
319
- env->regs[15] = env->elr_el[cur_el] & ~0x1;
320
- } else {
321
- env->regs[15] = env->elr_el[cur_el] & ~0x3;
322
- }
323
- qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
324
- "AArch32 EL%d PC 0x%" PRIx32 "\n",
325
- cur_el, new_el, env->regs[15]);
326
- } else {
327
- env->aarch64 = 1;
328
- pstate_write(env, spsr);
329
- if (!arm_singlestep_active(env)) {
330
- env->pstate &= ~PSTATE_SS;
331
- }
332
- aarch64_restore_sp(env, new_el);
333
- env->pc = env->elr_el[cur_el];
334
- qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
335
- "AArch64 EL%d PC 0x%" PRIx64 "\n",
336
- cur_el, new_el, env->pc);
337
- }
338
- /*
339
- * Note that cur_el can never be 0. If new_el is 0, then
340
- * el0_a64 is return_to_aa64, else el0_a64 is ignored.
341
- */
342
- aarch64_sve_change_el(env, cur_el, new_el, return_to_aa64);
343
-
344
- qemu_mutex_lock_iothread();
345
- arm_call_el_change_hook(arm_env_get_cpu(env));
346
- qemu_mutex_unlock_iothread();
347
-
348
- return;
349
-
350
-illegal_return:
351
- /* Illegal return events of various kinds have architecturally
352
- * mandated behaviour:
353
- * restore NZCV and DAIF from SPSR_ELx
354
- * set PSTATE.IL
355
- * restore PC from ELR_ELx
356
- * no change to exception level, execution state or stack pointer
357
- */
358
- env->pstate |= PSTATE_IL;
359
- env->pc = env->elr_el[cur_el];
360
- spsr &= PSTATE_NZCV | PSTATE_DAIF;
361
- spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
362
- pstate_write(env, spsr);
363
- if (!arm_singlestep_active(env)) {
364
- env->pstate &= ~PSTATE_SS;
365
- }
366
- qemu_log_mask(LOG_GUEST_ERROR, "Illegal exception return at EL%d: "
367
- "resuming execution at 0x%" PRIx64 "\n", cur_el, env->pc);
368
-}
369
-
370
/* Return true if the linked breakpoint entry lbn passes its checks */
371
static bool linked_bp_matches(ARMCPU *cpu, int lbn)
372
{
259
{
260
IMXEPITState *s = IMX_EPIT(opaque);
373
--
261
--
374
2.20.1
262
2.25.1
375
376
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
Add arrays to hold the registers, the definitions themselves, access
3
The CNT register is a read-only register. There is no need to
4
functions, and logic to reset counters when PMCR.P is set. Update
4
store it's value, it can be calculated on demand.
5
filtering code to support counters other than PMCCNTR. Support migration
5
The calculated frequency is needed temporarily only.
6
with raw read/write functions.
7
6
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
7
Note that this is a migration compatibility break for all boards
9
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
types that use the EPIT peripheral.
10
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
11
Message-id: 20181211151945.29137-11-aaron@os.amperecomputing.com
10
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
13
---
14
target/arm/cpu.h | 3 +
14
include/hw/timer/imx_epit.h | 2 -
15
target/arm/helper.c | 296 +++++++++++++++++++++++++++++++++++++++++---
15
hw/timer/imx_epit.c | 73 ++++++++++++++-----------------------
16
2 files changed, 282 insertions(+), 17 deletions(-)
16
2 files changed, 28 insertions(+), 47 deletions(-)
17
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
18
diff --git a/include/hw/timer/imx_epit.h b/include/hw/timer/imx_epit.h
19
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
20
--- a/include/hw/timer/imx_epit.h
21
+++ b/target/arm/cpu.h
21
+++ b/include/hw/timer/imx_epit.h
22
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
22
@@ -XXX,XX +XXX,XX @@ struct IMXEPITState {
23
* pmccntr_op_finish.
23
uint32_t sr;
24
*/
24
uint32_t lr;
25
uint64_t c15_ccnt_delta;
25
uint32_t cmp;
26
+ uint64_t c14_pmevcntr[31];
26
- uint32_t cnt;
27
+ uint64_t c14_pmevcntr_delta[31];
27
28
+ uint64_t c14_pmevtyper[31];
28
- uint32_t freq;
29
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
29
qemu_irq irq;
30
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
30
};
31
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
31
32
diff --git a/target/arm/helper.c b/target/arm/helper.c
32
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
33
index XXXXXXX..XXXXXXX 100644
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/helper.c
34
--- a/hw/timer/imx_epit.c
35
+++ b/target/arm/helper.c
35
+++ b/hw/timer/imx_epit.c
36
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
36
@@ -XXX,XX +XXX,XX @@ static void imx_epit_update_int(IMXEPITState *s)
37
#define PMCRDP 0x10
38
#define PMCRD 0x8
39
#define PMCRC 0x4
40
+#define PMCRP 0x2
41
#define PMCRE 0x1
42
43
#define PMXEVTYPER_P 0x80000000
44
@@ -XXX,XX +XXX,XX @@ uint64_t get_pmceid(CPUARMState *env, unsigned which)
45
return pmceid;
46
}
47
48
+/*
49
+ * Check at runtime whether a PMU event is supported for the current machine
50
+ */
51
+static bool event_supported(uint16_t number)
52
+{
53
+ if (number > MAX_EVENT_ID) {
54
+ return false;
55
+ }
56
+ return supported_event_map[number] != UNSUPPORTED_EVENT;
57
+}
58
+
59
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
60
bool isread)
61
{
62
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
63
prohibited = env->cp15.c9_pmcr & PMCRDP;
64
}
65
66
- /* TODO Remove assert, set filter to correct PMEVTYPER */
67
- assert(counter == 31);
68
- filter = env->cp15.pmccfiltr_el0;
69
+ if (counter == 31) {
70
+ filter = env->cp15.pmccfiltr_el0;
71
+ } else {
72
+ filter = env->cp15.c14_pmevtyper[counter];
73
+ }
74
75
p = filter & PMXEVTYPER_P;
76
u = filter & PMXEVTYPER_U;
77
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
78
filtered = m != p;
79
}
80
81
+ if (counter != 31) {
82
+ /*
83
+ * If not checking PMCCNTR, ensure the counter is setup to an event we
84
+ * support
85
+ */
86
+ uint16_t event = filter & PMXEVTYPER_EVTCOUNT;
87
+ if (!event_supported(event)) {
88
+ return false;
89
+ }
90
+ }
91
+
92
return enabled && !prohibited && !filtered;
93
}
94
95
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env)
96
}
37
}
97
}
38
}
98
39
99
+static void pmevcntr_op_start(CPUARMState *env, uint8_t counter)
40
-/*
100
+{
41
- * Must be called from within a ptimer_transaction_begin/commit block
101
+
42
- * for both s->timer_cmp and s->timer_reload.
102
+ uint16_t event = env->cp15.c14_pmevtyper[counter] & PMXEVTYPER_EVTCOUNT;
43
- */
103
+ uint64_t count = 0;
44
-static void imx_epit_set_freq(IMXEPITState *s)
104
+ if (event_supported(event)) {
45
+static uint32_t imx_epit_get_freq(IMXEPITState *s)
105
+ uint16_t event_idx = supported_event_map[event];
106
+ count = pm_events[event_idx].get_count(env);
107
+ }
108
+
109
+ if (pmu_counter_enabled(env, counter)) {
110
+ env->cp15.c14_pmevcntr[counter] =
111
+ count - env->cp15.c14_pmevcntr_delta[counter];
112
+ }
113
+ env->cp15.c14_pmevcntr_delta[counter] = count;
114
+}
115
+
116
+static void pmevcntr_op_finish(CPUARMState *env, uint8_t counter)
117
+{
118
+ if (pmu_counter_enabled(env, counter)) {
119
+ env->cp15.c14_pmevcntr_delta[counter] -=
120
+ env->cp15.c14_pmevcntr[counter];
121
+ }
122
+}
123
+
124
void pmu_op_start(CPUARMState *env)
125
{
46
{
126
+ unsigned int i;
47
- uint32_t clksrc;
127
pmccntr_op_start(env);
48
- uint32_t prescaler;
128
+ for (i = 0; i < pmu_num_counters(env); i++) {
49
-
129
+ pmevcntr_op_start(env, i);
50
- clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
130
+ }
51
- prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
52
-
53
- s->freq = imx_ccm_get_clock_frequency(s->ccm,
54
- imx_epit_clocks[clksrc]) / prescaler;
55
-
56
- DPRINTF("Setting ptimer frequency to %u\n", s->freq);
57
-
58
- if (s->freq) {
59
- ptimer_set_freq(s->timer_reload, s->freq);
60
- ptimer_set_freq(s->timer_cmp, s->freq);
61
- }
62
+ uint32_t clksrc = extract32(s->cr, CR_CLKSRC_SHIFT, CR_CLKSRC_BITS);
63
+ uint32_t prescaler = 1 + extract32(s->cr, CR_PRESCALE_SHIFT, CR_PRESCALE_BITS);
64
+ uint32_t f_in = imx_ccm_get_clock_frequency(s->ccm, imx_epit_clocks[clksrc]);
65
+ uint32_t freq = f_in / prescaler;
66
+ DPRINTF("ptimer frequency is %u\n", freq);
67
+ return freq;
131
}
68
}
132
69
133
void pmu_op_finish(CPUARMState *env)
70
/*
134
{
71
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reset(IMXEPITState *s, bool is_hard_reset)
135
+ unsigned int i;
72
s->sr = 0;
136
pmccntr_op_finish(env);
73
s->lr = EPIT_TIMER_MAX;
137
+ for (i = 0; i < pmu_num_counters(env); i++) {
74
s->cmp = 0;
138
+ pmevcntr_op_finish(env, i);
75
- s->cnt = 0;
139
+ }
76
ptimer_transaction_begin(s->timer_cmp);
140
}
77
ptimer_transaction_begin(s->timer_reload);
141
78
- /* stop both timers */
142
void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
143
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
144
env->cp15.c15_ccnt = 0;
145
}
146
147
+ if (value & PMCRP) {
148
+ unsigned int i;
149
+ for (i = 0; i < pmu_num_counters(env); i++) {
150
+ env->cp15.c14_pmevcntr[i] = 0;
151
+ }
152
+ }
153
+
154
/* only the DP, X, D and E bits are writable */
155
env->cp15.c9_pmcr &= ~0x39;
156
env->cp15.c9_pmcr |= (value & 0x39);
157
@@ -XXX,XX +XXX,XX @@ void pmccntr_op_finish(CPUARMState *env)
158
{
159
}
160
161
+void pmevcntr_op_start(CPUARMState *env, uint8_t i)
162
+{
163
+}
164
+
165
+void pmevcntr_op_finish(CPUARMState *env, uint8_t i)
166
+{
167
+}
168
+
169
void pmu_op_start(CPUARMState *env)
170
{
171
}
172
@@ -XXX,XX +XXX,XX @@ static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
173
env->cp15.c9_pmovsr |= value;
174
}
175
176
-static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
177
- uint64_t value)
178
+static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
179
+ uint64_t value, const uint8_t counter)
180
{
181
+ if (counter == 31) {
182
+ pmccfiltr_write(env, ri, value);
183
+ } else if (counter < pmu_num_counters(env)) {
184
+ pmevcntr_op_start(env, counter);
185
+
186
+ /*
187
+ * If this counter's event type is changing, store the current
188
+ * underlying count for the new type in c14_pmevcntr_delta[counter] so
189
+ * pmevcntr_op_finish has the correct baseline when it converts back to
190
+ * a delta.
191
+ */
192
+ uint16_t old_event = env->cp15.c14_pmevtyper[counter] &
193
+ PMXEVTYPER_EVTCOUNT;
194
+ uint16_t new_event = value & PMXEVTYPER_EVTCOUNT;
195
+ if (old_event != new_event) {
196
+ uint64_t count = 0;
197
+ if (event_supported(new_event)) {
198
+ uint16_t event_idx = supported_event_map[new_event];
199
+ count = pm_events[event_idx].get_count(env);
200
+ }
201
+ env->cp15.c14_pmevcntr_delta[counter] = count;
202
+ }
203
+
204
+ env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
205
+ pmevcntr_op_finish(env, counter);
206
+ }
207
/* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
208
* PMSELR value is equal to or greater than the number of implemented
209
* counters, but not equal to 0x1f. We opt to behave as a RAZ/WI.
210
*/
211
- if (env->cp15.c9_pmselr == 0x1f) {
212
- pmccfiltr_write(env, ri, value);
213
+}
214
+
215
+static uint64_t pmevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri,
216
+ const uint8_t counter)
217
+{
218
+ if (counter == 31) {
219
+ return env->cp15.pmccfiltr_el0;
220
+ } else if (counter < pmu_num_counters(env)) {
221
+ return env->cp15.c14_pmevtyper[counter];
222
+ } else {
223
+ /*
224
+ * We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER
225
+ * are CONSTRAINED UNPREDICTABLE. See comments in pmevtyper_write().
226
+ */
227
+ return 0;
228
}
229
}
230
231
+static void pmevtyper_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
232
+ uint64_t value)
233
+{
234
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
235
+ pmevtyper_write(env, ri, value, counter);
236
+}
237
+
238
+static void pmevtyper_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
239
+ uint64_t value)
240
+{
241
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
242
+ env->cp15.c14_pmevtyper[counter] = value;
243
+
79
+
244
+ /*
80
+ /*
245
+ * pmevtyper_rawwrite is called between a pair of pmu_op_start and
81
+ * The reset switches off the input clock, so even if the CR.EN is still
246
+ * pmu_op_finish calls when loading saved state for a migration. Because
82
+ * set, the timers are no longer running.
247
+ * we're potentially updating the type of event here, the value written to
248
+ * c14_pmevcntr_delta by the preceeding pmu_op_start call may be for a
249
+ * different counter type. Therefore, we need to set this value to the
250
+ * current count for the counter type we're writing so that pmu_op_finish
251
+ * has the correct count for its calculation.
252
+ */
83
+ */
253
+ uint16_t event = value & PMXEVTYPER_EVTCOUNT;
84
+ assert(imx_epit_get_freq(s) == 0);
254
+ if (event_supported(event)) {
85
ptimer_stop(s->timer_cmp);
255
+ uint16_t event_idx = supported_event_map[event];
86
ptimer_stop(s->timer_reload);
256
+ env->cp15.c14_pmevcntr_delta[counter] =
87
- /* compute new frequency */
257
+ pm_events[event_idx].get_count(env);
88
- imx_epit_set_freq(s);
258
+ }
89
/* init both timers to EPIT_TIMER_MAX */
259
+}
90
ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
260
+
91
ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
261
+static uint64_t pmevtyper_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
92
- if (s->freq && (s->cr & CR_EN)) {
262
+{
93
- /* if the timer is still enabled, restart it */
263
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
94
- ptimer_run(s->timer_reload, 0);
264
+ return pmevtyper_read(env, ri, counter);
95
- }
265
+}
96
ptimer_transaction_commit(s->timer_cmp);
266
+
97
ptimer_transaction_commit(s->timer_reload);
267
+static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
98
}
268
+ uint64_t value)
99
269
+{
100
-static uint32_t imx_epit_update_count(IMXEPITState *s)
270
+ pmevtyper_write(env, ri, value, env->cp15.c9_pmselr & 31);
101
-{
271
+}
102
- s->cnt = ptimer_get_count(s->timer_reload);
272
+
103
-
273
static uint64_t pmxevtyper_read(CPUARMState *env, const ARMCPRegInfo *ri)
104
- return s->cnt;
105
-}
106
-
107
static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
274
{
108
{
275
- /* We opt to behave as a RAZ/WI when attempts to access PMXEVTYPER
109
IMXEPITState *s = IMX_EPIT(opaque);
276
- * are CONSTRAINED UNPREDICTABLE. See comments in pmxevtyper_write().
110
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
277
+ return pmevtyper_read(env, ri, env->cp15.c9_pmselr & 31);
111
break;
278
+}
112
279
+
113
case 4: /* CNT */
280
+static void pmevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
114
- imx_epit_update_count(s);
281
+ uint64_t value, uint8_t counter)
115
- reg_value = s->cnt;
282
+{
116
+ reg_value = ptimer_get_count(s->timer_reload);
283
+ if (counter < pmu_num_counters(env)) {
117
break;
284
+ pmevcntr_op_start(env, counter);
118
285
+ env->cp15.c14_pmevcntr[counter] = value;
119
default:
286
+ pmevcntr_op_finish(env, counter);
120
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
287
+ }
121
{
122
if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
123
/* if the compare feature is on and timers are running */
124
- uint32_t tmp = imx_epit_update_count(s);
125
+ uint32_t tmp = ptimer_get_count(s->timer_reload);
126
uint64_t next;
127
if (tmp > s->cmp) {
128
/* It'll fire in this round of the timer */
129
@@ -XXX,XX +XXX,XX @@ static void imx_epit_reload_compare_timer(IMXEPITState *s)
130
131
static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
132
{
133
+ uint32_t freq = 0;
134
uint32_t oldcr = s->cr;
135
136
s->cr = value & 0x03ffffff;
137
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
138
ptimer_transaction_begin(s->timer_cmp);
139
ptimer_transaction_begin(s->timer_reload);
140
141
- /* Update the frequency. Has been done already in case of a reset. */
288
+ /*
142
+ /*
289
+ * We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
143
+ * Update the frequency. In case of a reset the input clock was
290
+ * are CONSTRAINED UNPREDICTABLE.
144
+ * switched off, so this can be skipped.
291
*/
145
+ */
292
- if (env->cp15.c9_pmselr == 0x1f) {
146
if (!(s->cr & CR_SWR)) {
293
- return env->cp15.pmccfiltr_el0;
147
- imx_epit_set_freq(s);
294
+}
148
+ freq = imx_epit_get_freq(s);
295
+
149
+ if (freq) {
296
+static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
150
+ ptimer_set_freq(s->timer_reload, freq);
297
+ uint8_t counter)
151
+ ptimer_set_freq(s->timer_cmp, freq);
298
+{
152
+ }
299
+ if (counter < pmu_num_counters(env)) {
300
+ uint64_t ret;
301
+ pmevcntr_op_start(env, counter);
302
+ ret = env->cp15.c14_pmevcntr[counter];
303
+ pmevcntr_op_finish(env, counter);
304
+ return ret;
305
} else {
306
+ /* We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
307
+ * are CONSTRAINED UNPREDICTABLE. */
308
return 0;
309
}
153
}
310
}
154
311
155
- if (s->freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
312
+static void pmevcntr_writefn(CPUARMState *env, const ARMCPRegInfo *ri,
156
+ if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
313
+ uint64_t value)
157
if (s->cr & CR_ENMOD) {
314
+{
158
if (s->cr & CR_RLD) {
315
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
159
ptimer_set_limit(s->timer_reload, s->lr, 1);
316
+ pmevcntr_write(env, ri, value, counter);
160
@@ -XXX,XX +XXX,XX @@ static const MemoryRegionOps imx_epit_ops = {
317
+}
161
318
+
162
static const VMStateDescription vmstate_imx_timer_epit = {
319
+static uint64_t pmevcntr_readfn(CPUARMState *env, const ARMCPRegInfo *ri)
163
.name = TYPE_IMX_EPIT,
320
+{
164
- .version_id = 2,
321
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
165
- .minimum_version_id = 2,
322
+ return pmevcntr_read(env, ri, counter);
166
+ .version_id = 3,
323
+}
167
+ .minimum_version_id = 3,
324
+
168
.fields = (VMStateField[]) {
325
+static void pmevcntr_rawwrite(CPUARMState *env, const ARMCPRegInfo *ri,
169
VMSTATE_UINT32(cr, IMXEPITState),
326
+ uint64_t value)
170
VMSTATE_UINT32(sr, IMXEPITState),
327
+{
171
VMSTATE_UINT32(lr, IMXEPITState),
328
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
172
VMSTATE_UINT32(cmp, IMXEPITState),
329
+ assert(counter < pmu_num_counters(env));
173
- VMSTATE_UINT32(cnt, IMXEPITState),
330
+ env->cp15.c14_pmevcntr[counter] = value;
174
- VMSTATE_UINT32(freq, IMXEPITState),
331
+ pmevcntr_write(env, ri, value, counter);
175
VMSTATE_PTIMER(timer_reload, IMXEPITState),
332
+}
176
VMSTATE_PTIMER(timer_cmp, IMXEPITState),
333
+
177
VMSTATE_END_OF_LIST()
334
+static uint64_t pmevcntr_rawread(CPUARMState *env, const ARMCPRegInfo *ri)
335
+{
336
+ uint8_t counter = ((ri->crm & 3) << 3) | (ri->opc2 & 7);
337
+ assert(counter < pmu_num_counters(env));
338
+ return env->cp15.c14_pmevcntr[counter];
339
+}
340
+
341
+static void pmxevcntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
342
+ uint64_t value)
343
+{
344
+ pmevcntr_write(env, ri, value, env->cp15.c9_pmselr & 31);
345
+}
346
+
347
+static uint64_t pmxevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
348
+{
349
+ return pmevcntr_read(env, ri, env->cp15.c9_pmselr & 31);
350
+}
351
+
352
static void pmuserenr_write(CPUARMState *env, const ARMCPRegInfo *ri,
353
uint64_t value)
354
{
355
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
356
.fieldoffset = offsetof(CPUARMState, cp15.pmccfiltr_el0),
357
.resetvalue = 0, },
358
{ .name = "PMXEVTYPER", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 1,
359
- .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access,
360
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
361
+ .accessfn = pmreg_access,
362
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
363
{ .name = "PMXEVTYPER_EL0", .state = ARM_CP_STATE_AA64,
364
.opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 1,
365
- .access = PL0_RW, .type = ARM_CP_NO_RAW, .accessfn = pmreg_access,
366
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
367
+ .accessfn = pmreg_access,
368
.writefn = pmxevtyper_write, .readfn = pmxevtyper_read },
369
- /* Unimplemented, RAZ/WI. */
370
{ .name = "PMXEVCNTR", .cp = 15, .crn = 9, .crm = 13, .opc1 = 0, .opc2 = 2,
371
- .access = PL0_RW, .type = ARM_CP_CONST, .resetvalue = 0,
372
- .accessfn = pmreg_access_xevcntr },
373
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
374
+ .accessfn = pmreg_access_xevcntr,
375
+ .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
376
+ { .name = "PMXEVCNTR_EL0", .state = ARM_CP_STATE_AA64,
377
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 13, .opc2 = 2,
378
+ .access = PL0_RW, .type = ARM_CP_NO_RAW | ARM_CP_IO,
379
+ .accessfn = pmreg_access_xevcntr,
380
+ .writefn = pmxevcntr_write, .readfn = pmxevcntr_read },
381
{ .name = "PMUSERENR", .cp = 15, .crn = 9, .crm = 14, .opc1 = 0, .opc2 = 0,
382
.access = PL0_R | PL1_RW, .accessfn = access_tpm,
383
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmuserenr),
384
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
385
#endif
386
/* The only field of MDCR_EL2 that has a defined architectural reset value
387
* is MDCR_EL2.HPMN which should reset to the value of PMCR_EL0.N; but we
388
- * don't impelment any PMU event counters, so using zero as a reset
389
+ * don't implement any PMU event counters, so using zero as a reset
390
* value for MDCR_EL2 is okay
391
*/
392
{ .name = "MDCR_EL2", .state = ARM_CP_STATE_BOTH,
393
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
394
* field as main ID register, and we implement only the cycle
395
* count register.
396
*/
397
+ unsigned int i, pmcrn = 0;
398
#ifndef CONFIG_USER_ONLY
399
ARMCPRegInfo pmcr = {
400
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
401
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
402
};
403
define_one_arm_cp_reg(cpu, &pmcr);
404
define_one_arm_cp_reg(cpu, &pmcr64);
405
+ for (i = 0; i < pmcrn; i++) {
406
+ char *pmevcntr_name = g_strdup_printf("PMEVCNTR%d", i);
407
+ char *pmevcntr_el0_name = g_strdup_printf("PMEVCNTR%d_EL0", i);
408
+ char *pmevtyper_name = g_strdup_printf("PMEVTYPER%d", i);
409
+ char *pmevtyper_el0_name = g_strdup_printf("PMEVTYPER%d_EL0", i);
410
+ ARMCPRegInfo pmev_regs[] = {
411
+ { .name = pmevcntr_name, .cp = 15, .crn = 15,
412
+ .crm = 8 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
413
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
414
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
415
+ .accessfn = pmreg_access },
416
+ { .name = pmevcntr_el0_name, .state = ARM_CP_STATE_AA64,
417
+ .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 8 | (3 & (i >> 3)),
418
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
419
+ .type = ARM_CP_IO,
420
+ .readfn = pmevcntr_readfn, .writefn = pmevcntr_writefn,
421
+ .raw_readfn = pmevcntr_rawread,
422
+ .raw_writefn = pmevcntr_rawwrite },
423
+ { .name = pmevtyper_name, .cp = 15, .crn = 15,
424
+ .crm = 12 | (3 & (i >> 3)), .opc1 = 0, .opc2 = i & 7,
425
+ .access = PL0_RW, .type = ARM_CP_IO | ARM_CP_ALIAS,
426
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
427
+ .accessfn = pmreg_access },
428
+ { .name = pmevtyper_el0_name, .state = ARM_CP_STATE_AA64,
429
+ .opc0 = 3, .opc1 = 3, .crn = 15, .crm = 12 | (3 & (i >> 3)),
430
+ .opc2 = i & 7, .access = PL0_RW, .accessfn = pmreg_access,
431
+ .type = ARM_CP_IO,
432
+ .readfn = pmevtyper_readfn, .writefn = pmevtyper_writefn,
433
+ .raw_writefn = pmevtyper_rawwrite },
434
+ REGINFO_SENTINEL
435
+ };
436
+ define_arm_cp_regs(cpu, pmev_regs);
437
+ g_free(pmevcntr_name);
438
+ g_free(pmevcntr_el0_name);
439
+ g_free(pmevtyper_name);
440
+ g_free(pmevtyper_el0_name);
441
+ }
442
#endif
443
ARMCPRegInfo clidr = {
444
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
445
--
178
--
446
2.20.1
179
2.25.1
447
448
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Axel Heider <axel.heider@hensoldt.net>
2
2
3
This function is, or will shortly become, too big to inline.
3
- fix #1263 for CR writes
4
- rework compare time handling
5
- The compare timer has to run even if CR.OCIEN is not set,
6
as SR.OCIF must be updated.
7
- The compare timer fires exactly once when the
8
compare value is less than the current value, but the
9
reload values is less than the compare value.
10
- The compare timer will never fire if the reload value is
11
less than the compare value. Disable it in this case.
4
12
13
Signed-off-by: Axel Heider <axel.heider@hensoldt.net>
14
[PMM: fixed minor style nits]
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-16-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
17
---
10
target/arm/cpu.h | 48 +++++----------------------------------------
18
hw/timer/imx_epit.c | 192 ++++++++++++++++++++++++++------------------
11
target/arm/helper.c | 44 +++++++++++++++++++++++++++++++++++++++++
19
1 file changed, 116 insertions(+), 76 deletions(-)
12
2 files changed, 49 insertions(+), 43 deletions(-)
13
20
14
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
21
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
15
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/cpu.h
23
--- a/hw/timer/imx_epit.c
17
+++ b/target/arm/cpu.h
24
+++ b/hw/timer/imx_epit.c
18
@@ -XXX,XX +XXX,XX @@ static inline int arm_mmu_idx_to_el(ARMMMUIdx mmu_idx)
25
@@ -XXX,XX +XXX,XX @@
19
}
26
* Originally written by Hans Jiang
20
27
* Updated by Peter Chubb
21
/* Return the MMU index for a v7M CPU in the specified security and
28
* Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
22
- * privilege state
29
+ * Updated by Axel Heider
23
+ * privilege state.
30
*
24
*/
31
* This code is licensed under GPL version 2 or later. See
25
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
32
* the COPYING file in the top-level directory.
26
- bool secstate,
33
@@ -XXX,XX +XXX,XX @@ static uint64_t imx_epit_read(void *opaque, hwaddr offset, unsigned size)
27
- bool priv)
34
return reg_value;
28
-{
35
}
29
- ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
36
30
-
37
-/* Must be called from ptimer_transaction_begin/commit block for s->timer_cmp */
31
- if (priv) {
38
-static void imx_epit_reload_compare_timer(IMXEPITState *s)
32
- mmu_idx |= ARM_MMU_IDX_M_PRIV;
39
+/*
40
+ * Must be called from a ptimer_transaction_begin/commit block for
41
+ * s->timer_cmp, but outside of a transaction block of s->timer_reload,
42
+ * so the proper counter value is read.
43
+ */
44
+static void imx_epit_update_compare_timer(IMXEPITState *s)
45
{
46
- if ((s->cr & (CR_EN | CR_OCIEN)) == (CR_EN | CR_OCIEN)) {
47
- /* if the compare feature is on and timers are running */
48
- uint32_t tmp = ptimer_get_count(s->timer_reload);
49
- uint64_t next;
50
- if (tmp > s->cmp) {
51
- /* It'll fire in this round of the timer */
52
- next = tmp - s->cmp;
53
- } else { /* catch it next time around */
54
- next = tmp - s->cmp + ((s->cr & CR_RLD) ? EPIT_TIMER_MAX : s->lr);
55
+ uint64_t counter = 0;
56
+ bool is_oneshot = false;
57
+ /*
58
+ * The compare timer only has to run if the timer peripheral is active
59
+ * and there is an input clock, Otherwise it can be switched off.
60
+ */
61
+ bool is_active = (s->cr & CR_EN) && imx_epit_get_freq(s);
62
+ if (is_active) {
63
+ /*
64
+ * Calculate next timeout for compare timer. Reading the reload
65
+ * counter returns proper results only if pending transactions
66
+ * on it are committed here. Otherwise stale values are be read.
67
+ */
68
+ counter = ptimer_get_count(s->timer_reload);
69
+ uint64_t limit = ptimer_get_limit(s->timer_cmp);
70
+ /*
71
+ * The compare timer is a periodic timer if the limit is at least
72
+ * the compare value. Otherwise it may fire at most once in the
73
+ * current round.
74
+ */
75
+ bool is_oneshot = (limit >= s->cmp);
76
+ if (counter >= s->cmp) {
77
+ /* The compare timer fires in the current round. */
78
+ counter -= s->cmp;
79
+ } else if (!is_oneshot) {
80
+ /*
81
+ * The compare timer fires after a reload, as it is below the
82
+ * compare value already in this round. Note that the counter
83
+ * value calculated below can be above the 32-bit limit, which
84
+ * is legal here because the compare timer is an internal
85
+ * helper ptimer only.
86
+ */
87
+ counter += limit - s->cmp;
88
+ } else {
89
+ /*
90
+ * The compare timer won't fire in this round, and the limit is
91
+ * set to a value below the compare value. This practically means
92
+ * it will never fire, so it can be switched off.
93
+ */
94
+ is_active = false;
95
}
96
- ptimer_set_count(s->timer_cmp, next);
97
}
98
+
99
+ /*
100
+ * Set the compare timer and let it run, or stop it. This is agnostic
101
+ * of CR.OCIEN bit, as this bit affects interrupt generation only. The
102
+ * compare timer needs to run even if no interrupts are to be generated,
103
+ * because the SR.OCIF bit must be updated also.
104
+ * Note that the timer might already be stopped or be running with
105
+ * counter values. However, finding out when an update is needed and
106
+ * when not is not trivial. It's much easier applying the setting again,
107
+ * as this does not harm either and the overhead is negligible.
108
+ */
109
+ if (is_active) {
110
+ ptimer_set_count(s->timer_cmp, counter);
111
+ ptimer_run(s->timer_cmp, is_oneshot ? 1 : 0);
112
+ } else {
113
+ ptimer_stop(s->timer_cmp);
114
+ }
115
+
116
}
117
118
static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
119
{
120
- uint32_t freq = 0;
121
uint32_t oldcr = s->cr;
122
123
s->cr = value & 0x03ffffff;
124
125
if (s->cr & CR_SWR) {
126
- /* handle the reset */
127
+ /*
128
+ * Reset clears CR.SWR again. It does not touch CR.EN, but the timers
129
+ * are still stopped because the input clock is disabled.
130
+ */
131
imx_epit_reset(s, false);
132
+ } else {
133
+ uint32_t freq;
134
+ uint32_t toggled_cr_bits = oldcr ^ s->cr;
135
+ /* re-initialize the limits if CR.RLD has changed */
136
+ bool set_limit = toggled_cr_bits & CR_RLD;
137
+ /* set the counter if the timer got just enabled and CR.ENMOD is set */
138
+ bool is_switched_on = (toggled_cr_bits & s->cr) & CR_EN;
139
+ bool set_counter = is_switched_on && (s->cr & CR_ENMOD);
140
+
141
+ ptimer_transaction_begin(s->timer_cmp);
142
+ ptimer_transaction_begin(s->timer_reload);
143
+ freq = imx_epit_get_freq(s);
144
+ if (freq) {
145
+ ptimer_set_freq(s->timer_reload, freq);
146
+ ptimer_set_freq(s->timer_cmp, freq);
147
+ }
148
+
149
+ if (set_limit || set_counter) {
150
+ uint64_t limit = (s->cr & CR_RLD) ? s->lr : EPIT_TIMER_MAX;
151
+ ptimer_set_limit(s->timer_reload, limit, set_counter ? 1 : 0);
152
+ if (set_limit) {
153
+ ptimer_set_limit(s->timer_cmp, limit, 0);
154
+ }
155
+ }
156
+ /*
157
+ * If there is an input clock and the peripheral is enabled, then
158
+ * ensure the wall clock timer is ticking. Otherwise stop the timers.
159
+ * The compare timer will be updated later.
160
+ */
161
+ if (freq && (s->cr & CR_EN)) {
162
+ ptimer_run(s->timer_reload, 0);
163
+ } else {
164
+ ptimer_stop(s->timer_reload);
165
+ }
166
+ /* Commit changes to reload timer, so they can propagate. */
167
+ ptimer_transaction_commit(s->timer_reload);
168
+ /* Update compare timer based on the committed reload timer value. */
169
+ imx_epit_update_compare_timer(s);
170
+ ptimer_transaction_commit(s->timer_cmp);
171
}
172
173
/*
174
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cr(IMXEPITState *s, uint32_t value)
175
* - write to CR.EN or CR.OCIE
176
*/
177
imx_epit_update_int(s);
178
-
179
- /*
180
- * TODO: could we 'break' here for reset? following operations appear
181
- * to duplicate the work imx_epit_reset() already did.
182
- */
183
-
184
- ptimer_transaction_begin(s->timer_cmp);
185
- ptimer_transaction_begin(s->timer_reload);
186
-
187
- /*
188
- * Update the frequency. In case of a reset the input clock was
189
- * switched off, so this can be skipped.
190
- */
191
- if (!(s->cr & CR_SWR)) {
192
- freq = imx_epit_get_freq(s);
193
- if (freq) {
194
- ptimer_set_freq(s->timer_reload, freq);
195
- ptimer_set_freq(s->timer_cmp, freq);
196
- }
33
- }
197
- }
34
-
198
-
35
- if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
199
- if (freq && (s->cr & CR_EN) && !(oldcr & CR_EN)) {
36
- mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
200
- if (s->cr & CR_ENMOD) {
201
- if (s->cr & CR_RLD) {
202
- ptimer_set_limit(s->timer_reload, s->lr, 1);
203
- ptimer_set_limit(s->timer_cmp, s->lr, 1);
204
- } else {
205
- ptimer_set_limit(s->timer_reload, EPIT_TIMER_MAX, 1);
206
- ptimer_set_limit(s->timer_cmp, EPIT_TIMER_MAX, 1);
207
- }
208
- }
209
-
210
- imx_epit_reload_compare_timer(s);
211
- ptimer_run(s->timer_reload, 0);
212
- if (s->cr & CR_OCIEN) {
213
- ptimer_run(s->timer_cmp, 0);
214
- } else {
215
- ptimer_stop(s->timer_cmp);
216
- }
217
- } else if (!(s->cr & CR_EN)) {
218
- /* stop both timers */
219
- ptimer_stop(s->timer_reload);
220
- ptimer_stop(s->timer_cmp);
221
- } else if (s->cr & CR_OCIEN) {
222
- if (!(oldcr & CR_OCIEN)) {
223
- imx_epit_reload_compare_timer(s);
224
- ptimer_run(s->timer_cmp, 0);
225
- }
226
- } else {
227
- ptimer_stop(s->timer_cmp);
37
- }
228
- }
38
-
229
-
39
- if (secstate) {
230
- ptimer_transaction_commit(s->timer_cmp);
40
- mmu_idx |= ARM_MMU_IDX_M_S;
231
- ptimer_transaction_commit(s->timer_reload);
41
- }
232
}
42
-
233
43
- return mmu_idx;
234
static void imx_epit_write_sr(IMXEPITState *s, uint32_t value)
44
-}
235
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_lr(IMXEPITState *s, uint32_t value)
45
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
236
/* If IOVW bit is set then set the timer value */
46
+ bool secstate, bool priv);
237
ptimer_set_count(s->timer_reload, s->lr);
47
238
}
48
/* Return the MMU index for a v7M CPU in the specified security state */
239
- /*
49
-static inline ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env,
240
- * Commit the change to s->timer_reload, so it can propagate. Otherwise
50
- bool secstate)
241
- * the timer interrupt may not fire properly. The commit must happen
51
-{
242
- * before calling imx_epit_reload_compare_timer(), which reads
52
- bool priv = arm_current_el(env) != 0;
243
- * s->timer_reload internally again.
53
-
244
- */
54
- return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
245
+ /* Commit the changes to s->timer_reload, so they can propagate. */
55
-}
246
ptimer_transaction_commit(s->timer_reload);
56
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
247
- imx_epit_reload_compare_timer(s);
57
248
+ /* Update the compare timer based on the committed reload timer value. */
58
/* Determine the current mmu_idx to use for normal loads/stores */
249
+ imx_epit_update_compare_timer(s);
59
-static inline int cpu_mmu_index(CPUARMState *env, bool ifetch)
250
ptimer_transaction_commit(s->timer_cmp);
60
-{
251
}
61
- int el = arm_current_el(env);
252
62
-
253
@@ -XXX,XX +XXX,XX @@ static void imx_epit_write_cmp(IMXEPITState *s, uint32_t value)
63
- if (arm_feature(env, ARM_FEATURE_M)) {
254
{
64
- ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
255
s->cmp = value;
65
-
256
66
- return arm_to_core_mmu_idx(mmu_idx);
257
+ /* Update the compare timer based on the committed reload timer value. */
67
- }
258
ptimer_transaction_begin(s->timer_cmp);
68
-
259
- imx_epit_reload_compare_timer(s);
69
- if (el < 2 && arm_is_secure_below_el3(env)) {
260
+ imx_epit_update_compare_timer(s);
70
- return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
261
ptimer_transaction_commit(s->timer_cmp);
71
- }
262
}
72
- return el;
263
73
-}
264
@@ -XXX,XX +XXX,XX @@ static void imx_epit_cmp(void *opaque)
74
+int cpu_mmu_index(CPUARMState *env, bool ifetch);
265
{
75
266
IMXEPITState *s = IMX_EPIT(opaque);
76
/* Indexes used when registering address spaces with cpu_address_space_init */
267
77
typedef enum ARMASIdx {
268
+ /* The cmp ptimer can't be running when the peripheral is disabled */
78
diff --git a/target/arm/helper.c b/target/arm/helper.c
269
+ assert(s->cr & CR_EN);
79
index XXXXXXX..XXXXXXX 100644
270
+
80
--- a/target/arm/helper.c
271
DPRINTF("sr was %d\n", s->sr);
81
+++ b/target/arm/helper.c
272
/* Set interrupt status bit SR.OCIF and update the interrupt state */
82
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
273
s->sr |= SR_OCIF;
83
return 0;
84
}
85
86
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
87
+ bool secstate, bool priv)
88
+{
89
+ ARMMMUIdx mmu_idx = ARM_MMU_IDX_M;
90
+
91
+ if (priv) {
92
+ mmu_idx |= ARM_MMU_IDX_M_PRIV;
93
+ }
94
+
95
+ if (armv7m_nvic_neg_prio_requested(env->nvic, secstate)) {
96
+ mmu_idx |= ARM_MMU_IDX_M_NEGPRI;
97
+ }
98
+
99
+ if (secstate) {
100
+ mmu_idx |= ARM_MMU_IDX_M_S;
101
+ }
102
+
103
+ return mmu_idx;
104
+}
105
+
106
+/* Return the MMU index for a v7M CPU in the specified security state */
107
+ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
108
+{
109
+ bool priv = arm_current_el(env) != 0;
110
+
111
+ return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
112
+}
113
+
114
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
115
+{
116
+ int el = arm_current_el(env);
117
+
118
+ if (arm_feature(env, ARM_FEATURE_M)) {
119
+ ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
120
+
121
+ return arm_to_core_mmu_idx(mmu_idx);
122
+ }
123
+
124
+ if (el < 2 && arm_is_secure_below_el3(env)) {
125
+ return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
126
+ }
127
+ return el;
128
+}
129
+
130
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
131
target_ulong *cs_base, uint32_t *pflags)
132
{
133
--
274
--
134
2.20.1
275
2.25.1
135
136
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
We will want to check TBI for I and D simultaneously.
3
Fix these:
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
WARNING: Block comments use a leading /* on a separate line
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
WARNING: Block comments use * on subsequent lines
7
Message-id: 20190108223129.5570-22-richard.henderson@linaro.org
7
WARNING: Block comments use a trailing */ on a separate line
8
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Reviewed-by: Claudio Fontana <cfontana@suse.de>
11
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
12
Message-id: 20221213190537.511-2-farosas@suse.de
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
14
---
10
target/arm/internals.h | 15 ++++++++++++---
15
target/arm/helper.c | 323 +++++++++++++++++++++++++++++---------------
11
target/arm/helper.c | 10 ++++++++--
16
1 file changed, 215 insertions(+), 108 deletions(-)
12
2 files changed, 20 insertions(+), 5 deletions(-)
13
17
14
diff --git a/target/arm/internals.h b/target/arm/internals.h
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/internals.h
17
+++ b/target/arm/internals.h
18
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
19
} ARMVAParameters;
20
21
#ifdef CONFIG_USER_ONLY
22
-static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
23
- uint64_t va,
24
- ARMMMUIdx mmu_idx, bool data)
25
+static inline ARMVAParameters aa64_va_parameters_both(CPUARMState *env,
26
+ uint64_t va,
27
+ ARMMMUIdx mmu_idx)
28
{
29
return (ARMVAParameters) {
30
/* 48-bit address space */
31
@@ -XXX,XX +XXX,XX @@ static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
32
.tbi = false,
33
};
34
}
35
+
36
+static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
37
+ uint64_t va,
38
+ ARMMMUIdx mmu_idx, bool data)
39
+{
40
+ return aa64_va_parameters_both(env, va, mmu_idx);
41
+}
42
#else
43
+ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
44
+ ARMMMUIdx mmu_idx);
45
ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
46
ARMMMUIdx mmu_idx, bool data);
47
#endif
48
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
diff --git a/target/arm/helper.c b/target/arm/helper.c
49
index XXXXXXX..XXXXXXX 100644
19
index XXXXXXX..XXXXXXX 100644
50
--- a/target/arm/helper.c
20
--- a/target/arm/helper.c
51
+++ b/target/arm/helper.c
21
+++ b/target/arm/helper.c
52
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
22
@@ -XXX,XX +XXX,XX @@ uint64_t read_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri)
53
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
23
static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
54
}
24
uint64_t v)
55
25
{
56
-ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
26
- /* Raw write of a coprocessor register (as needed for migration, etc).
57
- ARMMMUIdx mmu_idx, bool data)
27
+ /*
58
+ARMVAParameters aa64_va_parameters_both(CPUARMState *env, uint64_t va,
28
+ * Raw write of a coprocessor register (as needed for migration, etc).
59
+ ARMMMUIdx mmu_idx)
29
* Note that constant registers are treated as write-ignored; the
60
{
30
* caller should check for success by whether a readback gives the
61
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
31
* value written.
62
uint32_t el = regime_el(env, mmu_idx);
32
@@ -XXX,XX +XXX,XX @@ static void write_raw_cp_reg(CPUARMState *env, const ARMCPRegInfo *ri,
33
34
static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
35
{
36
- /* Return true if the regdef would cause an assertion if you called
37
+ /*
38
+ * Return true if the regdef would cause an assertion if you called
39
* read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
40
* program bug for it not to have the NO_RAW flag).
41
* NB that returning false here doesn't necessarily mean that calling
42
@@ -XXX,XX +XXX,XX @@ bool write_list_to_cpustate(ARMCPU *cpu)
43
if (ri->type & ARM_CP_NO_RAW) {
44
continue;
45
}
46
- /* Write value and confirm it reads back as written
47
+ /*
48
+ * Write value and confirm it reads back as written
49
* (to catch read-only registers and partially read-only
50
* registers where the incoming migration value doesn't match)
51
*/
52
@@ -XXX,XX +XXX,XX @@ static gint cpreg_key_compare(gconstpointer a, gconstpointer b)
53
54
void init_cpreg_list(ARMCPU *cpu)
55
{
56
- /* Initialise the cpreg_tuples[] array based on the cp_regs hash.
57
+ /*
58
+ * Initialise the cpreg_tuples[] array based on the cp_regs hash.
59
* Note that we require cpreg_tuples[] to be sorted by key ID.
60
*/
61
GList *keys;
62
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_el3_aa32ns(CPUARMState *env,
63
return CP_ACCESS_OK;
64
}
65
66
-/* Some secure-only AArch32 registers trap to EL3 if used from
67
+/*
68
+ * Some secure-only AArch32 registers trap to EL3 if used from
69
* Secure EL1 (but are just ordinary UNDEF in other non-EL3 contexts).
70
* Note that an access from Secure EL1 can only happen if EL3 is AArch64.
71
* We assume that the .access field is set to PL1_RW.
72
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_trap_aa32s_el1(CPUARMState *env,
73
return CP_ACCESS_TRAP_UNCATEGORIZED;
74
}
75
76
-/* Check for traps to performance monitor registers, which are controlled
77
+/*
78
+ * Check for traps to performance monitor registers, which are controlled
79
* by MDCR_EL2.TPM for EL2 and MDCR_EL3.TPM for EL3.
80
*/
81
static CPAccessResult access_tpm(CPUARMState *env, const ARMCPRegInfo *ri,
82
@@ -XXX,XX +XXX,XX @@ static void fcse_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
83
ARMCPU *cpu = env_archcpu(env);
84
85
if (raw_read(env, ri) != value) {
86
- /* Unlike real hardware the qemu TLB uses virtual addresses,
87
+ /*
88
+ * Unlike real hardware the qemu TLB uses virtual addresses,
89
* not modified virtual addresses, so this causes a TLB flush.
90
*/
91
tlb_flush(CPU(cpu));
92
@@ -XXX,XX +XXX,XX @@ static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri,
93
94
if (raw_read(env, ri) != value && !arm_feature(env, ARM_FEATURE_PMSA)
95
&& !extended_addresses_enabled(env)) {
96
- /* For VMSA (when not using the LPAE long descriptor page table
97
+ /*
98
+ * For VMSA (when not using the LPAE long descriptor page table
99
* format) this register includes the ASID, so do a TLB flush.
100
* For PMSA it is purely a process ID and no action is needed.
101
*/
102
@@ -XXX,XX +XXX,XX @@ static void tlbiipas2is_hyp_write(CPUARMState *env, const ARMCPRegInfo *ri,
103
}
104
105
static const ARMCPRegInfo cp_reginfo[] = {
106
- /* Define the secure and non-secure FCSE identifier CP registers
107
+ /*
108
+ * Define the secure and non-secure FCSE identifier CP registers
109
* separately because there is no secure bank in V8 (no _EL3). This allows
110
* the secure register to be properly reset and migrated. There is also no
111
* v8 EL1 version of the register so the non-secure instance stands alone.
112
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
113
.access = PL1_RW, .secure = ARM_CP_SECSTATE_S,
114
.fieldoffset = offsetof(CPUARMState, cp15.fcseidr_s),
115
.resetvalue = 0, .writefn = fcse_write, .raw_writefn = raw_write, },
116
- /* Define the secure and non-secure context identifier CP registers
117
+ /*
118
+ * Define the secure and non-secure context identifier CP registers
119
* separately because there is no secure bank in V8 (no _EL3). This allows
120
* the secure register to be properly reset and migrated. In the
121
* non-secure case, the 32-bit register will have reset and migration
122
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cp_reginfo[] = {
123
};
124
125
static const ARMCPRegInfo not_v8_cp_reginfo[] = {
126
- /* NB: Some of these registers exist in v8 but with more precise
127
+ /*
128
+ * NB: Some of these registers exist in v8 but with more precise
129
* definitions that don't use CP_ANY wildcards (mostly in v8_cp_reginfo[]).
130
*/
131
/* MMU Domain access control / MPU write buffer control */
132
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
133
.writefn = dacr_write, .raw_writefn = raw_write,
134
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.dacr_s),
135
offsetoflow32(CPUARMState, cp15.dacr_ns) } },
136
- /* ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs.
137
+ /*
138
+ * ARMv7 allocates a range of implementation defined TLB LOCKDOWN regs.
139
* For v6 and v5, these mappings are overly broad.
140
*/
141
{ .name = "TLB_LOCKDOWN", .cp = 15, .crn = 10, .crm = 0,
142
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v8_cp_reginfo[] = {
143
};
144
145
static const ARMCPRegInfo not_v6_cp_reginfo[] = {
146
- /* Not all pre-v6 cores implemented this WFI, so this is slightly
147
+ /*
148
+ * Not all pre-v6 cores implemented this WFI, so this is slightly
149
* over-broad.
150
*/
151
{ .name = "WFI_v5", .cp = 15, .crn = 7, .crm = 8, .opc1 = 0, .opc2 = 2,
152
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v6_cp_reginfo[] = {
153
};
154
155
static const ARMCPRegInfo not_v7_cp_reginfo[] = {
156
- /* Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which
157
+ /*
158
+ * Standard v6 WFI (also used in some pre-v6 cores); not in v7 (which
159
* is UNPREDICTABLE; we choose to NOP as most implementations do).
160
*/
161
{ .name = "WFI_v6", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
162
.access = PL1_W, .type = ARM_CP_WFI },
163
- /* L1 cache lockdown. Not architectural in v6 and earlier but in practice
164
+ /*
165
+ * L1 cache lockdown. Not architectural in v6 and earlier but in practice
166
* implemented in 926, 946, 1026, 1136, 1176 and 11MPCore. StrongARM and
167
* OMAPCP will override this space.
168
*/
169
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo not_v7_cp_reginfo[] = {
170
{ .name = "DUMMY", .cp = 15, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = CP_ANY,
171
.access = PL1_R, .type = ARM_CP_CONST | ARM_CP_NO_RAW,
172
.resetvalue = 0 },
173
- /* We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR;
174
+ /*
175
+ * We don't implement pre-v7 debug but most CPUs had at least a DBGDIDR;
176
* implementing it as RAZ means the "debug architecture version" bits
177
* will read as a reserved value, which should cause Linux to not try
178
* to use the debug hardware.
179
*/
180
{ .name = "DBGDIDR", .cp = 14, .crn = 0, .crm = 0, .opc1 = 0, .opc2 = 0,
181
.access = PL0_R, .type = ARM_CP_CONST, .resetvalue = 0 },
182
- /* MMU TLB control. Note that the wildcarding means we cover not just
183
+ /*
184
+ * MMU TLB control. Note that the wildcarding means we cover not just
185
* the unified TLB ops but also the dside/iside/inner-shareable variants.
186
*/
187
{ .name = "TLBIALL", .cp = 15, .crn = 8, .crm = CP_ANY,
188
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
189
190
/* In ARMv8 most bits of CPACR_EL1 are RES0. */
191
if (!arm_feature(env, ARM_FEATURE_V8)) {
192
- /* ARMv7 defines bits for unimplemented coprocessors as RAZ/WI.
193
+ /*
194
+ * ARMv7 defines bits for unimplemented coprocessors as RAZ/WI.
195
* ASEDIS [31] and D32DIS [30] are both UNK/SBZP without VFP.
196
* TRCDIS [28] is RAZ/WI since we do not implement a trace macrocell.
197
*/
198
@@ -XXX,XX +XXX,XX @@ static void cpacr_write(CPUARMState *env, const ARMCPRegInfo *ri,
199
value |= R_CPACR_ASEDIS_MASK;
200
}
201
202
- /* VFPv3 and upwards with NEON implement 32 double precision
203
+ /*
204
+ * VFPv3 and upwards with NEON implement 32 double precision
205
* registers (D0-D31).
206
*/
207
if (!cpu_isar_feature(aa32_simd_r32, env_archcpu(env))) {
208
@@ -XXX,XX +XXX,XX @@ static uint64_t cpacr_read(CPUARMState *env, const ARMCPRegInfo *ri)
209
210
static void cpacr_reset(CPUARMState *env, const ARMCPRegInfo *ri)
211
{
212
- /* Call cpacr_write() so that we reset with the correct RAO bits set
213
+ /*
214
+ * Call cpacr_write() so that we reset with the correct RAO bits set
215
* for our CPU features.
216
*/
217
cpacr_write(env, ri, 0);
218
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
219
{ .name = "MVA_prefetch",
220
.cp = 15, .crn = 7, .crm = 13, .opc1 = 0, .opc2 = 1,
221
.access = PL1_W, .type = ARM_CP_NOP },
222
- /* We need to break the TB after ISB to execute self-modifying code
223
+ /*
224
+ * We need to break the TB after ISB to execute self-modifying code
225
* correctly and also to take any pending interrupts immediately.
226
* So use arm_cp_write_ignore() function instead of ARM_CP_NOP flag.
227
*/
228
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6_cp_reginfo[] = {
229
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.ifar_s),
230
offsetof(CPUARMState, cp15.ifar_ns) },
231
.resetvalue = 0, },
232
- /* Watchpoint Fault Address Register : should actually only be present
233
+ /*
234
+ * Watchpoint Fault Address Register : should actually only be present
235
* for 1136, 1176, 11MPCore.
236
*/
237
{ .name = "WFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
238
@@ -XXX,XX +XXX,XX @@ static bool event_supported(uint16_t number)
239
static CPAccessResult pmreg_access(CPUARMState *env, const ARMCPRegInfo *ri,
240
bool isread)
241
{
242
- /* Performance monitor registers user accessibility is controlled
243
+ /*
244
+ * Performance monitor registers user accessibility is controlled
245
* by PMUSERENR. MDCR_EL2.TPM and MDCR_EL3.TPM allow configurable
246
* trapping to EL2 or EL3 for other accesses.
247
*/
248
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_ccntr(CPUARMState *env,
249
(MDCR_HPME | MDCR_HPMD | MDCR_HPMN | MDCR_HCCD | MDCR_HLP)
250
#define MDCR_EL3_PMU_ENABLE_BITS (MDCR_SPME | MDCR_SCCD)
251
252
-/* Returns true if the counter (pass 31 for PMCCNTR) should count events using
253
+/*
254
+ * Returns true if the counter (pass 31 for PMCCNTR) should count events using
255
* the current EL, security state, and register configuration.
256
*/
257
static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
258
@@ -XXX,XX +XXX,XX @@ static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
259
static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
260
uint64_t value)
261
{
262
- /* The value of PMSELR.SEL affects the behavior of PMXEVTYPER and
263
+ /*
264
+ * The value of PMSELR.SEL affects the behavior of PMXEVTYPER and
265
* PMXEVCNTR. We allow [0..31] to be written to PMSELR here; in the
266
* meanwhile, we check PMSELR.SEL when PMXEVTYPER and PMXEVCNTR are
267
* accessed.
268
@@ -XXX,XX +XXX,XX @@ static void pmevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
269
env->cp15.c14_pmevtyper[counter] = value & PMXEVTYPER_MASK;
270
pmevcntr_op_finish(env, counter);
271
}
272
- /* Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
273
+ /*
274
+ * Attempts to access PMXEVTYPER are CONSTRAINED UNPREDICTABLE when
275
* PMSELR value is equal to or greater than the number of implemented
276
* counters, but not equal to 0x1f. We opt to behave as a RAZ/WI.
277
*/
278
@@ -XXX,XX +XXX,XX @@ static uint64_t pmevcntr_read(CPUARMState *env, const ARMCPRegInfo *ri,
279
}
280
return ret;
281
} else {
282
- /* We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
283
- * are CONSTRAINED UNPREDICTABLE. */
284
+ /*
285
+ * We opt to behave as a RAZ/WI when attempts to access PM[X]EVCNTR
286
+ * are CONSTRAINED UNPREDICTABLE.
287
+ */
288
return 0;
289
}
290
}
291
@@ -XXX,XX +XXX,XX @@ static void pmintenclr_write(CPUARMState *env, const ARMCPRegInfo *ri,
292
static void vbar_write(CPUARMState *env, const ARMCPRegInfo *ri,
293
uint64_t value)
294
{
295
- /* Note that even though the AArch64 view of this register has bits
296
+ /*
297
+ * Note that even though the AArch64 view of this register has bits
298
* [10:0] all RES0 we can only mask the bottom 5, to comply with the
299
* architectural requirements for bits which are RES0 only in some
300
* contexts. (ARMv8 would permit us to do no masking at all, but ARMv7
301
@@ -XXX,XX +XXX,XX @@ static void scr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value)
302
if (!arm_feature(env, ARM_FEATURE_EL2)) {
303
valid_mask &= ~SCR_HCE;
304
305
- /* On ARMv7, SMD (or SCD as it is called in v7) is only
306
+ /*
307
+ * On ARMv7, SMD (or SCD as it is called in v7) is only
308
* supported if EL2 exists. The bit is UNK/SBZP when
309
* EL2 is unavailable. In QEMU ARMv7, we force it to always zero
310
* when EL2 is unavailable.
311
@@ -XXX,XX +XXX,XX @@ static uint64_t ccsidr_read(CPUARMState *env, const ARMCPRegInfo *ri)
312
{
313
ARMCPU *cpu = env_archcpu(env);
314
315
- /* Acquire the CSSELR index from the bank corresponding to the CCSIDR
316
+ /*
317
+ * Acquire the CSSELR index from the bank corresponding to the CCSIDR
318
* bank
319
*/
320
uint32_t index = A32_BANKED_REG_GET(env, csselr,
321
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
322
/* the old v6 WFI, UNPREDICTABLE in v7 but we choose to NOP */
323
{ .name = "NOP", .cp = 15, .crn = 7, .crm = 0, .opc1 = 0, .opc2 = 4,
324
.access = PL1_W, .type = ARM_CP_NOP },
325
- /* Performance monitors are implementation defined in v7,
326
+ /*
327
+ * Performance monitors are implementation defined in v7,
328
* but with an ARM recommended set of registers, which we
329
* follow.
330
*
331
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
332
.writefn = csselr_write, .resetvalue = 0,
333
.bank_fieldoffsets = { offsetof(CPUARMState, cp15.csselr_s),
334
offsetof(CPUARMState, cp15.csselr_ns) } },
335
- /* Auxiliary ID register: this actually has an IMPDEF value but for now
336
+ /*
337
+ * Auxiliary ID register: this actually has an IMPDEF value but for now
338
* just RAZ for all cores:
339
*/
340
{ .name = "AIDR", .state = ARM_CP_STATE_BOTH,
341
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
342
.access = PL1_R, .type = ARM_CP_CONST,
343
.accessfn = access_aa64_tid1,
344
.resetvalue = 0 },
345
- /* Auxiliary fault status registers: these also are IMPDEF, and we
346
+ /*
347
+ * Auxiliary fault status registers: these also are IMPDEF, and we
348
* choose to RAZ/WI for all cores.
349
*/
350
{ .name = "AFSR0_EL1", .state = ARM_CP_STATE_BOTH,
351
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
352
.opc0 = 3, .opc1 = 0, .crn = 5, .crm = 1, .opc2 = 1,
353
.access = PL1_RW, .accessfn = access_tvm_trvm,
354
.type = ARM_CP_CONST, .resetvalue = 0 },
355
- /* MAIR can just read-as-written because we don't implement caches
356
+ /*
357
+ * MAIR can just read-as-written because we don't implement caches
358
* and so don't need to care about memory attributes.
359
*/
360
{ .name = "MAIR_EL1", .state = ARM_CP_STATE_AA64,
361
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
362
.opc0 = 3, .opc1 = 6, .crn = 10, .crm = 2, .opc2 = 0,
363
.access = PL3_RW, .fieldoffset = offsetof(CPUARMState, cp15.mair_el[3]),
364
.resetvalue = 0 },
365
- /* For non-long-descriptor page tables these are PRRR and NMRR;
366
+ /*
367
+ * For non-long-descriptor page tables these are PRRR and NMRR;
368
* regardless they still act as reads-as-written for QEMU.
369
*/
370
- /* MAIR0/1 are defined separately from their 64-bit counterpart which
371
+ /*
372
+ * MAIR0/1 are defined separately from their 64-bit counterpart which
373
* allows them to assign the correct fieldoffset based on the endianness
374
* handled in the field definitions.
375
*/
376
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
377
static CPAccessResult gt_cntfrq_access(CPUARMState *env, const ARMCPRegInfo *ri,
378
bool isread)
379
{
380
- /* CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero.
381
+ /*
382
+ * CNTFRQ: not visible from PL0 if both PL0PCTEN and PL0VCTEN are zero.
383
* Writable only at the highest implemented exception level.
384
*/
385
int el = arm_current_el(env);
386
@@ -XXX,XX +XXX,XX @@ static CPAccessResult gt_stimer_access(CPUARMState *env,
387
const ARMCPRegInfo *ri,
388
bool isread)
389
{
390
- /* The AArch64 register view of the secure physical timer is
391
+ /*
392
+ * The AArch64 register view of the secure physical timer is
393
* always accessible from EL3, and configurably accessible from
394
* Secure EL1.
395
*/
396
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
397
ARMGenericTimer *gt = &cpu->env.cp15.c14_timer[timeridx];
398
399
if (gt->ctl & 1) {
400
- /* Timer enabled: calculate and set current ISTATUS, irq, and
401
+ /*
402
+ * Timer enabled: calculate and set current ISTATUS, irq, and
403
* reset timer to when ISTATUS next has to change
404
*/
405
uint64_t offset = timeridx == GTIMER_VIRT ?
406
@@ -XXX,XX +XXX,XX @@ static void gt_recalc_timer(ARMCPU *cpu, int timeridx)
407
/* Next transition is when we hit cval */
408
nexttick = gt->cval + offset;
409
}
410
- /* Note that the desired next expiry time might be beyond the
411
+ /*
412
+ * Note that the desired next expiry time might be beyond the
413
* signed-64-bit range of a QEMUTimer -- in this case we just
414
* set the timer for as far in the future as possible. When the
415
* timer expires we will reset the timer for any remaining period.
416
@@ -XXX,XX +XXX,XX @@ static void gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri,
417
/* Enable toggled */
418
gt_recalc_timer(cpu, timeridx);
419
} else if ((oldval ^ value) & 2) {
420
- /* IMASK toggled: don't need to recalculate,
421
+ /*
422
+ * IMASK toggled: don't need to recalculate,
423
* just set the interrupt line based on ISTATUS
424
*/
425
int irqstate = (oldval & 4) && !(value & 2);
426
@@ -XXX,XX +XXX,XX @@ static void arm_gt_cntfrq_reset(CPUARMState *env, const ARMCPRegInfo *opaque)
427
}
428
429
static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
430
- /* Note that CNTFRQ is purely reads-as-written for the benefit
431
+ /*
432
+ * Note that CNTFRQ is purely reads-as-written for the benefit
433
* of software; writing it doesn't actually change the timer frequency.
434
* Our reset value matches the fixed frequency we implement the timer at.
435
*/
436
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo generic_timer_cp_reginfo[] = {
437
.readfn = gt_virt_redir_cval_read, .raw_readfn = raw_read,
438
.writefn = gt_virt_redir_cval_write, .raw_writefn = raw_write,
439
},
440
- /* Secure timer -- this is actually restricted to only EL3
441
+ /*
442
+ * Secure timer -- this is actually restricted to only EL3
443
* and configurably Secure-EL1 via the accessfn.
444
*/
445
{ .name = "CNTPS_TVAL_EL1", .state = ARM_CP_STATE_AA64,
446
@@ -XXX,XX +XXX,XX @@ static CPAccessResult e2h_access(CPUARMState *env, const ARMCPRegInfo *ri,
447
448
#else
449
450
-/* In user-mode most of the generic timer registers are inaccessible
451
+/*
452
+ * In user-mode most of the generic timer registers are inaccessible
453
* however modern kernels (4.12+) allow access to cntvct_el0
454
*/
455
456
@@ -XXX,XX +XXX,XX @@ static uint64_t gt_virt_cnt_read(CPUARMState *env, const ARMCPRegInfo *ri)
457
{
458
ARMCPU *cpu = env_archcpu(env);
459
460
- /* Currently we have no support for QEMUTimer in linux-user so we
461
+ /*
462
+ * Currently we have no support for QEMUTimer in linux-user so we
463
* can't call gt_get_countervalue(env), instead we directly
464
* call the lower level functions.
465
*/
466
@@ -XXX,XX +XXX,XX @@ static CPAccessResult ats_access(CPUARMState *env, const ARMCPRegInfo *ri,
467
bool isread)
468
{
469
if (ri->opc2 & 4) {
470
- /* The ATS12NSO* operations must trap to EL3 or EL2 if executed in
471
+ /*
472
+ * The ATS12NSO* operations must trap to EL3 or EL2 if executed in
473
* Secure EL1 (which can only happen if EL3 is AArch64).
474
* They are simply UNDEF if executed from NS EL1.
475
* They function normally from EL2 or EL3.
476
@@ -XXX,XX +XXX,XX @@ static uint64_t do_ats_write(CPUARMState *env, uint64_t value,
477
}
478
}
479
} else {
480
- /* fsr is a DFSR/IFSR value for the short descriptor
481
+ /*
482
+ * fsr is a DFSR/IFSR value for the short descriptor
483
* translation table format (with WnR always clear).
484
* Convert it to a 32-bit PAR.
485
*/
486
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo pmsav8r_cp_reginfo[] = {
487
};
488
489
static const ARMCPRegInfo pmsav7_cp_reginfo[] = {
490
- /* Reset for all these registers is handled in arm_cpu_reset(),
491
+ /*
492
+ * Reset for all these registers is handled in arm_cpu_reset(),
493
* because the PMSAv7 is also used by M-profile CPUs, which do
494
* not register cpregs but still need the state to be reset.
495
*/
496
@@ -XXX,XX +XXX,XX @@ static void vmsa_ttbcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
497
}
498
499
if (arm_feature(env, ARM_FEATURE_LPAE)) {
500
- /* With LPAE the TTBCR could result in a change of ASID
501
+ /*
502
+ * With LPAE the TTBCR could result in a change of ASID
503
* via the TTBCR.A1 bit, so do a TLB flush.
504
*/
505
tlb_flush(CPU(cpu));
506
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo vmsa_cp_reginfo[] = {
507
offsetoflow32(CPUARMState, cp15.tcr_el[1])} },
508
};
509
510
-/* Note that unlike TTBCR, writing to TTBCR2 does not require flushing
511
+/*
512
+ * Note that unlike TTBCR, writing to TTBCR2 does not require flushing
513
* qemu tlbs nor adjusting cached masks.
514
*/
515
static const ARMCPRegInfo ttbcr2_reginfo = {
516
@@ -XXX,XX +XXX,XX @@ static void omap_wfi_write(CPUARMState *env, const ARMCPRegInfo *ri,
517
static void omap_cachemaint_write(CPUARMState *env, const ARMCPRegInfo *ri,
518
uint64_t value)
519
{
520
- /* On OMAP there are registers indicating the max/min index of dcache lines
521
+ /*
522
+ * On OMAP there are registers indicating the max/min index of dcache lines
523
* containing a dirty line; cache flush operations have to reset these.
524
*/
525
env->cp15.c15_i_max = 0x000;
526
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo omap_cp_reginfo[] = {
527
.crm = 8, .opc1 = 0, .opc2 = 0, .access = PL1_RW,
528
.type = ARM_CP_NO_RAW,
529
.readfn = arm_cp_read_zero, .writefn = omap_wfi_write, },
530
- /* TODO: Peripheral port remap register:
531
+ /*
532
+ * TODO: Peripheral port remap register:
533
* On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt controller
534
* base address at $rn & ~0xfff and map size of 0x200 << ($rn & 0xfff),
535
* when MMU is off.
536
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
537
.cp = 15, .crn = 1, .crm = 0, .opc1 = 0, .opc2 = 1, .access = PL1_RW,
538
.fieldoffset = offsetof(CPUARMState, cp15.c1_xscaleauxcr),
539
.resetvalue = 0, },
540
- /* XScale specific cache-lockdown: since we have no cache we NOP these
541
+ /*
542
+ * XScale specific cache-lockdown: since we have no cache we NOP these
543
* and hope the guest does not really rely on cache behaviour.
544
*/
545
{ .name = "XSCALE_LOCK_ICACHE_LINE",
546
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo xscale_cp_reginfo[] = {
547
};
548
549
static const ARMCPRegInfo dummy_c15_cp_reginfo[] = {
550
- /* RAZ/WI the whole crn=15 space, when we don't have a more specific
551
+ /*
552
+ * RAZ/WI the whole crn=15 space, when we don't have a more specific
553
* implementation of this implementation-defined space.
554
* Ideally this should eventually disappear in favour of actually
555
* implementing the correct behaviour for all cores.
556
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
557
};
558
559
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
560
- /* The cache test-and-clean instructions always return (1 << 30)
561
+ /*
562
+ * The cache test-and-clean instructions always return (1 << 30)
563
* to indicate that there are no dirty cache lines.
564
*/
565
{ .name = "TC_DCACHE", .cp = 15, .crn = 7, .crm = 10, .opc1 = 0, .opc2 = 3,
566
@@ -XXX,XX +XXX,XX @@ static uint64_t mpidr_read_val(CPUARMState *env)
567
568
if (arm_feature(env, ARM_FEATURE_V7MP)) {
569
mpidr |= (1U << 31);
570
- /* Cores which are uniprocessor (non-coherent)
571
+ /*
572
+ * Cores which are uniprocessor (non-coherent)
573
* but still implement the MP extensions set
574
* bit 30. (For instance, Cortex-R5).
575
*/
576
@@ -XXX,XX +XXX,XX @@ static CPAccessResult access_tocu(CPUARMState *env, const ARMCPRegInfo *ri,
577
return do_cacheop_pou_access(env, HCR_TOCU | HCR_TPU);
578
}
579
580
-/* See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
581
+/*
582
+ * See: D4.7.2 TLB maintenance requirements and the TLB maintenance instructions
583
* Page D4-1736 (DDI0487A.b)
584
*/
585
586
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_alle3is_write(CPUARMState *env, const ARMCPRegInfo *ri,
587
static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
588
uint64_t value)
589
{
590
- /* Invalidate by VA, EL2
591
+ /*
592
+ * Invalidate by VA, EL2
593
* Currently handles both VAE2 and VALE2, since we don't support
594
* flush-last-level-only.
595
*/
596
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae2_write(CPUARMState *env, const ARMCPRegInfo *ri,
597
static void tlbi_aa64_vae3_write(CPUARMState *env, const ARMCPRegInfo *ri,
598
uint64_t value)
599
{
600
- /* Invalidate by VA, EL3
601
+ /*
602
+ * Invalidate by VA, EL3
603
* Currently handles both VAE3 and VALE3, since we don't support
604
* flush-last-level-only.
605
*/
606
@@ -XXX,XX +XXX,XX @@ static void tlbi_aa64_vae1is_write(CPUARMState *env, const ARMCPRegInfo *ri,
607
static void tlbi_aa64_vae1_write(CPUARMState *env, const ARMCPRegInfo *ri,
608
uint64_t value)
609
{
610
- /* Invalidate by VA, EL1&0 (AArch64 version).
611
+ /*
612
+ * Invalidate by VA, EL1&0 (AArch64 version).
613
* Currently handles all of VAE1, VAAE1, VAALE1 and VALE1,
614
* since we don't support flush-for-specific-ASID-only or
615
* flush-last-level-only.
616
@@ -XXX,XX +XXX,XX @@ static CPAccessResult sp_el0_access(CPUARMState *env, const ARMCPRegInfo *ri,
617
bool isread)
618
{
619
if (!(env->pstate & PSTATE_SP)) {
620
- /* Access to SP_EL0 is undefined if it's being used as
621
+ /*
622
+ * Access to SP_EL0 is undefined if it's being used as
623
* the stack pointer.
624
*/
625
return CP_ACCESS_TRAP_UNCATEGORIZED;
626
@@ -XXX,XX +XXX,XX @@ static void sctlr_write(CPUARMState *env, const ARMCPRegInfo *ri,
627
}
628
629
if (raw_read(env, ri) == value) {
630
- /* Skip the TLB flush if nothing actually changed; Linux likes
631
+ /*
632
+ * Skip the TLB flush if nothing actually changed; Linux likes
633
* to do a lot of pointless SCTLR writes.
634
*/
635
return;
636
@@ -XXX,XX +XXX,XX @@ static void mdcr_el2_write(CPUARMState *env, const ARMCPRegInfo *ri,
637
}
638
639
static const ARMCPRegInfo v8_cp_reginfo[] = {
640
- /* Minimal set of EL0-visible registers. This will need to be expanded
641
+ /*
642
+ * Minimal set of EL0-visible registers. This will need to be expanded
643
* significantly for system emulation of AArch64 CPUs.
644
*/
645
{ .name = "NZCV", .state = ARM_CP_STATE_AA64,
646
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v8_cp_reginfo[] = {
647
.opc0 = 3, .opc1 = 0, .crn = 4, .crm = 0, .opc2 = 0,
648
.access = PL1_RW,
649
.fieldoffset = offsetof(CPUARMState, banked_spsr[BANK_SVC]) },
650
- /* We rely on the access checks not allowing the guest to write to the
651
+ /*
652
+ * We rely on the access checks not allowing the guest to write to the
653
* state field when SPSel indicates that it's being used as the stack
654
* pointer.
655
*/
656
@@ -XXX,XX +XXX,XX @@ static void do_hcr_write(CPUARMState *env, uint64_t value, uint64_t valid_mask)
657
if (arm_feature(env, ARM_FEATURE_EL3)) {
658
valid_mask &= ~HCR_HCD;
659
} else if (cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
660
- /* Architecturally HCR.TSC is RES0 if EL3 is not implemented.
661
+ /*
662
+ * Architecturally HCR.TSC is RES0 if EL3 is not implemented.
663
* However, if we're using the SMC PSCI conduit then QEMU is
664
* effectively acting like EL3 firmware and so the guest at
665
* EL2 should retain the ability to prevent EL1 from being
666
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
667
.access = PL2_W, .type = ARM_CP_NO_RAW | ARM_CP_EL3_NO_EL2_UNDEF,
668
.writefn = tlbi_aa64_vae2is_write },
669
#ifndef CONFIG_USER_ONLY
670
- /* Unlike the other EL2-related AT operations, these must
671
+ /*
672
+ * Unlike the other EL2-related AT operations, these must
673
* UNDEF from EL3 if EL2 is not implemented, which is why we
674
* define them here rather than with the rest of the AT ops.
675
*/
676
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
677
.access = PL2_W, .accessfn = at_s1e2_access,
678
.type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC | ARM_CP_EL3_NO_EL2_UNDEF,
679
.writefn = ats_write64 },
680
- /* The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
681
+ /*
682
+ * The AArch32 ATS1H* operations are CONSTRAINED UNPREDICTABLE
683
* if EL2 is not implemented; we choose to UNDEF. Behaviour at EL3
684
* with SCR.NS == 0 outside Monitor mode is UNPREDICTABLE; we choose
685
* to behave as if SCR.NS was 1.
686
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_cp_reginfo[] = {
687
.writefn = ats1h_write, .type = ARM_CP_NO_RAW | ARM_CP_RAISES_EXC },
688
{ .name = "CNTHCTL_EL2", .state = ARM_CP_STATE_BOTH,
689
.opc0 = 3, .opc1 = 4, .crn = 14, .crm = 1, .opc2 = 0,
690
- /* ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the
691
+ /*
692
+ * ARMv7 requires bit 0 and 1 to reset to 1. ARMv8 defines the
693
* reset values as IMPDEF. We choose to reset to 3 to comply with
694
* both ARMv7 and ARMv8.
695
*/
696
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo el2_sec_cp_reginfo[] = {
697
static CPAccessResult nsacr_access(CPUARMState *env, const ARMCPRegInfo *ri,
698
bool isread)
699
{
700
- /* The NSACR is RW at EL3, and RO for NS EL1 and NS EL2.
701
+ /*
702
+ * The NSACR is RW at EL3, and RO for NS EL1 and NS EL2.
703
* At Secure EL1 it traps to EL3 or EL2.
704
*/
705
if (arm_current_el(env) == 3) {
706
@@ -XXX,XX +XXX,XX @@ static void define_pmu_regs(ARMCPU *cpu)
707
}
708
}
709
710
-/* We don't know until after realize whether there's a GICv3
711
+/*
712
+ * We don't know until after realize whether there's a GICv3
713
* attached, and that is what registers the gicv3 sysregs.
714
* So we have to fill in the GIC fields in ID_PFR/ID_PFR1_EL1/ID_AA64PFR0_EL1
715
* at runtime.
716
@@ -XXX,XX +XXX,XX @@ static uint64_t id_aa64pfr0_read(CPUARMState *env, const ARMCPRegInfo *ri)
717
}
718
#endif
719
720
-/* Shared logic between LORID and the rest of the LOR* registers.
721
+/*
722
+ * Shared logic between LORID and the rest of the LOR* registers.
723
* Secure state exclusion has already been dealt with.
724
*/
725
static CPAccessResult access_lor_ns(CPUARMState *env,
726
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
727
728
define_arm_cp_regs(cpu, cp_reginfo);
729
if (!arm_feature(env, ARM_FEATURE_V8)) {
730
- /* Must go early as it is full of wildcards that may be
731
+ /*
732
+ * Must go early as it is full of wildcards that may be
733
* overridden by later definitions.
734
*/
735
define_arm_cp_regs(cpu, not_v8_cp_reginfo);
736
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
737
.access = PL1_R, .type = ARM_CP_CONST,
738
.accessfn = access_aa32_tid3,
739
.resetvalue = cpu->isar.id_pfr0 },
740
- /* ID_PFR1 is not a plain ARM_CP_CONST because we don't know
741
+ /*
742
+ * ID_PFR1 is not a plain ARM_CP_CONST because we don't know
743
* the value of the GIC field until after we define these regs.
744
*/
745
{ .name = "ID_PFR1", .state = ARM_CP_STATE_BOTH,
746
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
747
748
define_arm_cp_regs(cpu, el3_regs);
749
}
750
- /* The behaviour of NSACR is sufficiently various that we don't
751
+ /*
752
+ * The behaviour of NSACR is sufficiently various that we don't
753
* try to describe it in a single reginfo:
754
* if EL3 is 64 bit, then trap to EL3 from S EL1,
755
* reads as constant 0xc00 from NS EL1 and NS EL2
756
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
757
if (cpu_isar_feature(aa32_jazelle, cpu)) {
758
define_arm_cp_regs(cpu, jazelle_regs);
759
}
760
- /* Slightly awkwardly, the OMAP and StrongARM cores need all of
761
+ /*
762
+ * Slightly awkwardly, the OMAP and StrongARM cores need all of
763
* cp15 crn=0 to be writes-ignored, whereas for other cores they should
764
* be read-only (ie write causes UNDEF exception).
765
*/
766
{
767
ARMCPRegInfo id_pre_v8_midr_cp_reginfo[] = {
768
- /* Pre-v8 MIDR space.
769
+ /*
770
+ * Pre-v8 MIDR space.
771
* Note that the MIDR isn't a simple constant register because
772
* of the TI925 behaviour where writes to another register can
773
* cause the MIDR value to change.
774
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
775
if (arm_feature(env, ARM_FEATURE_OMAPCP) ||
776
arm_feature(env, ARM_FEATURE_STRONGARM)) {
777
size_t i;
778
- /* Register the blanket "writes ignored" value first to cover the
779
+ /*
780
+ * Register the blanket "writes ignored" value first to cover the
781
* whole space. Then update the specific ID registers to allow write
782
* access, so that they ignore writes rather than causing them to
783
* UNDEF.
784
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
785
.raw_writefn = raw_write,
786
};
787
if (arm_feature(env, ARM_FEATURE_XSCALE)) {
788
- /* Normally we would always end the TB on an SCTLR write, but Linux
789
+ /*
790
+ * Normally we would always end the TB on an SCTLR write, but Linux
791
* arch/arm/mach-pxa/sleep.S expects two instructions following
792
* an MMU enable to execute from cache. Imitate this behaviour.
793
*/
794
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const ARMCPRegInfo *r,
795
void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
796
const ARMCPRegInfo *r, void *opaque)
797
{
798
- /* Define implementations of coprocessor registers.
799
+ /*
800
+ * Define implementations of coprocessor registers.
801
* We store these in a hashtable because typically
802
* there are less than 150 registers in a space which
803
* is 16*16*16*8*8 = 262144 in size.
804
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
805
default:
806
g_assert_not_reached();
807
}
808
- /* The AArch64 pseudocode CheckSystemAccess() specifies that op1
809
+ /*
810
+ * The AArch64 pseudocode CheckSystemAccess() specifies that op1
811
* encodes a minimum access level for the register. We roll this
812
* runtime check into our general permission check code, so check
813
* here that the reginfo's specified permissions are strict enough
814
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
815
assert((r->access & ~mask) == 0);
816
}
817
818
- /* Check that the register definition has enough info to handle
819
+ /*
820
+ * Check that the register definition has enough info to handle
821
* reads and writes if they are permitted.
822
*/
823
if (!(r->type & (ARM_CP_SPECIAL_MASK | ARM_CP_CONST))) {
824
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
825
continue;
826
}
827
if (state == ARM_CP_STATE_AA32) {
828
- /* Under AArch32 CP registers can be common
829
+ /*
830
+ * Under AArch32 CP registers can be common
831
* (same for secure and non-secure world) or banked.
832
*/
833
char *name;
834
@@ -XXX,XX +XXX,XX @@ void define_one_arm_cp_reg_with_opaque(ARMCPU *cpu,
835
g_assert_not_reached();
836
}
837
} else {
838
- /* AArch64 registers get mapped to non-secure instance
839
- * of AArch32 */
840
+ /*
841
+ * AArch64 registers get mapped to non-secure instance
842
+ * of AArch32
843
+ */
844
add_cpreg_to_hashtable(cpu, r, opaque, state,
845
ARM_CP_SECSTATE_NS,
846
crm, opc1, opc2, r->name);
847
@@ -XXX,XX +XXX,XX @@ void arm_cp_reset_ignore(CPUARMState *env, const ARMCPRegInfo *opaque)
848
849
static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
850
{
851
- /* Return true if it is not valid for us to switch to
852
+ /*
853
+ * Return true if it is not valid for us to switch to
854
* this CPU mode (ie all the UNPREDICTABLE cases in
855
* the ARM ARM CPSRWriteByInstr pseudocode).
856
*/
857
@@ -XXX,XX +XXX,XX @@ static int bad_mode_switch(CPUARMState *env, int mode, CPSRWriteType write_type)
858
case ARM_CPU_MODE_UND:
859
case ARM_CPU_MODE_IRQ:
860
case ARM_CPU_MODE_FIQ:
861
- /* Note that we don't implement the IMPDEF NSACR.RFR which in v7
862
+ /*
863
+ * Note that we don't implement the IMPDEF NSACR.RFR which in v7
864
* allows FIQ mode to be Secure-only. (In v8 this doesn't exist.)
865
*/
866
- /* If HCR.TGE is set then changes from Monitor to NS PL1 via MSR
867
+ /*
868
+ * If HCR.TGE is set then changes from Monitor to NS PL1 via MSR
869
* and CPS are treated as illegal mode changes.
870
*/
871
if (write_type == CPSRWriteByInstr &&
872
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
873
env->GE = (val >> 16) & 0xf;
874
}
875
876
- /* In a V7 implementation that includes the security extensions but does
877
+ /*
878
+ * In a V7 implementation that includes the security extensions but does
879
* not include Virtualization Extensions the SCR.FW and SCR.AW bits control
880
* whether non-secure software is allowed to change the CPSR_F and CPSR_A
881
* bits respectively.
882
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
883
changed_daif = (env->daif ^ val) & mask;
884
885
if (changed_daif & CPSR_A) {
886
- /* Check to see if we are allowed to change the masking of async
887
+ /*
888
+ * Check to see if we are allowed to change the masking of async
889
* abort exceptions from a non-secure state.
890
*/
891
if (!(env->cp15.scr_el3 & SCR_AW)) {
892
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
893
}
894
895
if (changed_daif & CPSR_F) {
896
- /* Check to see if we are allowed to change the masking of FIQ
897
+ /*
898
+ * Check to see if we are allowed to change the masking of FIQ
899
* exceptions from a non-secure state.
900
*/
901
if (!(env->cp15.scr_el3 & SCR_FW)) {
902
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
903
mask &= ~CPSR_F;
904
}
905
906
- /* Check whether non-maskable FIQ (NMFI) support is enabled.
907
+ /*
908
+ * Check whether non-maskable FIQ (NMFI) support is enabled.
909
* If this bit is set software is not allowed to mask
910
* FIQs, but is allowed to set CPSR_F to 0.
911
*/
912
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
913
if (write_type != CPSRWriteRaw &&
914
((env->uncached_cpsr ^ val) & mask & CPSR_M)) {
915
if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR) {
916
- /* Note that we can only get here in USR mode if this is a
917
+ /*
918
+ * Note that we can only get here in USR mode if this is a
919
* gdb stub write; for this case we follow the architectural
920
* behaviour for guest writes in USR mode of ignoring an attempt
921
* to switch mode. (Those are caught by translate.c for writes
922
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
923
*/
924
mask &= ~CPSR_M;
925
} else if (bad_mode_switch(env, val & CPSR_M, write_type)) {
926
- /* Attempt to switch to an invalid mode: this is UNPREDICTABLE in
927
+ /*
928
+ * Attempt to switch to an invalid mode: this is UNPREDICTABLE in
929
* v7, and has defined behaviour in v8:
930
* + leave CPSR.M untouched
931
* + allow changes to the other CPSR fields
932
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
933
env->regs[14] = env->banked_r14[r14_bank_number(mode)];
934
}
935
936
-/* Physical Interrupt Target EL Lookup Table
937
+/*
938
+ * Physical Interrupt Target EL Lookup Table
939
*
940
* [ From ARM ARM section G1.13.4 (Table G1-15) ]
941
*
942
@@ -XXX,XX +XXX,XX @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
943
if (arm_feature(env, ARM_FEATURE_EL3)) {
944
rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
945
} else {
946
- /* Either EL2 is the highest EL (and so the EL2 register width
947
+ /*
948
+ * Either EL2 is the highest EL (and so the EL2 register width
949
* is given by is64); or there is no EL2 or EL3, in which case
950
* the value of 'rw' does not affect the table lookup anyway.
951
*/
952
@@ -XXX,XX +XXX,XX @@ void aarch64_sync_64_to_32(CPUARMState *env)
953
env->banked_r13[bank_number(ARM_CPU_MODE_UND)] = env->xregs[23];
954
}
955
956
- /* Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
957
+ /*
958
+ * Registers x24-x30 are mapped to r8-r14 in FIQ mode. If we are in FIQ
959
* mode, then we can copy to r8-r14. Otherwise, we copy to the
960
* FIQ bank for r8-r14.
961
*/
962
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
963
/* High vectors. When enabled, base address cannot be remapped. */
964
addr += 0xffff0000;
965
} else {
966
- /* ARM v7 architectures provide a vector base address register to remap
967
+ /*
968
+ * ARM v7 architectures provide a vector base address register to remap
969
* the interrupt vector table.
970
* This register is only followed in non-monitor mode, and is banked.
971
* Note: only bits 31:5 are valid.
972
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch64(CPUState *cs)
973
aarch64_sve_change_el(env, cur_el, new_el, is_a64(env));
974
975
if (cur_el < new_el) {
976
- /* Entry vector offset depends on whether the implemented EL
977
+ /*
978
+ * Entry vector offset depends on whether the implemented EL
979
* immediately lower than the target level is using AArch32 or AArch64
980
*/
981
bool is_aa64;
982
@@ -XXX,XX +XXX,XX @@ static void handle_semihosting(CPUState *cs)
983
}
984
#endif
985
986
-/* Handle a CPU exception for A and R profile CPUs.
987
+/*
988
+ * Handle a CPU exception for A and R profile CPUs.
989
* Do any appropriate logging, handle PSCI calls, and then hand off
990
* to the AArch64-entry or AArch32-entry function depending on the
991
* target exception level's register width.
992
@@ -XXX,XX +XXX,XX @@ void arm_cpu_do_interrupt(CPUState *cs)
993
}
994
#endif
995
996
- /* Hooks may change global state so BQL should be held, also the
997
+ /*
998
+ * Hooks may change global state so BQL should be held, also the
999
* BQL needs to be held for any modification of
1000
* cs->interrupt_request.
1001
*/
63
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
1002
@@ -XXX,XX +XXX,XX @@ ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
64
};
1003
};
65
}
1004
}
66
1005
67
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
1006
-/* Note that signed overflow is undefined in C. The following routines are
68
+ ARMMMUIdx mmu_idx, bool data)
1007
- careful to use unsigned types where modulo arithmetic is required.
69
+{
1008
- Failure to do so _will_ break on newer gcc. */
70
+ return aa64_va_parameters_both(env, va, mmu_idx);
1009
+/*
71
+}
1010
+ * Note that signed overflow is undefined in C. The following routines are
72
+
1011
+ * careful to use unsigned types where modulo arithmetic is required.
73
static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
1012
+ * Failure to do so _will_ break on newer gcc.
74
ARMMMUIdx mmu_idx)
1013
+ */
75
{
1014
1015
/* Signed saturating arithmetic. */
1016
1017
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
1018
return (a & mask) | (b & ~mask);
1019
}
1020
1021
-/* CRC helpers.
1022
+/*
1023
+ * CRC helpers.
1024
* The upper bytes of val (above the number specified by 'bytes') must have
1025
* been zeroed out by the caller.
1026
*/
1027
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(crc32c)(uint32_t acc, uint32_t val, uint32_t bytes)
1028
return crc32c(acc, buf, bytes) ^ 0xffffffff;
1029
}
1030
1031
-/* Return the exception level to which FP-disabled exceptions should
1032
+/*
1033
+ * Return the exception level to which FP-disabled exceptions should
1034
* be taken, or 0 if FP is enabled.
1035
*/
1036
int fp_exception_el(CPUARMState *env, int cur_el)
1037
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
1038
#ifndef CONFIG_USER_ONLY
1039
uint64_t hcr_el2;
1040
1041
- /* CPACR and the CPTR registers don't exist before v6, so FP is
1042
+ /*
1043
+ * CPACR and the CPTR registers don't exist before v6, so FP is
1044
* always accessible
1045
*/
1046
if (!arm_feature(env, ARM_FEATURE_V6)) {
1047
@@ -XXX,XX +XXX,XX @@ int fp_exception_el(CPUARMState *env, int cur_el)
1048
1049
hcr_el2 = arm_hcr_el2_eff(env);
1050
1051
- /* The CPACR controls traps to EL1, or PL1 if we're 32 bit:
1052
+ /*
1053
+ * The CPACR controls traps to EL1, or PL1 if we're 32 bit:
1054
* 0, 2 : trap EL0 and EL1/PL1 accesses
1055
* 1 : trap only EL0 accesses
1056
* 3 : trap no accesses
76
--
1057
--
77
2.20.1
1058
2.25.1
78
79
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
The pattern
3
Fix the following:
4
4
5
ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
5
ERROR: spaces required around that '|' (ctx:VxV)
6
ERROR: space required before the open parenthesis '('
7
ERROR: spaces required around that '+' (ctx:VxB)
8
ERROR: space prohibited between function name and open parenthesis '('
6
9
7
is computing the full ARMMMUIdx, stripping off the ARM bits,
10
(the last two still have some occurrences in macros which I left
8
and then putting them back.
11
behind because it might impact readability)
9
12
10
Avoid the extra two steps with the appropriate helper function.
13
Signed-off-by: Fabiano Rosas <farosas@suse.de>
11
14
Reviewed-by: Claudio Fontana <cfontana@suse.de>
12
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
13
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
16
Message-id: 20221213190537.511-3-farosas@suse.de
14
Message-id: 20190108223129.5570-17-richard.henderson@linaro.org
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
18
---
17
target/arm/cpu.h | 9 ++++++++-
19
target/arm/helper.c | 42 +++++++++++++++++++++---------------------
18
target/arm/internals.h | 8 ++++++++
20
1 file changed, 21 insertions(+), 21 deletions(-)
19
target/arm/helper.c | 27 ++++++++++++++++-----------
20
3 files changed, 32 insertions(+), 12 deletions(-)
21
21
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate_and_priv(CPUARMState *env,
27
/* Return the MMU index for a v7M CPU in the specified security state */
28
ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate);
29
30
-/* Determine the current mmu_idx to use for normal loads/stores */
31
+/**
32
+ * cpu_mmu_index:
33
+ * @env: The cpu environment
34
+ * @ifetch: True for code access, false for data access.
35
+ *
36
+ * Return the core mmu index for the current translation regime.
37
+ * This function is used by generic TCG code paths.
38
+ */
39
int cpu_mmu_index(CPUARMState *env, bool ifetch);
40
41
/* Indexes used when registering address spaces with cpu_address_space_init */
42
diff --git a/target/arm/internals.h b/target/arm/internals.h
43
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/internals.h
45
+++ b/target/arm/internals.h
46
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_virq(ARMCPU *cpu);
47
*/
48
void arm_cpu_update_vfiq(ARMCPU *cpu);
49
50
+/**
51
+ * arm_mmu_idx:
52
+ * @env: The cpu environment
53
+ *
54
+ * Return the full ARMMMUIdx for the current translation regime.
55
+ */
56
+ARMMMUIdx arm_mmu_idx(CPUARMState *env);
57
+
58
#endif
59
diff --git a/target/arm/helper.c b/target/arm/helper.c
22
diff --git a/target/arm/helper.c b/target/arm/helper.c
60
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
61
--- a/target/arm/helper.c
24
--- a/target/arm/helper.c
62
+++ b/target/arm/helper.c
25
+++ b/target/arm/helper.c
63
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_callee_stack(ARMCPU *cpu, uint32_t lr, bool dotailchain,
26
@@ -XXX,XX +XXX,XX @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
64
limit = env->v7m.msplim[M_REG_S];
27
uint32_t regidx = (uintptr_t)key;
65
}
28
const ARMCPRegInfo *ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);
66
} else {
29
67
- mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
30
- if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
68
+ mmu_idx = arm_mmu_idx(env);
31
+ if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
69
frame_sp_p = &env->regs[13];
32
cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);
70
limit = v7m_sp_limit(env);
33
/* The value array need not be initialized at this point */
34
cpu->cpreg_array_len++;
35
@@ -XXX,XX +XXX,XX @@ static void count_cpreg(gpointer key, gpointer opaque)
36
37
ri = g_hash_table_lookup(cpu->cp_regs, key);
38
39
- if (!(ri->type & (ARM_CP_NO_RAW|ARM_CP_ALIAS))) {
40
+ if (!(ri->type & (ARM_CP_NO_RAW | ARM_CP_ALIAS))) {
41
cpu->cpreg_array_len++;
71
}
42
}
72
@@ -XXX,XX +XXX,XX @@ static bool v7m_push_stack(ARMCPU *cpu)
73
CPUARMState *env = &cpu->env;
74
uint32_t xpsr = xpsr_read(env);
75
uint32_t frameptr = env->regs[13];
76
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
77
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
78
79
/* Align stack pointer if the guest wants that */
80
if ((frameptr & 4) &&
81
@@ -XXX,XX +XXX,XX @@ hwaddr arm_cpu_get_phys_page_attrs_debug(CPUState *cs, vaddr addr,
82
int prot;
83
bool ret;
84
ARMMMUFaultInfo fi = {};
85
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
86
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
87
88
*attrs = (MemTxAttrs) {};
89
90
@@ -XXX,XX +XXX,XX @@ ARMMMUIdx arm_v7m_mmu_idx_for_secstate(CPUARMState *env, bool secstate)
91
return arm_v7m_mmu_idx_for_secstate_and_priv(env, secstate, priv);
92
}
43
}
93
44
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v6k_cp_reginfo[] = {
94
-int cpu_mmu_index(CPUARMState *env, bool ifetch)
45
.resetfn = arm_cp_reset_ignore },
95
+ARMMMUIdx arm_mmu_idx(CPUARMState *env)
46
{ .name = "TPIDRRO_EL0", .state = ARM_CP_STATE_AA64,
96
{
47
.opc0 = 3, .opc1 = 3, .opc2 = 3, .crn = 13, .crm = 0,
97
- int el = arm_current_el(env);
48
- .access = PL0_R|PL1_W,
98
+ int el;
49
+ .access = PL0_R | PL1_W,
99
50
.fieldoffset = offsetof(CPUARMState, cp15.tpidrro_el[0]),
100
if (arm_feature(env, ARM_FEATURE_M)) {
51
.resetvalue = 0},
101
- ARMMMUIdx mmu_idx = arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
52
{ .name = "TPIDRURO", .cp = 15, .crn = 13, .crm = 0, .opc1 = 0, .opc2 = 3,
102
-
53
- .access = PL0_R|PL1_W,
103
- return arm_to_core_mmu_idx(mmu_idx);
54
+ .access = PL0_R | PL1_W,
104
+ return arm_v7m_mmu_idx_for_secstate(env, env->v7m.secure);
55
.bank_fieldoffsets = { offsetoflow32(CPUARMState, cp15.tpidruro_s),
56
offsetoflow32(CPUARMState, cp15.tpidruro_ns) },
57
.resetfn = arm_cp_reset_ignore },
58
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo cache_block_ops_cp_reginfo[] = {
59
.resetvalue = 0 },
60
/* The cache ops themselves: these all NOP for QEMU */
61
{ .name = "IICR", .cp = 15, .crm = 5, .opc1 = 0,
62
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
63
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
64
{ .name = "IDCR", .cp = 15, .crm = 6, .opc1 = 0,
65
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
66
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
67
{ .name = "CDCR", .cp = 15, .crm = 12, .opc1 = 0,
68
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
69
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
70
{ .name = "PIR", .cp = 15, .crm = 12, .opc1 = 1,
71
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
72
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
73
{ .name = "PDR", .cp = 15, .crm = 12, .opc1 = 2,
74
- .access = PL0_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
75
+ .access = PL0_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
76
{ .name = "CIDCR", .cp = 15, .crm = 14, .opc1 = 0,
77
- .access = PL1_W, .type = ARM_CP_NOP|ARM_CP_64BIT },
78
+ .access = PL1_W, .type = ARM_CP_NOP | ARM_CP_64BIT },
79
};
80
81
static const ARMCPRegInfo cache_test_clean_cp_reginfo[] = {
82
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
83
ARMCPRegInfo cbar = {
84
.name = "CBAR",
85
.cp = 15, .crn = 15, .crm = 0, .opc1 = 4, .opc2 = 0,
86
- .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
87
+ .access = PL1_R | PL3_W, .resetvalue = cpu->reset_cbar,
88
.fieldoffset = offsetof(CPUARMState,
89
cp15.c15_config_base_address)
90
};
91
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
92
return;
93
94
if (old_mode == ARM_CPU_MODE_FIQ) {
95
- memcpy (env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
96
- memcpy (env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
97
+ memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
98
+ memcpy(env->regs + 8, env->usr_regs, 5 * sizeof(uint32_t));
99
} else if (mode == ARM_CPU_MODE_FIQ) {
100
- memcpy (env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
101
- memcpy (env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
102
+ memcpy(env->usr_regs, env->regs + 8, 5 * sizeof(uint32_t));
103
+ memcpy(env->regs + 8, env->fiq_regs, 5 * sizeof(uint32_t));
105
}
104
}
106
105
107
+ el = arm_current_el(env);
106
i = bank_number(old_mode);
108
if (el < 2 && arm_is_secure_below_el3(env)) {
107
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
109
- return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0 + el);
108
RESULT(sum, n, 16); \
110
+ return ARMMMUIdx_S1SE0 + el;
109
if (sum >= 0) \
111
+ } else {
110
ge |= 3 << (n * 2); \
112
+ return ARMMMUIdx_S12NSE0 + el;
111
- } while(0)
113
}
112
+ } while (0)
114
- return el;
113
115
+}
114
#define SARITH8(a, b, n, op) do { \
116
+
115
int32_t sum; \
117
+int cpu_mmu_index(CPUARMState *env, bool ifetch)
116
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
118
+{
117
RESULT(sum, n, 8); \
119
+ return arm_to_core_mmu_idx(arm_mmu_idx(env));
118
if (sum >= 0) \
120
}
119
ge |= 1 << n; \
121
120
- } while(0)
122
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
121
+ } while (0)
123
target_ulong *cs_base, uint32_t *pflags)
122
124
{
123
125
- ARMMMUIdx mmu_idx = core_to_arm_mmu_idx(env, cpu_mmu_index(env, false));
124
#define ADD16(a, b, n) SARITH16(a, b, n, +)
126
+ ARMMMUIdx mmu_idx = arm_mmu_idx(env);
125
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
127
int current_el = arm_current_el(env);
126
RESULT(sum, n, 16); \
128
int fp_el = fp_exception_el(env, current_el);
127
if ((sum >> 16) == 1) \
129
uint32_t flags = 0;
128
ge |= 3 << (n * 2); \
129
- } while(0)
130
+ } while (0)
131
132
#define ADD8(a, b, n) do { \
133
uint32_t sum; \
134
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
135
RESULT(sum, n, 8); \
136
if ((sum >> 8) == 1) \
137
ge |= 1 << n; \
138
- } while(0)
139
+ } while (0)
140
141
#define SUB16(a, b, n) do { \
142
uint32_t sum; \
143
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
144
RESULT(sum, n, 16); \
145
if ((sum >> 16) == 0) \
146
ge |= 3 << (n * 2); \
147
- } while(0)
148
+ } while (0)
149
150
#define SUB8(a, b, n) do { \
151
uint32_t sum; \
152
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
153
RESULT(sum, n, 8); \
154
if ((sum >> 8) == 0) \
155
ge |= 1 << n; \
156
- } while(0)
157
+ } while (0)
158
159
#define PFX u
160
#define ARITH_GE
130
--
161
--
131
2.20.1
162
2.25.1
132
133
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
pmccntr_read and pmccntr_write contained duplicate code that was already
3
Fix this:
4
being handled by pmccntr_sync. Consolidate the duplicated code into two
4
ERROR: braces {} are necessary for all arms of this statement
5
functions: pmccntr_op_start and pmccntr_op_finish. Add a companion to
6
c15_ccnt in CPUARMState so that we can simultaneously save both the
7
architectural register value and the last underlying cycle count - this
8
ensures time isn't lost and will also allow us to access the 'old'
9
architectural register value in order to detect overflows in later
10
patches.
11
5
12
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
6
Signed-off-by: Fabiano Rosas <farosas@suse.de>
13
Signed-off-by: Aaron Lindsay <aclindsa@gmail.com>
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
14
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
15
Message-id: 20181211151945.29137-3-aaron@os.amperecomputing.com
9
Message-id: 20221213190537.511-4-farosas@suse.de
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
17
---
11
---
18
target/arm/cpu.h | 37 +++++++++++---
12
target/arm/helper.c | 67 ++++++++++++++++++++++++++++-----------------
19
target/arm/helper.c | 118 ++++++++++++++++++++++++++------------------
13
1 file changed, 42 insertions(+), 25 deletions(-)
20
2 files changed, 100 insertions(+), 55 deletions(-)
21
14
22
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
23
index XXXXXXX..XXXXXXX 100644
24
--- a/target/arm/cpu.h
25
+++ b/target/arm/cpu.h
26
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
27
uint64_t oslsr_el1; /* OS Lock Status */
28
uint64_t mdcr_el2;
29
uint64_t mdcr_el3;
30
- /* If the counter is enabled, this stores the last time the counter
31
- * was reset. Otherwise it stores the counter value
32
+ /* Stores the architectural value of the counter *the last time it was
33
+ * updated* by pmccntr_op_start. Accesses should always be surrounded
34
+ * by pmccntr_op_start/pmccntr_op_finish to guarantee the latest
35
+ * architecturally-correct value is being read/set.
36
*/
37
uint64_t c15_ccnt;
38
+ /* Stores the delta between the architectural value and the underlying
39
+ * cycle count during normal operation. It is used to update c15_ccnt
40
+ * to be the correct architectural value before accesses. During
41
+ * accesses, c15_ccnt_delta contains the underlying count being used
42
+ * for the access, after which it reverts to the delta value in
43
+ * pmccntr_op_finish.
44
+ */
45
+ uint64_t c15_ccnt_delta;
46
uint64_t pmccfiltr_el0; /* Performance Monitor Filter Register */
47
uint64_t vpidr_el2; /* Virtualization Processor ID Register */
48
uint64_t vmpidr_el2; /* Virtualization Multiprocessor ID Register */
49
@@ -XXX,XX +XXX,XX @@ int cpu_arm_signal_handler(int host_signum, void *pinfo,
50
void *puc);
51
52
/**
53
- * pmccntr_sync
54
+ * pmccntr_op_start/finish
55
* @env: CPUARMState
56
*
57
- * Synchronises the counter in the PMCCNTR. This must always be called twice,
58
- * once before any action that might affect the timer and again afterwards.
59
- * The function is used to swap the state of the register if required.
60
- * This only happens when not in user mode (!CONFIG_USER_ONLY)
61
+ * Convert the counter in the PMCCNTR between its delta form (the typical mode
62
+ * when it's enabled) and the guest-visible value. These two calls must always
63
+ * surround any action which might affect the counter.
64
*/
65
-void pmccntr_sync(CPUARMState *env);
66
+void pmccntr_op_start(CPUARMState *env);
67
+void pmccntr_op_finish(CPUARMState *env);
68
+
69
+/**
70
+ * pmu_op_start/finish
71
+ * @env: CPUARMState
72
+ *
73
+ * Convert all PMU counters between their delta form (the typical mode when
74
+ * they are enabled) and the guest-visible values. These two calls must
75
+ * surround any action which might affect the counters.
76
+ */
77
+void pmu_op_start(CPUARMState *env);
78
+void pmu_op_finish(CPUARMState *env);
79
80
/* SCTLR bit meanings. Several bits have been reused in newer
81
* versions of the architecture; in that case we define constants
82
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/target/arm/helper.c b/target/arm/helper.c
83
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
84
--- a/target/arm/helper.c
17
--- a/target/arm/helper.c
85
+++ b/target/arm/helper.c
18
+++ b/target/arm/helper.c
86
@@ -XXX,XX +XXX,XX @@ static inline bool arm_ccnt_enabled(CPUARMState *env)
19
@@ -XXX,XX +XXX,XX @@ void cpsr_write(CPUARMState *env, uint32_t val, uint32_t mask,
87
20
env->CF = (val >> 29) & 1;
88
return true;
21
env->VF = (val << 3) & 0x80000000;
22
}
23
- if (mask & CPSR_Q)
24
+ if (mask & CPSR_Q) {
25
env->QF = ((val & CPSR_Q) != 0);
26
- if (mask & CPSR_T)
27
+ }
28
+ if (mask & CPSR_T) {
29
env->thumb = ((val & CPSR_T) != 0);
30
+ }
31
if (mask & CPSR_IT_0_1) {
32
env->condexec_bits &= ~3;
33
env->condexec_bits |= (val >> 25) & 3;
34
@@ -XXX,XX +XXX,XX @@ static void switch_mode(CPUARMState *env, int mode)
35
int i;
36
37
old_mode = env->uncached_cpsr & CPSR_M;
38
- if (mode == old_mode)
39
+ if (mode == old_mode) {
40
return;
41
+ }
42
43
if (old_mode == ARM_CPU_MODE_FIQ) {
44
memcpy(env->fiq_regs, env->regs + 8, 5 * sizeof(uint32_t));
45
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_do_interrupt_aarch32(CPUState *cs)
46
new_mode = ARM_CPU_MODE_UND;
47
addr = 0x04;
48
mask = CPSR_I;
49
- if (env->thumb)
50
+ if (env->thumb) {
51
offset = 2;
52
- else
53
+ } else {
54
offset = 4;
55
+ }
56
break;
57
case EXCP_SWI:
58
new_mode = ARM_CPU_MODE_SVC;
59
@@ -XXX,XX +XXX,XX @@ static inline uint16_t add16_sat(uint16_t a, uint16_t b)
60
61
res = a + b;
62
if (((res ^ a) & 0x8000) && !((a ^ b) & 0x8000)) {
63
- if (a & 0x8000)
64
+ if (a & 0x8000) {
65
res = 0x8000;
66
- else
67
+ } else {
68
res = 0x7fff;
69
+ }
70
}
71
return res;
89
}
72
}
90
-
73
@@ -XXX,XX +XXX,XX @@ static inline uint8_t add8_sat(uint8_t a, uint8_t b)
91
-void pmccntr_sync(CPUARMState *env)
74
92
+/*
75
res = a + b;
93
+ * Ensure c15_ccnt is the guest-visible count so that operations such as
76
if (((res ^ a) & 0x80) && !((a ^ b) & 0x80)) {
94
+ * enabling/disabling the counter or filtering, modifying the count itself,
77
- if (a & 0x80)
95
+ * etc. can be done logically. This is essentially a no-op if the counter is
78
+ if (a & 0x80) {
96
+ * not enabled at the time of the call.
79
res = 0x80;
97
+ */
80
- else
98
+void pmccntr_op_start(CPUARMState *env)
81
+ } else {
82
res = 0x7f;
83
+ }
84
}
85
return res;
86
}
87
@@ -XXX,XX +XXX,XX @@ static inline uint16_t sub16_sat(uint16_t a, uint16_t b)
88
89
res = a - b;
90
if (((res ^ a) & 0x8000) && ((a ^ b) & 0x8000)) {
91
- if (a & 0x8000)
92
+ if (a & 0x8000) {
93
res = 0x8000;
94
- else
95
+ } else {
96
res = 0x7fff;
97
+ }
98
}
99
return res;
100
}
101
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_sat(uint8_t a, uint8_t b)
102
103
res = a - b;
104
if (((res ^ a) & 0x80) && ((a ^ b) & 0x80)) {
105
- if (a & 0x80)
106
+ if (a & 0x80) {
107
res = 0x80;
108
- else
109
+ } else {
110
res = 0x7f;
111
+ }
112
}
113
return res;
114
}
115
@@ -XXX,XX +XXX,XX @@ static inline uint16_t add16_usat(uint16_t a, uint16_t b)
99
{
116
{
100
- uint64_t temp_ticks;
117
uint16_t res;
101
-
118
res = a + b;
102
- temp_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
119
- if (res < a)
103
+ uint64_t cycles = 0;
120
+ if (res < a) {
104
+ cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
121
res = 0xffff;
105
ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
106
107
- if (env->cp15.c9_pmcr & PMCRD) {
108
- /* Increment once every 64 processor clock cycles */
109
- temp_ticks /= 64;
110
- }
111
-
112
if (arm_ccnt_enabled(env)) {
113
- env->cp15.c15_ccnt = temp_ticks - env->cp15.c15_ccnt;
114
+ uint64_t eff_cycles = cycles;
115
+ if (env->cp15.c9_pmcr & PMCRD) {
116
+ /* Increment once every 64 processor clock cycles */
117
+ eff_cycles /= 64;
118
+ }
119
+
120
+ env->cp15.c15_ccnt = eff_cycles - env->cp15.c15_ccnt_delta;
121
}
122
+ env->cp15.c15_ccnt_delta = cycles;
123
+}
124
+
125
+/*
126
+ * If PMCCNTR is enabled, recalculate the delta between the clock and the
127
+ * guest-visible count. A call to pmccntr_op_finish should follow every call to
128
+ * pmccntr_op_start.
129
+ */
130
+void pmccntr_op_finish(CPUARMState *env)
131
+{
132
+ if (arm_ccnt_enabled(env)) {
133
+ uint64_t prev_cycles = env->cp15.c15_ccnt_delta;
134
+
135
+ if (env->cp15.c9_pmcr & PMCRD) {
136
+ /* Increment once every 64 processor clock cycles */
137
+ prev_cycles /= 64;
138
+ }
139
+
140
+ env->cp15.c15_ccnt_delta = prev_cycles - env->cp15.c15_ccnt;
141
+ }
122
+ }
142
+}
123
return res;
143
+
144
+void pmu_op_start(CPUARMState *env)
145
+{
146
+ pmccntr_op_start(env);
147
+}
148
+
149
+void pmu_op_finish(CPUARMState *env)
150
+{
151
+ pmccntr_op_finish(env);
152
}
124
}
153
125
154
static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
126
static inline uint16_t sub16_usat(uint16_t a, uint16_t b)
155
uint64_t value)
156
{
127
{
157
- pmccntr_sync(env);
128
- if (a > b)
158
+ pmu_op_start(env);
129
+ if (a > b) {
159
130
return a - b;
160
if (value & PMCRC) {
131
- else
161
/* The counter has been reset */
132
+ } else {
162
@@ -XXX,XX +XXX,XX @@ static void pmcr_write(CPUARMState *env, const ARMCPRegInfo *ri,
133
return 0;
163
env->cp15.c9_pmcr &= ~0x39;
134
+ }
164
env->cp15.c9_pmcr |= (value & 0x39);
165
166
- pmccntr_sync(env);
167
+ pmu_op_finish(env);
168
}
135
}
169
136
170
static uint64_t pmccntr_read(CPUARMState *env, const ARMCPRegInfo *ri)
137
static inline uint8_t add8_usat(uint8_t a, uint8_t b)
171
{
138
{
172
- uint64_t total_ticks;
139
uint8_t res;
173
-
140
res = a + b;
174
- if (!arm_ccnt_enabled(env)) {
141
- if (res < a)
175
- /* Counter is disabled, do not change value */
142
+ if (res < a) {
176
- return env->cp15.c15_ccnt;
143
res = 0xff;
177
- }
144
+ }
178
-
145
return res;
179
- total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
180
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
181
-
182
- if (env->cp15.c9_pmcr & PMCRD) {
183
- /* Increment once every 64 processor clock cycles */
184
- total_ticks /= 64;
185
- }
186
- return total_ticks - env->cp15.c15_ccnt;
187
+ uint64_t ret;
188
+ pmccntr_op_start(env);
189
+ ret = env->cp15.c15_ccnt;
190
+ pmccntr_op_finish(env);
191
+ return ret;
192
}
146
}
193
147
194
static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
148
static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
195
@@ -XXX,XX +XXX,XX @@ static void pmselr_write(CPUARMState *env, const ARMCPRegInfo *ri,
196
static void pmccntr_write(CPUARMState *env, const ARMCPRegInfo *ri,
197
uint64_t value)
198
{
149
{
199
- uint64_t total_ticks;
150
- if (a > b)
200
-
151
+ if (a > b) {
201
- if (!arm_ccnt_enabled(env)) {
152
return a - b;
202
- /* Counter is disabled, set the absolute value */
153
- else
203
- env->cp15.c15_ccnt = value;
154
+ } else {
204
- return;
155
return 0;
205
- }
156
+ }
206
-
207
- total_ticks = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
208
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
209
-
210
- if (env->cp15.c9_pmcr & PMCRD) {
211
- /* Increment once every 64 processor clock cycles */
212
- total_ticks /= 64;
213
- }
214
- env->cp15.c15_ccnt = total_ticks - value;
215
+ pmccntr_op_start(env);
216
+ env->cp15.c15_ccnt = value;
217
+ pmccntr_op_finish(env);
218
}
157
}
219
158
220
static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
159
#define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
221
@@ -XXX,XX +XXX,XX @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
160
@@ -XXX,XX +XXX,XX @@ static inline uint8_t sub8_usat(uint8_t a, uint8_t b)
222
161
223
#else /* CONFIG_USER_ONLY */
162
static inline uint8_t do_usad(uint8_t a, uint8_t b)
224
225
-void pmccntr_sync(CPUARMState *env)
226
+void pmccntr_op_start(CPUARMState *env)
227
+{
228
+}
229
+
230
+void pmccntr_op_finish(CPUARMState *env)
231
+{
232
+}
233
+
234
+void pmu_op_start(CPUARMState *env)
235
+{
236
+}
237
+
238
+void pmu_op_finish(CPUARMState *env)
239
{
163
{
164
- if (a > b)
165
+ if (a > b) {
166
return a - b;
167
- else
168
+ } else {
169
return b - a;
170
+ }
240
}
171
}
241
172
242
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env)
173
/* Unsigned sum of absolute byte differences. */
243
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
174
@@ -XXX,XX +XXX,XX @@ uint32_t HELPER(sel_flags)(uint32_t flags, uint32_t a, uint32_t b)
244
uint64_t value)
175
uint32_t mask;
245
{
176
246
- pmccntr_sync(env);
177
mask = 0;
247
+ pmccntr_op_start(env);
178
- if (flags & 1)
248
env->cp15.pmccfiltr_el0 = value & 0xfc000000;
179
+ if (flags & 1) {
249
- pmccntr_sync(env);
180
mask |= 0xff;
250
+ pmccntr_op_finish(env);
181
- if (flags & 2)
182
+ }
183
+ if (flags & 2) {
184
mask |= 0xff00;
185
- if (flags & 4)
186
+ }
187
+ if (flags & 4) {
188
mask |= 0xff0000;
189
- if (flags & 8)
190
+ }
191
+ if (flags & 8) {
192
mask |= 0xff000000;
193
+ }
194
return (a & mask) | (b & ~mask);
251
}
195
}
252
196
253
static void pmcntenset_write(CPUARMState *env, const ARMCPRegInfo *ri,
254
--
197
--
255
2.20.1
198
2.25.1
256
257
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
This is immediately necessary for the PMUv3 implementation to check
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
ID_DFR0.PerfMon to enable/disable specific features, but defines the
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
full complement of fields for possible future use elsewhere.
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
6
Message-id: 20221213190537.511-5-farosas@suse.de
7
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20181211151945.29137-8-aaron@os.amperecomputing.com
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
8
---
12
target/arm/cpu.h | 9 +++++++++
9
target/arm/m_helper.c | 16 ----------------
13
1 file changed, 9 insertions(+)
10
1 file changed, 16 deletions(-)
14
11
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
12
diff --git a/target/arm/m_helper.c b/target/arm/m_helper.c
16
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
14
--- a/target/arm/m_helper.c
18
+++ b/target/arm/cpu.h
15
+++ b/target/arm/m_helper.c
19
@@ -XXX,XX +XXX,XX @@ FIELD(ID_AA64MMFR1, PAN, 20, 4)
16
@@ -XXX,XX +XXX,XX @@
20
FIELD(ID_AA64MMFR1, SPECSEI, 24, 4)
17
*/
21
FIELD(ID_AA64MMFR1, XNX, 28, 4)
18
22
19
#include "qemu/osdep.h"
23
+FIELD(ID_DFR0, COPDBG, 0, 4)
20
-#include "qemu/units.h"
24
+FIELD(ID_DFR0, COPSDBG, 4, 4)
21
-#include "target/arm/idau.h"
25
+FIELD(ID_DFR0, MMAPDBG, 8, 4)
22
-#include "trace.h"
26
+FIELD(ID_DFR0, COPTRC, 12, 4)
23
#include "cpu.h"
27
+FIELD(ID_DFR0, MMAPTRC, 16, 4)
24
#include "internals.h"
28
+FIELD(ID_DFR0, MPROFDBG, 20, 4)
25
-#include "exec/gdbstub.h"
29
+FIELD(ID_DFR0, PERFMON, 24, 4)
26
#include "exec/helper-proto.h"
30
+FIELD(ID_DFR0, TRACEFILT, 28, 4)
27
-#include "qemu/host-utils.h"
31
+
28
#include "qemu/main-loop.h"
32
QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK);
29
#include "qemu/bitops.h"
33
30
-#include "qemu/crc32c.h"
34
/* If adding a feature bit which corresponds to a Linux ELF
31
-#include "qemu/qemu-print.h"
32
#include "qemu/log.h"
33
#include "exec/exec-all.h"
34
-#include <zlib.h> /* For crc32 */
35
-#include "semihosting/semihost.h"
36
-#include "sysemu/cpus.h"
37
-#include "sysemu/kvm.h"
38
-#include "qemu/range.h"
39
-#include "qapi/qapi-commands-machine-target.h"
40
-#include "qapi/error.h"
41
-#include "qemu/guest-random.h"
42
#ifdef CONFIG_TCG
43
-#include "arm_ldst.h"
44
#include "exec/cpu_ldst.h"
45
#include "semihosting/common-semi.h"
46
#endif
35
--
47
--
36
2.20.1
48
2.25.1
37
38
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Fabiano Rosas <farosas@suse.de>
2
2
3
The instruction event is only enabled when icount is used, cycles are
3
Signed-off-by: Fabiano Rosas <farosas@suse.de>
4
always supported. Always defining get_cycle_count (but altering its
4
Reviewed-by: Claudio Fontana <cfontana@suse.de>
5
behavior depending on CONFIG_USER_ONLY) allows us to remove some
5
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
6
CONFIG_USER_ONLY #defines throughout the rest of the code.
6
Message-id: 20221213190537.511-6-farosas@suse.de
7
8
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
9
Signed-off-by: Aaron Lindsay <aaron@os.amperecomputing.com>
10
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Message-id: 20181211151945.29137-12-aaron@os.amperecomputing.com
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
---
8
---
14
target/arm/helper.c | 90 ++++++++++++++++++++++-----------------------
9
target/arm/helper.c | 7 -------
15
1 file changed, 44 insertions(+), 46 deletions(-)
10
1 file changed, 7 deletions(-)
16
11
17
diff --git a/target/arm/helper.c b/target/arm/helper.c
12
diff --git a/target/arm/helper.c b/target/arm/helper.c
18
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/helper.c
14
--- a/target/arm/helper.c
20
+++ b/target/arm/helper.c
15
+++ b/target/arm/helper.c
21
@@ -XXX,XX +XXX,XX @@
16
@@ -XXX,XX +XXX,XX @@
22
#include "arm_ldst.h"
17
*/
18
19
#include "qemu/osdep.h"
20
-#include "qemu/units.h"
21
#include "qemu/log.h"
22
#include "trace.h"
23
#include "cpu.h"
24
#include "internals.h"
25
#include "exec/helper-proto.h"
26
-#include "qemu/host-utils.h"
27
#include "qemu/main-loop.h"
28
#include "qemu/timer.h"
29
#include "qemu/bitops.h"
30
@@ -XXX,XX +XXX,XX @@
31
#include "exec/exec-all.h"
23
#include <zlib.h> /* For crc32 */
32
#include <zlib.h> /* For crc32 */
24
#include "exec/semihost.h"
33
#include "hw/irq.h"
25
+#include "sysemu/cpus.h"
34
-#include "semihosting/semihost.h"
35
-#include "sysemu/cpus.h"
36
#include "sysemu/cpu-timers.h"
26
#include "sysemu/kvm.h"
37
#include "sysemu/kvm.h"
27
#include "fpu/softfloat.h"
38
-#include "qemu/range.h"
28
#include "qemu/range.h"
39
#include "qapi/qapi-commands-machine-target.h"
29
@@ -XXX,XX +XXX,XX @@ typedef struct pm_event {
40
#include "qapi/error.h"
30
uint64_t (*get_count)(CPUARMState *);
41
#include "qemu/guest-random.h"
31
} pm_event;
42
#ifdef CONFIG_TCG
32
43
-#include "arm_ldst.h"
33
+static bool event_always_supported(CPUARMState *env)
44
-#include "exec/cpu_ldst.h"
34
+{
45
#include "semihosting/common-semi.h"
35
+ return true;
46
#endif
36
+}
47
#include "cpregs.h"
37
+
38
+/*
39
+ * Return the underlying cycle count for the PMU cycle counters. If we're in
40
+ * usermode, simply return 0.
41
+ */
42
+static uint64_t cycles_get_count(CPUARMState *env)
43
+{
44
+#ifndef CONFIG_USER_ONLY
45
+ return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
46
+ ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
47
+#else
48
+ return cpu_get_host_ticks();
49
+#endif
50
+}
51
+
52
+#ifndef CONFIG_USER_ONLY
53
+static bool instructions_supported(CPUARMState *env)
54
+{
55
+ return use_icount == 1 /* Precise instruction counting */;
56
+}
57
+
58
+static uint64_t instructions_get_count(CPUARMState *env)
59
+{
60
+ return (uint64_t)cpu_get_icount_raw();
61
+}
62
+#endif
63
+
64
static const pm_event pm_events[] = {
65
+#ifndef CONFIG_USER_ONLY
66
+ { .number = 0x008, /* INST_RETIRED, Instruction architecturally executed */
67
+ .supported = instructions_supported,
68
+ .get_count = instructions_get_count,
69
+ },
70
+ { .number = 0x011, /* CPU_CYCLES, Cycle */
71
+ .supported = event_always_supported,
72
+ .get_count = cycles_get_count,
73
+ }
74
+#endif
75
};
76
77
/*
78
@@ -XXX,XX +XXX,XX @@ static const pm_event pm_events[] = {
79
* should first be updated to something sparse instead of the current
80
* supported_event_map[] array.
81
*/
82
-#define MAX_EVENT_ID 0x0
83
+#define MAX_EVENT_ID 0x11
84
#define UNSUPPORTED_EVENT UINT16_MAX
85
static uint16_t supported_event_map[MAX_EVENT_ID + 1];
86
87
@@ -XXX,XX +XXX,XX @@ static CPAccessResult pmreg_access_swinc(CPUARMState *env,
88
return pmreg_access(env, ri, isread);
89
}
90
91
-#ifndef CONFIG_USER_ONLY
92
-
93
static CPAccessResult pmreg_access_selr(CPUARMState *env,
94
const ARMCPRegInfo *ri,
95
bool isread)
96
@@ -XXX,XX +XXX,XX @@ static bool pmu_counter_enabled(CPUARMState *env, uint8_t counter)
97
*/
98
void pmccntr_op_start(CPUARMState *env)
99
{
100
- uint64_t cycles = 0;
101
- cycles = muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL),
102
- ARM_CPU_FREQ, NANOSECONDS_PER_SECOND);
103
+ uint64_t cycles = cycles_get_count(env);
104
105
if (pmu_counter_enabled(env, 31)) {
106
uint64_t eff_cycles = cycles;
107
@@ -XXX,XX +XXX,XX @@ static void pmccntr_write32(CPUARMState *env, const ARMCPRegInfo *ri,
108
pmccntr_write(env, ri, deposit64(cur_val, 0, 32, value));
109
}
110
111
-#else /* CONFIG_USER_ONLY */
112
-
113
-void pmccntr_op_start(CPUARMState *env)
114
-{
115
-}
116
-
117
-void pmccntr_op_finish(CPUARMState *env)
118
-{
119
-}
120
-
121
-void pmevcntr_op_start(CPUARMState *env, uint8_t i)
122
-{
123
-}
124
-
125
-void pmevcntr_op_finish(CPUARMState *env, uint8_t i)
126
-{
127
-}
128
-
129
-void pmu_op_start(CPUARMState *env)
130
-{
131
-}
132
-
133
-void pmu_op_finish(CPUARMState *env)
134
-{
135
-}
136
-
137
-void pmu_pre_el_change(ARMCPU *cpu, void *ignored)
138
-{
139
-}
140
-
141
-void pmu_post_el_change(ARMCPU *cpu, void *ignored)
142
-{
143
-}
144
-
145
-#endif
146
-
147
static void pmccfiltr_write(CPUARMState *env, const ARMCPRegInfo *ri,
148
uint64_t value)
149
{
150
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
151
/* Unimplemented so WI. */
152
{ .name = "PMSWINC", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 4,
153
.access = PL0_W, .accessfn = pmreg_access_swinc, .type = ARM_CP_NOP },
154
-#ifndef CONFIG_USER_ONLY
155
{ .name = "PMSELR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 5,
156
.access = PL0_RW, .type = ARM_CP_ALIAS,
157
.fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmselr),
158
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7_cp_reginfo[] = {
159
.fieldoffset = offsetof(CPUARMState, cp15.c15_ccnt),
160
.readfn = pmccntr_read, .writefn = pmccntr_write,
161
.raw_readfn = raw_read, .raw_writefn = raw_write, },
162
-#endif
163
{ .name = "PMCCFILTR", .cp = 15, .opc1 = 0, .crn = 14, .crm = 15, .opc2 = 7,
164
.writefn = pmccfiltr_write_a32, .readfn = pmccfiltr_read_a32,
165
.access = PL0_RW, .accessfn = pmreg_access,
166
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
167
* count register.
168
*/
169
unsigned int i, pmcrn = 0;
170
-#ifndef CONFIG_USER_ONLY
171
ARMCPRegInfo pmcr = {
172
.name = "PMCR", .cp = 15, .crn = 9, .crm = 12, .opc1 = 0, .opc2 = 0,
173
.access = PL0_RW,
174
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
175
g_free(pmevtyper_name);
176
g_free(pmevtyper_el0_name);
177
}
178
-#endif
179
ARMCPRegInfo clidr = {
180
.name = "CLIDR", .state = ARM_CP_STATE_BOTH,
181
.opc0 = 3, .crn = 0, .crm = 0, .opc1 = 1, .opc2 = 1,
182
--
48
--
183
2.20.1
49
2.25.1
184
185
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Claudio Fontana <cfontana@suse.de>
2
2
3
Add 4 attributes that controls the EL1 enable bits, as we may not
3
Remove some unused headers.
4
always want to turn on pointer authentication with -cpu max.
5
However, by default they are enabled.
6
4
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Claudio Fontana <cfontana@suse.de>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Acked-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190108223129.5570-31-richard.henderson@linaro.org
7
Reviewed-by: Claudio Fontana <cfontana@suse.de>
8
Reviewed-by: Cornelia Huck <cohuck@redhat.com>
9
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Message-id: 20221213190537.511-7-farosas@suse.de
11
[added back some includes that are still needed at this point]
12
Signed-off-by: Fabiano Rosas <farosas@suse.de>
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
14
---
12
target/arm/cpu.c | 3 +++
15
target/arm/cpu.c | 1 -
13
target/arm/cpu64.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++
16
target/arm/cpu64.c | 6 ------
14
2 files changed, 63 insertions(+)
17
2 files changed, 7 deletions(-)
15
18
16
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
19
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
17
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/cpu.c
21
--- a/target/arm/cpu.c
19
+++ b/target/arm/cpu.c
22
+++ b/target/arm/cpu.c
20
@@ -XXX,XX +XXX,XX @@ static void arm_cpu_reset(CPUState *s)
23
@@ -XXX,XX +XXX,XX @@
21
env->pstate = PSTATE_MODE_EL0t;
24
#include "target/arm/idau.h"
22
/* Userspace expects access to DC ZVA, CTL_EL0 and the cache ops */
25
#include "qemu/module.h"
23
env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
26
#include "qapi/error.h"
24
+ /* Enable all PAC instructions */
27
-#include "qapi/visitor.h"
25
+ env->cp15.hcr_el2 |= HCR_API;
28
#include "cpu.h"
26
+ env->cp15.scr_el3 |= SCR_API;
29
#ifdef CONFIG_TCG
27
/* and to the FP/Neon instructions */
30
#include "hw/core/tcg-cpu-ops.h"
28
env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
29
/* and to the SVE instructions */
30
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
31
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/cpu64.c
33
--- a/target/arm/cpu64.c
33
+++ b/target/arm/cpu64.c
34
+++ b/target/arm/cpu64.c
34
@@ -XXX,XX +XXX,XX @@ static void cpu_max_set_sve_vq(Object *obj, Visitor *v, const char *name,
35
@@ -XXX,XX +XXX,XX @@
35
error_propagate(errp, err);
36
#include "qemu/osdep.h"
36
}
37
#include "qapi/error.h"
37
38
#include "cpu.h"
38
+#ifdef CONFIG_USER_ONLY
39
-#ifdef CONFIG_TCG
39
+static void cpu_max_get_packey(Object *obj, Visitor *v, const char *name,
40
-#include "hw/core/tcg-cpu-ops.h"
40
+ void *opaque, Error **errp)
41
-#endif /* CONFIG_TCG */
41
+{
42
#include "qemu/module.h"
42
+ ARMCPU *cpu = ARM_CPU(obj);
43
-#if !defined(CONFIG_USER_ONLY)
43
+ const uint64_t *bit = opaque;
44
-#include "hw/loader.h"
44
+ bool enabled = (cpu->env.cp15.sctlr_el[1] & *bit) != 0;
45
-#endif
45
+
46
#include "sysemu/kvm.h"
46
+ visit_type_bool(v, name, &enabled, errp);
47
#include "sysemu/hvf.h"
47
+}
48
#include "kvm_arm.h"
48
+
49
+static void cpu_max_set_packey(Object *obj, Visitor *v, const char *name,
50
+ void *opaque, Error **errp)
51
+{
52
+ ARMCPU *cpu = ARM_CPU(obj);
53
+ Error *err = NULL;
54
+ const uint64_t *bit = opaque;
55
+ bool enabled;
56
+
57
+ visit_type_bool(v, name, &enabled, errp);
58
+
59
+ if (!err) {
60
+ if (enabled) {
61
+ cpu->env.cp15.sctlr_el[1] |= *bit;
62
+ } else {
63
+ cpu->env.cp15.sctlr_el[1] &= ~*bit;
64
+ }
65
+ }
66
+ error_propagate(errp, err);
67
+}
68
+#endif
69
+
70
/* -cpu max: if KVM is enabled, like -cpu host (best possible with this host);
71
* otherwise, a CPU with as many features enabled as our emulation supports.
72
* The version of '-cpu max' for qemu-system-arm is defined in cpu.c;
73
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
74
*/
75
cpu->ctr = 0x80038003; /* 32 byte I and D cacheline size, VIPT icache */
76
cpu->dcz_blocksize = 7; /* 512 bytes */
77
+
78
+ /*
79
+ * Note that Linux will enable enable all of the keys at once.
80
+ * But doing it this way will allow experimentation beyond that.
81
+ */
82
+ {
83
+ static const uint64_t apia_bit = SCTLR_EnIA;
84
+ static const uint64_t apib_bit = SCTLR_EnIB;
85
+ static const uint64_t apda_bit = SCTLR_EnDA;
86
+ static const uint64_t apdb_bit = SCTLR_EnDB;
87
+
88
+ object_property_add(obj, "apia", "bool", cpu_max_get_packey,
89
+ cpu_max_set_packey, NULL,
90
+ (void *)&apia_bit, &error_fatal);
91
+ object_property_add(obj, "apib", "bool", cpu_max_get_packey,
92
+ cpu_max_set_packey, NULL,
93
+ (void *)&apib_bit, &error_fatal);
94
+ object_property_add(obj, "apda", "bool", cpu_max_get_packey,
95
+ cpu_max_set_packey, NULL,
96
+ (void *)&apda_bit, &error_fatal);
97
+ object_property_add(obj, "apdb", "bool", cpu_max_get_packey,
98
+ cpu_max_set_packey, NULL,
99
+ (void *)&apdb_bit, &error_fatal);
100
+
101
+ /* Enable all PAC keys by default. */
102
+ cpu->env.cp15.sctlr_el[1] |= SCTLR_EnIA | SCTLR_EnIB;
103
+ cpu->env.cp15.sctlr_el[1] |= SCTLR_EnDA | SCTLR_EnDB;
104
+ }
105
#endif
106
107
cpu->sve_max_vq = ARM_MAX_VQ;
108
--
49
--
109
2.20.1
50
2.25.1
110
111
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
We can perform this with fewer operations.
3
The pointed MouseTransformInfo structure is accessed read-only.
4
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
5
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-32-richard.henderson@linaro.org
7
Message-id: 20221220142520.24094-2-philmd@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
9
---
10
target/arm/translate-a64.c | 62 +++++++++++++-------------------------
10
include/hw/input/tsc2xxx.h | 4 ++--
11
1 file changed, 21 insertions(+), 41 deletions(-)
11
hw/input/tsc2005.c | 2 +-
12
hw/input/tsc210x.c | 3 +--
13
3 files changed, 4 insertions(+), 5 deletions(-)
12
14
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
diff --git a/include/hw/input/tsc2xxx.h b/include/hw/input/tsc2xxx.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
17
--- a/include/hw/input/tsc2xxx.h
16
+++ b/target/arm/translate-a64.c
18
+++ b/include/hw/input/tsc2xxx.h
17
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
19
@@ -XXX,XX +XXX,XX @@ uWireSlave *tsc2102_init(qemu_irq pint);
18
/* Load the PC from a generic TCG variable.
20
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
19
*
21
I2SCodec *tsc210x_codec(uWireSlave *chip);
20
* If address tagging is enabled via the TCR TBI bits, then loading
22
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
21
- * an address into the PC will clear out any tag in the it:
23
-void tsc210x_set_transform(uWireSlave *chip, MouseTransformInfo *info);
22
+ * an address into the PC will clear out any tag in it:
24
+void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info);
23
* + for EL2 and EL3 there is only one TBI bit, and if it is set
25
void tsc210x_key_event(uWireSlave *chip, int key, int down);
24
* then the address is zero-extended, clearing bits [63:56]
26
25
* + for EL0 and EL1, TBI0 controls addresses with bit 55 == 0
27
/* tsc2005.c */
26
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
28
void *tsc2005_init(qemu_irq pintdav);
27
int tbi = s->tbii;
29
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
28
30
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
29
if (s->current_el <= 1) {
31
+void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info);
30
- /* Test if NEITHER or BOTH TBI values are set. If so, no need to
32
31
- * examine bit 55 of address, can just generate code.
33
#endif
32
- * If mixed, then test via generated code
34
diff --git a/hw/input/tsc2005.c b/hw/input/tsc2005.c
33
- */
35
index XXXXXXX..XXXXXXX 100644
34
- if (tbi == 3) {
36
--- a/hw/input/tsc2005.c
35
- TCGv_i64 tmp_reg = tcg_temp_new_i64();
37
+++ b/hw/input/tsc2005.c
36
- /* Both bits set, sign extension from bit 55 into [63:56] will
38
@@ -XXX,XX +XXX,XX @@ void *tsc2005_init(qemu_irq pintdav)
37
- * cover both cases
39
* from the touchscreen. Assuming 12-bit precision was used during
38
- */
40
* tslib calibration.
39
- tcg_gen_shli_i64(tmp_reg, src, 8);
41
*/
40
- tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
42
-void tsc2005_set_transform(void *opaque, MouseTransformInfo *info)
41
- tcg_temp_free_i64(tmp_reg);
43
+void tsc2005_set_transform(void *opaque, const MouseTransformInfo *info)
42
- } else if (tbi == 0) {
44
{
43
- /* Neither bit set, just load it as-is */
45
TSC2005State *s = (TSC2005State *) opaque;
44
- tcg_gen_mov_i64(cpu_pc, src);
46
45
- } else {
47
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
46
- TCGv_i64 tcg_tmpval = tcg_temp_new_i64();
48
index XXXXXXX..XXXXXXX 100644
47
- TCGv_i64 tcg_bit55 = tcg_temp_new_i64();
49
--- a/hw/input/tsc210x.c
48
- TCGv_i64 tcg_zero = tcg_const_i64(0);
50
+++ b/hw/input/tsc210x.c
49
+ if (tbi != 0) {
51
@@ -XXX,XX +XXX,XX @@ I2SCodec *tsc210x_codec(uWireSlave *chip)
50
+ /* Sign-extend from bit 55. */
52
* from the touchscreen. Assuming 12-bit precision was used during
51
+ tcg_gen_sextract_i64(cpu_pc, src, 0, 56);
53
* tslib calibration.
52
54
*/
53
- tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
55
-void tsc210x_set_transform(uWireSlave *chip,
54
+ if (tbi != 3) {
56
- MouseTransformInfo *info)
55
+ TCGv_i64 tcg_zero = tcg_const_i64(0);
57
+void tsc210x_set_transform(uWireSlave *chip, const MouseTransformInfo *info)
56
58
{
57
- if (tbi == 1) {
59
TSC210xState *s = (TSC210xState *) chip->opaque;
58
- /* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
60
#if 0
59
- tcg_gen_andi_i64(tcg_tmpval, src,
60
- 0x00FFFFFFFFFFFFFFull);
61
- tcg_gen_movcond_i64(TCG_COND_EQ, cpu_pc, tcg_bit55, tcg_zero,
62
- tcg_tmpval, src);
63
- } else {
64
- /* tbi0==0, tbi1==1, so 1-fill upper byte if bit 55 = 1 */
65
- tcg_gen_ori_i64(tcg_tmpval, src,
66
- 0xFF00000000000000ull);
67
- tcg_gen_movcond_i64(TCG_COND_NE, cpu_pc, tcg_bit55, tcg_zero,
68
- tcg_tmpval, src);
69
+ /*
70
+ * The two TBI bits differ.
71
+ * If tbi0, then !tbi1: only use the extension if positive.
72
+ * if !tbi0, then tbi1: only use the extension if negative.
73
+ */
74
+ tcg_gen_movcond_i64(tbi == 1 ? TCG_COND_GE : TCG_COND_LT,
75
+ cpu_pc, cpu_pc, tcg_zero, cpu_pc, src);
76
+ tcg_temp_free_i64(tcg_zero);
77
}
78
- tcg_temp_free_i64(tcg_zero);
79
- tcg_temp_free_i64(tcg_bit55);
80
- tcg_temp_free_i64(tcg_tmpval);
81
+ return;
82
}
83
- } else { /* EL > 1 */
84
+ } else {
85
if (tbi != 0) {
86
/* Force tag byte to all zero */
87
- tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
88
- } else {
89
- /* Load unmodified address */
90
- tcg_gen_mov_i64(cpu_pc, src);
91
+ tcg_gen_extract_i64(cpu_pc, src, 0, 56);
92
+ return;
93
}
94
}
95
+
96
+ /* Load unmodified address */
97
+ tcg_gen_mov_i64(cpu_pc, src);
98
}
99
100
typedef struct DisasCompare64 {
101
--
61
--
102
2.20.1
62
2.25.1
103
63
104
64
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
While we could expose stage_1_mmu_idx, the combination is
3
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
4
probably going to be more useful.
4
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
5
5
Message-id: 20221220142520.24094-3-philmd@linaro.org
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-18-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
7
---
11
target/arm/internals.h | 15 +++++++++++++++
8
hw/arm/nseries.c | 18 +++++++++---------
12
target/arm/helper.c | 7 +++++++
9
1 file changed, 9 insertions(+), 9 deletions(-)
13
2 files changed, 22 insertions(+)
14
10
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
11
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
16
index XXXXXXX..XXXXXXX 100644
12
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
13
--- a/hw/arm/nseries.c
18
+++ b/target/arm/internals.h
14
+++ b/hw/arm/nseries.c
19
@@ -XXX,XX +XXX,XX @@ void arm_cpu_update_vfiq(ARMCPU *cpu);
15
@@ -XXX,XX +XXX,XX @@ static void n8x0_i2c_setup(struct n800_s *s)
20
*/
21
ARMMMUIdx arm_mmu_idx(CPUARMState *env);
22
23
+/**
24
+ * arm_stage1_mmu_idx:
25
+ * @env: The cpu environment
26
+ *
27
+ * Return the ARMMMUIdx for the stage1 traversal for the current regime.
28
+ */
29
+#ifdef CONFIG_USER_ONLY
30
+static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
31
+{
32
+ return ARMMMUIdx_S1NSE0;
33
+}
34
+#else
35
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
36
+#endif
37
+
38
#endif
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 @@ int cpu_mmu_index(CPUARMState *env, bool ifetch)
44
return arm_to_core_mmu_idx(arm_mmu_idx(env));
45
}
16
}
46
17
47
+#ifndef CONFIG_USER_ONLY
18
/* Touchscreen and keypad controller */
48
+ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
19
-static MouseTransformInfo n800_pointercal = {
49
+{
20
+static const MouseTransformInfo n800_pointercal = {
50
+ return stage_1_mmu_idx(arm_mmu_idx(env));
21
.x = 800,
51
+}
22
.y = 480,
52
+#endif
23
.a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },
53
+
24
};
54
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
25
55
target_ulong *cs_base, uint32_t *pflags)
26
-static MouseTransformInfo n810_pointercal = {
27
+static const MouseTransformInfo n810_pointercal = {
28
.x = 800,
29
.y = 480,
30
.a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },
31
@@ -XXX,XX +XXX,XX @@ static void n810_key_event(void *opaque, int keycode)
32
33
#define M    0
34
35
-static int n810_keys[0x80] = {
36
+static const int n810_keys[0x80] = {
37
[0x01] = 16,    /* Q */
38
[0x02] = 37,    /* K */
39
[0x03] = 24,    /* O */
40
@@ -XXX,XX +XXX,XX @@ static void n8x0_usb_setup(struct n800_s *s)
41
/* Setup done before the main bootloader starts by some early setup code
42
* - used when we want to run the main bootloader in emulation. This
43
* isn't documented. */
44
-static uint32_t n800_pinout[104] = {
45
+static const uint32_t n800_pinout[104] = {
46
0x080f00d8, 0x00d40808, 0x03080808, 0x080800d0,
47
0x00dc0808, 0x0b0f0f00, 0x080800b4, 0x00c00808,
48
0x08080808, 0x180800c4, 0x00b80000, 0x08080808,
49
@@ -XXX,XX +XXX,XX @@ static void n8x0_boot_init(void *opaque)
50
#define OMAP_TAG_CBUS        0x4e03
51
#define OMAP_TAG_EM_ASIC_BB5    0x4e04
52
53
-static struct omap_gpiosw_info_s {
54
+static const struct omap_gpiosw_info_s {
55
const char *name;
56
int line;
57
int type;
58
@@ -XXX,XX +XXX,XX @@ static struct omap_gpiosw_info_s {
59
{ NULL }
60
};
61
62
-static struct omap_partition_info_s {
63
+static const struct omap_partition_info_s {
64
uint32_t offset;
65
uint32_t size;
66
int mask;
67
@@ -XXX,XX +XXX,XX @@ static struct omap_partition_info_s {
68
{ 0, 0, 0, NULL }
69
};
70
71
-static uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
72
+static const uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
73
74
static int n8x0_atag_setup(void *p, int model)
56
{
75
{
76
uint8_t *b;
77
uint16_t *w;
78
uint32_t *l;
79
- struct omap_gpiosw_info_s *gpiosw;
80
- struct omap_partition_info_s *partition;
81
+ const struct omap_gpiosw_info_s *gpiosw;
82
+ const struct omap_partition_info_s *partition;
83
const char *tag;
84
85
w = p;
57
--
86
--
58
2.20.1
87
2.25.1
59
88
60
89
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Silent when compiling with -Wextra:
4
5
../hw/arm/nseries.c:1081:12: warning: missing field 'line' initializer [-Wmissing-field-initializers]
6
{ NULL }
7
^
8
9
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
10
Message-id: 20221220142520.24094-4-philmd@linaro.org
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
11
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-30-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
13
---
8
target/arm/cpu64.c | 4 ++++
14
hw/arm/nseries.c | 10 ++++------
9
1 file changed, 4 insertions(+)
15
1 file changed, 4 insertions(+), 6 deletions(-)
10
16
11
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
17
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
12
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/cpu64.c
19
--- a/hw/arm/nseries.c
14
+++ b/target/arm/cpu64.c
20
+++ b/hw/arm/nseries.c
15
@@ -XXX,XX +XXX,XX @@ static void aarch64_max_initfn(Object *obj)
21
@@ -XXX,XX +XXX,XX @@ static const struct omap_gpiosw_info_s {
16
22
"headphone", N8X0_HEADPHONE_GPIO,
17
t = cpu->isar.id_aa64isar1;
23
OMAP_GPIOSW_TYPE_CONNECTION | OMAP_GPIOSW_INVERTED,
18
t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
24
},
19
+ t = FIELD_DP64(t, ID_AA64ISAR1, APA, 1); /* PAuth, architected only */
25
- { NULL }
20
+ t = FIELD_DP64(t, ID_AA64ISAR1, API, 0);
26
+ { /* end of list */ }
21
+ t = FIELD_DP64(t, ID_AA64ISAR1, GPA, 1);
27
}, n810_gpiosw_info[] = {
22
+ t = FIELD_DP64(t, ID_AA64ISAR1, GPI, 0);
28
{
23
cpu->isar.id_aa64isar1 = t;
29
"gps_reset", N810_GPS_RESET_GPIO,
24
30
@@ -XXX,XX +XXX,XX @@ static const struct omap_gpiosw_info_s {
25
t = cpu->isar.id_aa64pfr0;
31
"slide", N810_SLIDE_GPIO,
32
OMAP_GPIOSW_TYPE_COVER | OMAP_GPIOSW_INVERTED,
33
},
34
- { NULL }
35
+ { /* end of list */ }
36
};
37
38
static const struct omap_partition_info_s {
39
@@ -XXX,XX +XXX,XX @@ static const struct omap_partition_info_s {
40
{ 0x00080000, 0x00200000, 0x0, "kernel" },
41
{ 0x00280000, 0x00200000, 0x3, "initfs" },
42
{ 0x00480000, 0x0fb80000, 0x3, "rootfs" },
43
-
44
- { 0, 0, 0, NULL }
45
+ { /* end of list */ }
46
}, n810_part_info[] = {
47
{ 0x00000000, 0x00020000, 0x3, "bootloader" },
48
{ 0x00020000, 0x00060000, 0x0, "config" },
49
{ 0x00080000, 0x00220000, 0x0, "kernel" },
50
{ 0x002a0000, 0x00400000, 0x0, "initfs" },
51
{ 0x006a0000, 0x0f960000, 0x0, "rootfs" },
52
-
53
- { 0, 0, 0, NULL }
54
+ { /* end of list */ }
55
};
56
57
static const uint8_t n8x0_bd_addr[6] = { N8X0_BD_ADDR };
26
--
58
--
27
2.20.1
59
2.25.1
28
60
29
61
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Zhuojia Shen <chaosdefinition@hotmail.com>
2
2
3
The arm_regime_tbi{0,1} functions are replacable with the new function
3
In CPUID registers exposed to userspace, some registers were missing
4
by giving the lowest and highest address.
4
and some fields were not exposed. This patch aligns exposed ID
5
5
registers and their fields with what the upstream kernel currently
6
exposes.
7
8
Specifically, the following new ID registers/fields are exposed to
9
userspace:
10
11
ID_AA64PFR1_EL1.BT: bits 3-0
12
ID_AA64PFR1_EL1.MTE: bits 11-8
13
ID_AA64PFR1_EL1.SME: bits 27-24
14
15
ID_AA64ZFR0_EL1.SVEver: bits 3-0
16
ID_AA64ZFR0_EL1.AES: bits 7-4
17
ID_AA64ZFR0_EL1.BitPerm: bits 19-16
18
ID_AA64ZFR0_EL1.BF16: bits 23-20
19
ID_AA64ZFR0_EL1.SHA3: bits 35-32
20
ID_AA64ZFR0_EL1.SM4: bits 43-40
21
ID_AA64ZFR0_EL1.I8MM: bits 47-44
22
ID_AA64ZFR0_EL1.F32MM: bits 55-52
23
ID_AA64ZFR0_EL1.F64MM: bits 59-56
24
25
ID_AA64SMFR0_EL1.F32F32: bit 32
26
ID_AA64SMFR0_EL1.B16F32: bit 34
27
ID_AA64SMFR0_EL1.F16F32: bit 35
28
ID_AA64SMFR0_EL1.I8I32: bits 39-36
29
ID_AA64SMFR0_EL1.F64F64: bit 48
30
ID_AA64SMFR0_EL1.I16I64: bits 55-52
31
ID_AA64SMFR0_EL1.FA64: bit 63
32
33
ID_AA64MMFR0_EL1.ECV: bits 63-60
34
35
ID_AA64MMFR1_EL1.AFP: bits 47-44
36
37
ID_AA64MMFR2_EL1.AT: bits 35-32
38
39
ID_AA64ISAR0_EL1.RNDR: bits 63-60
40
41
ID_AA64ISAR1_EL1.FRINTTS: bits 35-32
42
ID_AA64ISAR1_EL1.BF16: bits 47-44
43
ID_AA64ISAR1_EL1.DGH: bits 51-48
44
ID_AA64ISAR1_EL1.I8MM: bits 55-52
45
46
ID_AA64ISAR2_EL1.WFxT: bits 3-0
47
ID_AA64ISAR2_EL1.RPRES: bits 7-4
48
ID_AA64ISAR2_EL1.GPA3: bits 11-8
49
ID_AA64ISAR2_EL1.APA3: bits 15-12
50
51
The code is also refactored to use symbolic names for ID register fields
52
for better readability and maintainability.
53
54
The test case in tests/tcg/aarch64/sysregs.c is also updated to match
55
the intended behavior.
56
57
Signed-off-by: Zhuojia Shen <chaosdefinition@hotmail.com>
58
Message-id: DS7PR12MB6309FB585E10772928F14271ACE79@DS7PR12MB6309.namprd12.prod.outlook.com
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
59
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
60
[PMM: use Sn_n_Cn_Cn_n syntax to work with older assemblers
8
Message-id: 20190108223129.5570-24-richard.henderson@linaro.org
61
that don't recognize id_aa64isar2_el1 and id_aa64mmfr2_el1]
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
62
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
63
---
11
target/arm/cpu.h | 35 -----------------------
64
target/arm/helper.c | 96 +++++++++++++++++++++++++------
12
target/arm/helper.c | 70 ++++++++++++++++-----------------------------
65
tests/tcg/aarch64/sysregs.c | 24 ++++++--
13
2 files changed, 24 insertions(+), 81 deletions(-)
66
tests/tcg/aarch64/Makefile.target | 7 ++-
14
67
3 files changed, 103 insertions(+), 24 deletions(-)
15
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
68
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/cpu.h
18
+++ b/target/arm/cpu.h
19
@@ -XXX,XX +XXX,XX @@ static inline bool arm_cpu_bswap_data(CPUARMState *env)
20
}
21
#endif
22
23
-#ifndef CONFIG_USER_ONLY
24
-/**
25
- * arm_regime_tbi0:
26
- * @env: CPUARMState
27
- * @mmu_idx: MMU index indicating required translation regime
28
- *
29
- * Extracts the TBI0 value from the appropriate TCR for the current EL
30
- *
31
- * Returns: the TBI0 value.
32
- */
33
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx);
34
-
35
-/**
36
- * arm_regime_tbi1:
37
- * @env: CPUARMState
38
- * @mmu_idx: MMU index indicating required translation regime
39
- *
40
- * Extracts the TBI1 value from the appropriate TCR for the current EL
41
- *
42
- * Returns: the TBI1 value.
43
- */
44
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx);
45
-#else
46
-/* We can't handle tagged addresses properly in user-only mode */
47
-static inline uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
48
-{
49
- return 0;
50
-}
51
-
52
-static inline uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
53
-{
54
- return 0;
55
-}
56
-#endif
57
-
58
void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
59
target_ulong *cs_base, uint32_t *flags);
60
61
diff --git a/target/arm/helper.c b/target/arm/helper.c
69
diff --git a/target/arm/helper.c b/target/arm/helper.c
62
index XXXXXXX..XXXXXXX 100644
70
index XXXXXXX..XXXXXXX 100644
63
--- a/target/arm/helper.c
71
--- a/target/arm/helper.c
64
+++ b/target/arm/helper.c
72
+++ b/target/arm/helper.c
65
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx stage_1_mmu_idx(ARMMMUIdx mmu_idx)
73
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
66
return mmu_idx;
74
#ifdef CONFIG_USER_ONLY
67
}
75
static const ARMCPRegUserSpaceInfo v8_user_idregs[] = {
68
76
{ .name = "ID_AA64PFR0_EL1",
69
-/* Returns TBI0 value for current regime el */
77
- .exported_bits = 0x000f000f00ff0000,
70
-uint32_t arm_regime_tbi0(CPUARMState *env, ARMMMUIdx mmu_idx)
78
- .fixed_bits = 0x0000000000000011 },
71
-{
79
+ .exported_bits = R_ID_AA64PFR0_FP_MASK |
72
- TCR *tcr;
80
+ R_ID_AA64PFR0_ADVSIMD_MASK |
73
- uint32_t el;
81
+ R_ID_AA64PFR0_SVE_MASK |
74
-
82
+ R_ID_AA64PFR0_DIT_MASK,
75
- /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
83
+ .fixed_bits = (0x1u << R_ID_AA64PFR0_EL0_SHIFT) |
76
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
84
+ (0x1u << R_ID_AA64PFR0_EL1_SHIFT) },
77
- */
85
{ .name = "ID_AA64PFR1_EL1",
78
- mmu_idx = stage_1_mmu_idx(mmu_idx);
86
- .exported_bits = 0x00000000000000f0 },
79
-
87
+ .exported_bits = R_ID_AA64PFR1_BT_MASK |
80
- tcr = regime_tcr(env, mmu_idx);
88
+ R_ID_AA64PFR1_SSBS_MASK |
81
- el = regime_el(env, mmu_idx);
89
+ R_ID_AA64PFR1_MTE_MASK |
82
-
90
+ R_ID_AA64PFR1_SME_MASK },
83
- if (el > 1) {
91
{ .name = "ID_AA64PFR*_EL1_RESERVED",
84
- return extract64(tcr->raw_tcr, 20, 1);
92
- .is_glob = true },
85
- } else {
93
- { .name = "ID_AA64ZFR0_EL1" },
86
- return extract64(tcr->raw_tcr, 37, 1);
94
+ .is_glob = true },
87
- }
95
+ { .name = "ID_AA64ZFR0_EL1",
88
-}
96
+ .exported_bits = R_ID_AA64ZFR0_SVEVER_MASK |
89
-
97
+ R_ID_AA64ZFR0_AES_MASK |
90
-/* Returns TBI1 value for current regime el */
98
+ R_ID_AA64ZFR0_BITPERM_MASK |
91
-uint32_t arm_regime_tbi1(CPUARMState *env, ARMMMUIdx mmu_idx)
99
+ R_ID_AA64ZFR0_BFLOAT16_MASK |
92
-{
100
+ R_ID_AA64ZFR0_SHA3_MASK |
93
- TCR *tcr;
101
+ R_ID_AA64ZFR0_SM4_MASK |
94
- uint32_t el;
102
+ R_ID_AA64ZFR0_I8MM_MASK |
95
-
103
+ R_ID_AA64ZFR0_F32MM_MASK |
96
- /* For EL0 and EL1, TBI is controlled by stage 1's TCR, so convert
104
+ R_ID_AA64ZFR0_F64MM_MASK },
97
- * a stage 1+2 mmu index into the appropriate stage 1 mmu index.
105
+ { .name = "ID_AA64SMFR0_EL1",
98
- */
106
+ .exported_bits = R_ID_AA64SMFR0_F32F32_MASK |
99
- mmu_idx = stage_1_mmu_idx(mmu_idx);
107
+ R_ID_AA64SMFR0_B16F32_MASK |
100
-
108
+ R_ID_AA64SMFR0_F16F32_MASK |
101
- tcr = regime_tcr(env, mmu_idx);
109
+ R_ID_AA64SMFR0_I8I32_MASK |
102
- el = regime_el(env, mmu_idx);
110
+ R_ID_AA64SMFR0_F64F64_MASK |
103
-
111
+ R_ID_AA64SMFR0_I16I64_MASK |
104
- if (el > 1) {
112
+ R_ID_AA64SMFR0_FA64_MASK },
105
- return 0;
113
{ .name = "ID_AA64MMFR0_EL1",
106
- } else {
114
- .fixed_bits = 0x00000000ff000000 },
107
- return extract64(tcr->raw_tcr, 38, 1);
115
- { .name = "ID_AA64MMFR1_EL1" },
108
- }
116
+ .exported_bits = R_ID_AA64MMFR0_ECV_MASK,
109
-}
117
+ .fixed_bits = (0xfu << R_ID_AA64MMFR0_TGRAN64_SHIFT) |
110
-
118
+ (0xfu << R_ID_AA64MMFR0_TGRAN4_SHIFT) },
111
/* Return the TTBR associated with this translation regime */
119
+ { .name = "ID_AA64MMFR1_EL1",
112
static inline uint64_t regime_ttbr(CPUARMState *env, ARMMMUIdx mmu_idx,
120
+ .exported_bits = R_ID_AA64MMFR1_AFP_MASK },
113
int ttbrn)
121
+ { .name = "ID_AA64MMFR2_EL1",
114
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
122
+ .exported_bits = R_ID_AA64MMFR2_AT_MASK },
115
123
{ .name = "ID_AA64MMFR*_EL1_RESERVED",
116
*pc = env->pc;
124
- .is_glob = true },
117
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
125
+ .is_glob = true },
118
- /* Get control bits for tagged addresses */
126
{ .name = "ID_AA64DFR0_EL1",
119
- flags = FIELD_DP32(flags, TBFLAG_A64, TBII,
127
- .fixed_bits = 0x0000000000000006 },
120
- (arm_regime_tbi1(env, mmu_idx) << 1) |
128
- { .name = "ID_AA64DFR1_EL1" },
121
- arm_regime_tbi0(env, mmu_idx));
129
+ .fixed_bits = (0x6u << R_ID_AA64DFR0_DEBUGVER_SHIFT) },
130
+ { .name = "ID_AA64DFR1_EL1" },
131
{ .name = "ID_AA64DFR*_EL1_RESERVED",
132
- .is_glob = true },
133
+ .is_glob = true },
134
{ .name = "ID_AA64AFR*",
135
- .is_glob = true },
136
+ .is_glob = true },
137
{ .name = "ID_AA64ISAR0_EL1",
138
- .exported_bits = 0x00fffffff0fffff0 },
139
+ .exported_bits = R_ID_AA64ISAR0_AES_MASK |
140
+ R_ID_AA64ISAR0_SHA1_MASK |
141
+ R_ID_AA64ISAR0_SHA2_MASK |
142
+ R_ID_AA64ISAR0_CRC32_MASK |
143
+ R_ID_AA64ISAR0_ATOMIC_MASK |
144
+ R_ID_AA64ISAR0_RDM_MASK |
145
+ R_ID_AA64ISAR0_SHA3_MASK |
146
+ R_ID_AA64ISAR0_SM3_MASK |
147
+ R_ID_AA64ISAR0_SM4_MASK |
148
+ R_ID_AA64ISAR0_DP_MASK |
149
+ R_ID_AA64ISAR0_FHM_MASK |
150
+ R_ID_AA64ISAR0_TS_MASK |
151
+ R_ID_AA64ISAR0_RNDR_MASK },
152
{ .name = "ID_AA64ISAR1_EL1",
153
- .exported_bits = 0x000000f0ffffffff },
154
+ .exported_bits = R_ID_AA64ISAR1_DPB_MASK |
155
+ R_ID_AA64ISAR1_APA_MASK |
156
+ R_ID_AA64ISAR1_API_MASK |
157
+ R_ID_AA64ISAR1_JSCVT_MASK |
158
+ R_ID_AA64ISAR1_FCMA_MASK |
159
+ R_ID_AA64ISAR1_LRCPC_MASK |
160
+ R_ID_AA64ISAR1_GPA_MASK |
161
+ R_ID_AA64ISAR1_GPI_MASK |
162
+ R_ID_AA64ISAR1_FRINTTS_MASK |
163
+ R_ID_AA64ISAR1_SB_MASK |
164
+ R_ID_AA64ISAR1_BF16_MASK |
165
+ R_ID_AA64ISAR1_DGH_MASK |
166
+ R_ID_AA64ISAR1_I8MM_MASK },
167
+ { .name = "ID_AA64ISAR2_EL1",
168
+ .exported_bits = R_ID_AA64ISAR2_WFXT_MASK |
169
+ R_ID_AA64ISAR2_RPRES_MASK |
170
+ R_ID_AA64ISAR2_GPA3_MASK |
171
+ R_ID_AA64ISAR2_APA3_MASK },
172
{ .name = "ID_AA64ISAR*_EL1_RESERVED",
173
- .is_glob = true },
174
+ .is_glob = true },
175
};
176
modify_arm_cp_regs(v8_idregs, v8_user_idregs);
177
#endif
178
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
179
#ifdef CONFIG_USER_ONLY
180
static const ARMCPRegUserSpaceInfo id_v8_user_midr_cp_reginfo[] = {
181
{ .name = "MIDR_EL1",
182
- .exported_bits = 0x00000000ffffffff },
183
- { .name = "REVIDR_EL1" },
184
+ .exported_bits = R_MIDR_EL1_REVISION_MASK |
185
+ R_MIDR_EL1_PARTNUM_MASK |
186
+ R_MIDR_EL1_ARCHITECTURE_MASK |
187
+ R_MIDR_EL1_VARIANT_MASK |
188
+ R_MIDR_EL1_IMPLEMENTER_MASK },
189
+ { .name = "REVIDR_EL1" },
190
};
191
modify_arm_cp_regs(id_v8_midr_cp_reginfo, id_v8_user_midr_cp_reginfo);
192
#endif
193
diff --git a/tests/tcg/aarch64/sysregs.c b/tests/tcg/aarch64/sysregs.c
194
index XXXXXXX..XXXXXXX 100644
195
--- a/tests/tcg/aarch64/sysregs.c
196
+++ b/tests/tcg/aarch64/sysregs.c
197
@@ -XXX,XX +XXX,XX @@
198
#define HWCAP_CPUID (1 << 11)
199
#endif
200
201
+/*
202
+ * Older assemblers don't recognize newer system register names,
203
+ * but we can still access them by the Sn_n_Cn_Cn_n syntax.
204
+ */
205
+#define SYS_ID_AA64ISAR2_EL1 S3_0_C0_C6_2
206
+#define SYS_ID_AA64MMFR2_EL1 S3_0_C0_C7_2
122
+
207
+
123
+#ifndef CONFIG_USER_ONLY
208
int failed_bit_count;
124
+ /*
209
125
+ * Get control bits for tagged addresses. Note that the
210
/* Read and print system register `id' value */
126
+ * translator only uses this for instruction addresses.
211
@@ -XXX,XX +XXX,XX @@ int main(void)
127
+ */
212
* minimum valid fields - for the purposes of this check allowed
128
+ {
213
* to have non-zero values.
129
+ ARMMMUIdx stage1 = stage_1_mmu_idx(mmu_idx);
214
*/
130
+ ARMVAParameters p0 = aa64_va_parameters_both(env, 0, stage1);
215
- get_cpu_reg_check_mask(id_aa64isar0_el1, _m(00ff,ffff,f0ff,fff0));
131
+ int tbii, tbid;
216
- get_cpu_reg_check_mask(id_aa64isar1_el1, _m(0000,00f0,ffff,ffff));
132
+
217
+ get_cpu_reg_check_mask(id_aa64isar0_el1, _m(f0ff,ffff,f0ff,fff0));
133
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
218
+ get_cpu_reg_check_mask(id_aa64isar1_el1, _m(00ff,f0ff,ffff,ffff));
134
+ if (regime_el(env, stage1) < 2) {
219
+ get_cpu_reg_check_mask(SYS_ID_AA64ISAR2_EL1, _m(0000,0000,0000,ffff));
135
+ ARMVAParameters p1 = aa64_va_parameters_both(env, -1, stage1);
220
/* TGran4 & TGran64 as pegged to -1 */
136
+ tbid = (p1.tbi << 1) | p0.tbi;
221
- get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(0000,0000,ff00,0000));
137
+ tbii = tbid & ~((p1.tbid << 1) | p0.tbid);
222
- get_cpu_reg_check_zero(id_aa64mmfr1_el1);
138
+ } else {
223
+ get_cpu_reg_check_mask(id_aa64mmfr0_el1, _m(f000,0000,ff00,0000));
139
+ tbid = p0.tbi;
224
+ get_cpu_reg_check_mask(id_aa64mmfr1_el1, _m(0000,f000,0000,0000));
140
+ tbii = tbid & !p0.tbid;
225
+ get_cpu_reg_check_mask(SYS_ID_AA64MMFR2_EL1, _m(0000,000f,0000,0000));
141
+ }
226
/* EL1/EL0 reported as AA64 only */
142
+
227
get_cpu_reg_check_mask(id_aa64pfr0_el1, _m(000f,000f,00ff,0011));
143
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBII, tbii);
228
- get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0000,00f0));
144
+ }
229
+ get_cpu_reg_check_mask(id_aa64pfr1_el1, _m(0000,0000,0f00,0fff));
230
/* all hidden, DebugVer fixed to 0x6 (ARMv8 debug architecture) */
231
get_cpu_reg_check_mask(id_aa64dfr0_el1, _m(0000,0000,0000,0006));
232
get_cpu_reg_check_zero(id_aa64dfr1_el1);
233
- get_cpu_reg_check_zero(id_aa64zfr0_el1);
234
+ get_cpu_reg_check_mask(id_aa64zfr0_el1, _m(0ff0,ff0f,00ff,00ff));
235
+#ifdef HAS_ARMV9_SME
236
+ get_cpu_reg_check_mask(id_aa64smfr0_el1, _m(80f1,00fd,0000,0000));
145
+#endif
237
+#endif
146
238
147
if (cpu_isar_feature(aa64_sve, cpu)) {
239
get_cpu_reg_check_zero(id_aa64afr0_el1);
148
int sve_el = sve_exception_el(env, current_el);
240
get_cpu_reg_check_zero(id_aa64afr1_el1);
241
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
242
index XXXXXXX..XXXXXXX 100644
243
--- a/tests/tcg/aarch64/Makefile.target
244
+++ b/tests/tcg/aarch64/Makefile.target
245
@@ -XXX,XX +XXX,XX @@ config-cc.mak: Makefile
246
     $(call cc-option,-march=armv8.1-a+sve2, CROSS_CC_HAS_SVE2); \
247
     $(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \
248
     $(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
249
-     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE)) 3> config-cc.mak
250
+     $(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
251
+     $(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak
252
-include config-cc.mak
253
254
# Pauth Tests
255
@@ -XXX,XX +XXX,XX @@ endif
256
ifneq ($(CROSS_CC_HAS_SVE),)
257
# System Registers Tests
258
AARCH64_TESTS += sysregs
259
+ifneq ($(CROSS_CC_HAS_ARMV9_SME),)
260
+sysregs: CFLAGS+=-march=armv9-a+sme -DHAS_ARMV9_SME
261
+else
262
sysregs: CFLAGS+=-march=armv8.1-a+sve
263
+endif
264
265
# SVE ioctl test
266
AARCH64_TESTS += sve-ioctls
149
--
267
--
150
2.20.1
268
2.25.1
151
152
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
We need to reuse this from helper-a64.c. Provide a stub
3
This function is not used anywhere outside this file,
4
definition for CONFIG_USER_ONLY. This matches the stub
4
so we can make the function "static void".
5
definitions that we removed for arm_regime_tbi{0,1} before.
6
5
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190108223129.5570-21-richard.henderson@linaro.org
8
Reviewed-by: Eric Auger <eric.auger@redhat.com>
9
Message-id: 20221216214924.4711-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
---
11
---
12
target/arm/internals.h | 17 +++++++++++++++++
12
include/hw/arm/smmu-common.h | 3 ---
13
target/arm/helper.c | 4 ++--
13
hw/arm/smmu-common.c | 2 +-
14
2 files changed, 19 insertions(+), 2 deletions(-)
14
2 files changed, 1 insertion(+), 4 deletions(-)
15
15
16
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
diff --git a/include/hw/arm/smmu-common.h b/include/hw/arm/smmu-common.h
17
index XXXXXXX..XXXXXXX 100644
17
index XXXXXXX..XXXXXXX 100644
18
--- a/target/arm/internals.h
18
--- a/include/hw/arm/smmu-common.h
19
+++ b/target/arm/internals.h
19
+++ b/include/hw/arm/smmu-common.h
20
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVAParameters {
20
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
21
bool using64k : 1;
21
/* Unmap the range of all the notifiers registered to any IOMMU mr */
22
} ARMVAParameters;
22
void smmu_inv_notifiers_all(SMMUState *s);
23
23
24
+#ifdef CONFIG_USER_ONLY
24
-/* Unmap the range of all the notifiers registered to @mr */
25
+static inline ARMVAParameters aa64_va_parameters(CPUARMState *env,
25
-void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr);
26
+ uint64_t va,
26
-
27
+ ARMMMUIdx mmu_idx, bool data)
27
#endif /* HW_ARM_SMMU_COMMON_H */
28
+{
28
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
29
+ return (ARMVAParameters) {
30
+ /* 48-bit address space */
31
+ .tsz = 16,
32
+ /* We can't handle tagged addresses properly in user-only mode */
33
+ .tbi = false,
34
+ };
35
+}
36
+#else
37
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
38
+ ARMMMUIdx mmu_idx, bool data);
39
+#endif
40
+
41
#endif
42
diff --git a/target/arm/helper.c b/target/arm/helper.c
43
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
44
--- a/target/arm/helper.c
30
--- a/hw/arm/smmu-common.c
45
+++ b/target/arm/helper.c
31
+++ b/hw/arm/smmu-common.c
46
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
32
@@ -XXX,XX +XXX,XX @@ static void smmu_unmap_notifier_range(IOMMUNotifier *n)
47
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
48
}
33
}
49
34
50
-static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
35
/* Unmap all notifiers attached to @mr */
51
- ARMMMUIdx mmu_idx, bool data)
36
-inline void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
52
+ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
37
+static void smmu_inv_notifiers_mr(IOMMUMemoryRegion *mr)
53
+ ARMMMUIdx mmu_idx, bool data)
54
{
38
{
55
uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
39
IOMMUNotifier *n;
56
uint32_t el = regime_el(env, mmu_idx);
40
57
--
41
--
58
2.20.1
42
2.25.1
59
43
60
44
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Philippe Mathieu-Daudé <philmd@linaro.org>
2
2
3
Stripping out the authentication data does not require any crypto,
3
When using Clang ("Apple clang version 14.0.0 (clang-1400.0.29.202)")
4
it merely requires the virtual address parameters.
4
and building with -Wall we get:
5
5
6
hw/arm/smmu-common.c:173:33: warning: static function 'smmu_hash_remove_by_asid_iova' is used in an inline function with external linkage [-Wstatic-in-inline]
7
hw/arm/smmu-common.h:170:1: note: use 'static' to give inline function 'smmu_iotlb_inv_iova' internal linkage
8
void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
9
^
10
static
11
12
None of our code base require / use inlined functions with external
13
linkage. Some places use internal inlining in the hot path. These
14
two functions are certainly not in any hot path and don't justify
15
any inlining, so these are likely oversights rather than intentional.
16
17
Reported-by: Stefan Weil <sw@weilnetz.de>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
18
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
19
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
8
Message-id: 20190108223129.5570-25-richard.henderson@linaro.org
20
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
21
Reviewed-by: Eric Auger <eric.auger@redhat.com>
22
Message-id: 20221216214924.4711-3-philmd@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
23
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
24
---
11
target/arm/pauth_helper.c | 14 +++++++++++++-
25
hw/arm/smmu-common.c | 13 ++++++-------
12
1 file changed, 13 insertions(+), 1 deletion(-)
26
1 file changed, 6 insertions(+), 7 deletions(-)
13
27
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
28
diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c
15
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
30
--- a/hw/arm/smmu-common.c
17
+++ b/target/arm/pauth_helper.c
31
+++ b/hw/arm/smmu-common.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
32
@@ -XXX,XX +XXX,XX @@ void smmu_iotlb_insert(SMMUState *bs, SMMUTransCfg *cfg, SMMUTLBEntry *new)
19
g_assert_not_reached(); /* FIXME */
33
g_hash_table_insert(bs->iotlb, key, new);
20
}
34
}
21
35
22
+static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
36
-inline void smmu_iotlb_inv_all(SMMUState *s)
23
+{
37
+void smmu_iotlb_inv_all(SMMUState *s)
24
+ uint64_t extfield = -param.select;
25
+ int bot_pac_bit = 64 - param.tsz;
26
+ int top_pac_bit = 64 - 8 * param.tbi;
27
+
28
+ return deposit64(ptr, bot_pac_bit, top_pac_bit - bot_pac_bit, extfield);
29
+}
30
+
31
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
32
ARMPACKey *key, bool data, int keynumber)
33
{
38
{
34
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
39
trace_smmu_iotlb_inv_all();
35
40
g_hash_table_remove_all(s->iotlb);
36
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
41
@@ -XXX,XX +XXX,XX @@ static gboolean smmu_hash_remove_by_asid_iova(gpointer key, gpointer value,
42
((entry->iova & ~info->mask) == info->iova);
43
}
44
45
-inline void
46
-smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
47
- uint8_t tg, uint64_t num_pages, uint8_t ttl)
48
+void smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
49
+ uint8_t tg, uint64_t num_pages, uint8_t ttl)
37
{
50
{
38
- g_assert_not_reached(); /* FIXME */
51
/* if tg is not set we use 4KB range invalidation */
39
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
52
uint8_t granule = tg ? tg * 2 + 10 : 12;
40
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
53
@@ -XXX,XX +XXX,XX @@ smmu_iotlb_inv_iova(SMMUState *s, int asid, dma_addr_t iova,
41
+
54
&info);
42
+ return pauth_original_ptr(ptr, param);
43
}
55
}
44
56
45
static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
57
-inline void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
58
+void smmu_iotlb_inv_asid(SMMUState *s, uint16_t asid)
59
{
60
trace_smmu_iotlb_inv_asid(asid);
61
g_hash_table_foreach_remove(s->iotlb, smmu_hash_remove_by_asid, &asid);
62
@@ -XXX,XX +XXX,XX @@ error:
63
*
64
* return 0 on success
65
*/
66
-inline int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
67
- SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
68
+int smmu_ptw(SMMUTransCfg *cfg, dma_addr_t iova, IOMMUAccessFlags perm,
69
+ SMMUTLBEntry *tlbe, SMMUPTWEventInfo *info)
70
{
71
if (!cfg->aa64) {
72
/*
46
--
73
--
47
2.20.1
74
2.25.1
48
75
49
76
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
This will enable PAuth decode in a subsequent patch.
3
So far the GPT timers were unable to raise IRQs to the processor.
4
4
5
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20190108223129.5570-13-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
target/arm/translate-a64.c | 47 +++++++++++++++++++++++++++++---------
9
include/hw/arm/fsl-imx7.h | 5 +++++
11
1 file changed, 36 insertions(+), 11 deletions(-)
10
hw/arm/fsl-imx7.c | 10 ++++++++++
11
2 files changed, 15 insertions(+)
12
12
13
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
13
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
14
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/translate-a64.c
15
--- a/include/hw/arm/fsl-imx7.h
16
+++ b/target/arm/translate-a64.c
16
+++ b/include/hw/arm/fsl-imx7.h
17
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
17
@@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs {
18
rn = extract32(insn, 5, 5);
18
FSL_IMX7_USB2_IRQ = 42,
19
op4 = extract32(insn, 0, 5);
19
FSL_IMX7_USB3_IRQ = 40,
20
20
21
- if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
21
+ FSL_IMX7_GPT1_IRQ = 55,
22
- unallocated_encoding(s);
22
+ FSL_IMX7_GPT2_IRQ = 54,
23
- return;
23
+ FSL_IMX7_GPT3_IRQ = 53,
24
+ if (op2 != 0x1f) {
24
+ FSL_IMX7_GPT4_IRQ = 52,
25
+ goto do_unallocated;
25
+
26
FSL_IMX7_WDOG1_IRQ = 78,
27
FSL_IMX7_WDOG2_IRQ = 79,
28
FSL_IMX7_WDOG3_IRQ = 10,
29
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
30
index XXXXXXX..XXXXXXX 100644
31
--- a/hw/arm/fsl-imx7.c
32
+++ b/hw/arm/fsl-imx7.c
33
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
34
FSL_IMX7_GPT4_ADDR,
35
};
36
37
+ static const int FSL_IMX7_GPTn_IRQ[FSL_IMX7_NUM_GPTS] = {
38
+ FSL_IMX7_GPT1_IRQ,
39
+ FSL_IMX7_GPT2_IRQ,
40
+ FSL_IMX7_GPT3_IRQ,
41
+ FSL_IMX7_GPT4_IRQ,
42
+ };
43
+
44
s->gpt[i].ccm = IMX_CCM(&s->ccm);
45
sysbus_realize(SYS_BUS_DEVICE(&s->gpt[i]), &error_abort);
46
sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpt[i]), 0, FSL_IMX7_GPTn_ADDR[i]);
47
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpt[i]), 0,
48
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
49
+ FSL_IMX7_GPTn_IRQ[i]));
26
}
50
}
27
51
28
switch (opc) {
52
for (i = 0; i < FSL_IMX7_NUM_GPIOS; i++) {
29
case 0: /* BR */
30
case 1: /* BLR */
31
case 2: /* RET */
32
- gen_a64_set_pc(s, cpu_reg(s, rn));
33
+ switch (op3) {
34
+ case 0:
35
+ if (op4 != 0) {
36
+ goto do_unallocated;
37
+ }
38
+ dst = cpu_reg(s, rn);
39
+ break;
40
+
41
+ default:
42
+ goto do_unallocated;
43
+ }
44
+
45
+ gen_a64_set_pc(s, dst);
46
/* BLR also needs to load return address */
47
if (opc == 1) {
48
tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
49
}
50
break;
51
+
52
case 4: /* ERET */
53
if (s->current_el == 0) {
54
- unallocated_encoding(s);
55
- return;
56
+ goto do_unallocated;
57
+ }
58
+ switch (op3) {
59
+ case 0:
60
+ if (op4 != 0) {
61
+ goto do_unallocated;
62
+ }
63
+ dst = tcg_temp_new_i64();
64
+ tcg_gen_ld_i64(dst, cpu_env,
65
+ offsetof(CPUARMState, elr_el[s->current_el]));
66
+ break;
67
+
68
+ default:
69
+ goto do_unallocated;
70
}
71
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
72
gen_io_start();
73
}
74
- dst = tcg_temp_new_i64();
75
- tcg_gen_ld_i64(dst, cpu_env,
76
- offsetof(CPUARMState, elr_el[s->current_el]));
77
+
78
gen_helper_exception_return(cpu_env, dst);
79
tcg_temp_free_i64(dst);
80
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
81
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
82
/* Must exit loop to check un-masked IRQs */
83
s->base.is_jmp = DISAS_EXIT;
84
return;
85
+
86
case 5: /* DRPS */
87
- if (rn != 0x1f) {
88
- unallocated_encoding(s);
89
+ if (op3 != 0 || op4 != 0 || rn != 0x1f) {
90
+ goto do_unallocated;
91
} else {
92
unsupported_encoding(s, insn);
93
}
94
return;
95
+
96
default:
97
+ do_unallocated:
98
unallocated_encoding(s);
99
return;
100
}
101
--
53
--
102
2.20.1
54
2.25.1
103
104
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
This is not really functional yet, because the crypto is not yet
3
CCM derived clocks will have to be added later.
4
implemented. This, however follows the AddPAC pseudo function.
5
4
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-27-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
8
---
11
target/arm/pauth_helper.c | 42 ++++++++++++++++++++++++++++++++++++++-
9
hw/misc/imx7_ccm.c | 49 +++++++++++++++++++++++++++++++++++++---------
12
1 file changed, 41 insertions(+), 1 deletion(-)
10
1 file changed, 40 insertions(+), 9 deletions(-)
13
11
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
12
diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c
15
index XXXXXXX..XXXXXXX 100644
13
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
14
--- a/hw/misc/imx7_ccm.c
17
+++ b/target/arm/pauth_helper.c
15
+++ b/hw/misc/imx7_ccm.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
16
@@ -XXX,XX +XXX,XX @@
19
static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
17
#include "hw/misc/imx7_ccm.h"
20
ARMPACKey *key, bool data)
18
#include "migration/vmstate.h"
19
20
+#include "trace.h"
21
+
22
+#define CKIH_FREQ 24000000 /* 24MHz crystal input */
23
+
24
static void imx7_analog_reset(DeviceState *dev)
21
{
25
{
22
- g_assert_not_reached(); /* FIXME */
26
IMX7AnalogState *s = IMX7_ANALOG(dev);
23
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
27
@@ -XXX,XX +XXX,XX @@ static const VMStateDescription vmstate_imx7_ccm = {
24
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
28
static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
25
+ uint64_t pac, ext_ptr, ext, test;
29
{
26
+ int bot_bit, top_bit;
30
/*
31
- * This function is "consumed" by GPT emulation code, however on
32
- * i.MX7 each GPT block can have their own clock root. This means
33
- * that this functions needs somehow to know requester's identity
34
- * and the way to pass it: be it via additional IMXClk constants
35
- * or by adding another argument to this method needs to be
36
- * figured out
37
+ * This function is "consumed" by GPT emulation code. Some clocks
38
+ * have fixed frequencies and we can provide requested frequency
39
+ * easily. However for CCM provided clocks (like IPG) each GPT
40
+ * timer can have its own clock root.
41
+ * This means we need additionnal information when calling this
42
+ * function to know the requester's identity.
43
*/
44
- qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Not implemented\n",
45
- TYPE_IMX7_CCM, __func__);
46
- return 0;
47
+ uint32_t freq = 0;
27
+
48
+
28
+ /* If tagged pointers are in use, use ptr<55>, otherwise ptr<63>. */
49
+ switch (clock) {
29
+ if (param.tbi) {
50
+ case CLK_NONE:
30
+ ext = sextract64(ptr, 55, 1);
51
+ break;
31
+ } else {
52
+ case CLK_32k:
32
+ ext = sextract64(ptr, 63, 1);
53
+ freq = CKIL_FREQ;
54
+ break;
55
+ case CLK_HIGH:
56
+ freq = CKIH_FREQ;
57
+ break;
58
+ case CLK_IPG:
59
+ case CLK_IPG_HIGH:
60
+ /*
61
+ * For now we don't have a way to figure out the device this
62
+ * function is called for. Until then the IPG derived clocks
63
+ * are left unimplemented.
64
+ */
65
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Clock %d Not implemented\n",
66
+ TYPE_IMX7_CCM, __func__, clock);
67
+ break;
68
+ default:
69
+ qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
70
+ TYPE_IMX7_CCM, __func__, clock);
71
+ break;
33
+ }
72
+ }
34
+
73
+
35
+ /* Build a pointer with known good extension bits. */
74
+ trace_ccm_clock_freq(clock, freq);
36
+ top_bit = 64 - 8 * param.tbi;
37
+ bot_bit = 64 - param.tsz;
38
+ ext_ptr = deposit64(ptr, bot_bit, top_bit - bot_bit, ext);
39
+
75
+
40
+ pac = pauth_computepac(ext_ptr, modifier, *key);
76
+ return freq;
41
+
42
+ /*
43
+ * Check if the ptr has good extension bits and corrupt the
44
+ * pointer authentication code if not.
45
+ */
46
+ test = sextract64(ptr, bot_bit, top_bit - bot_bit);
47
+ if (test != 0 && test != -1) {
48
+ pac ^= MAKE_64BIT_MASK(top_bit - 1, 1);
49
+ }
50
+
51
+ /*
52
+ * Preserve the determination between upper and lower at bit 55,
53
+ * and insert pointer authentication code.
54
+ */
55
+ if (param.tbi) {
56
+ ptr &= ~MAKE_64BIT_MASK(bot_bit, 55 - bot_bit + 1);
57
+ pac &= MAKE_64BIT_MASK(bot_bit, 54 - bot_bit + 1);
58
+ } else {
59
+ ptr &= MAKE_64BIT_MASK(0, bot_bit);
60
+ pac &= ~(MAKE_64BIT_MASK(55, 1) | MAKE_64BIT_MASK(0, bot_bit));
61
+ }
62
+ ext &= MAKE_64BIT_MASK(55, 1);
63
+ return pac | ext | ptr;
64
}
77
}
65
78
66
static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
79
static void imx7_ccm_class_init(ObjectClass *klass, void *data)
67
--
80
--
68
2.20.1
81
2.25.1
69
70
diff view generated by jsdifflib
1
From: Aaron Lindsay <aaron@os.amperecomputing.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
Add an array for PMOVSSET so we only define it for v7ve+ platforms
3
The i.MX6UL doesn't support CLK_HIGH ou CLK_HIGH_DIV clock source.
4
4
5
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
5
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
6
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Message-id: 20181211151945.29137-7-aaron@os.amperecomputing.com
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
8
---
10
target/arm/helper.c | 28 ++++++++++++++++++++++++++++
9
include/hw/timer/imx_gpt.h | 1 +
11
1 file changed, 28 insertions(+)
10
hw/arm/fsl-imx6ul.c | 2 +-
11
hw/misc/imx6ul_ccm.c | 6 ------
12
hw/timer/imx_gpt.c | 25 +++++++++++++++++++++++++
13
4 files changed, 27 insertions(+), 7 deletions(-)
12
14
13
diff --git a/target/arm/helper.c b/target/arm/helper.c
15
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
14
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper.c
17
--- a/include/hw/timer/imx_gpt.h
16
+++ b/target/arm/helper.c
18
+++ b/include/hw/timer/imx_gpt.h
17
@@ -XXX,XX +XXX,XX @@ static void pmovsr_write(CPUARMState *env, const ARMCPRegInfo *ri,
19
@@ -XXX,XX +XXX,XX @@
18
env->cp15.c9_pmovsr &= ~value;
20
#define TYPE_IMX25_GPT "imx25.gpt"
21
#define TYPE_IMX31_GPT "imx31.gpt"
22
#define TYPE_IMX6_GPT "imx6.gpt"
23
+#define TYPE_IMX6UL_GPT "imx6ul.gpt"
24
#define TYPE_IMX7_GPT "imx7.gpt"
25
26
#define TYPE_IMX_GPT TYPE_IMX25_GPT
27
diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c
28
index XXXXXXX..XXXXXXX 100644
29
--- a/hw/arm/fsl-imx6ul.c
30
+++ b/hw/arm/fsl-imx6ul.c
31
@@ -XXX,XX +XXX,XX @@ static void fsl_imx6ul_init(Object *obj)
32
*/
33
for (i = 0; i < FSL_IMX6UL_NUM_GPTS; i++) {
34
snprintf(name, NAME_SIZE, "gpt%d", i);
35
- object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX7_GPT);
36
+ object_initialize_child(obj, name, &s->gpt[i], TYPE_IMX6UL_GPT);
37
}
38
39
/*
40
diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/hw/misc/imx6ul_ccm.c
43
+++ b/hw/misc/imx6ul_ccm.c
44
@@ -XXX,XX +XXX,XX @@ static uint32_t imx6ul_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock)
45
case CLK_32k:
46
freq = CKIL_FREQ;
47
break;
48
- case CLK_HIGH:
49
- freq = CKIH_FREQ;
50
- break;
51
- case CLK_HIGH_DIV:
52
- freq = CKIH_FREQ / 8;
53
- break;
54
default:
55
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: unsupported clock %d\n",
56
TYPE_IMX6UL_CCM, __func__, clock);
57
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/hw/timer/imx_gpt.c
60
+++ b/hw/timer/imx_gpt.c
61
@@ -XXX,XX +XXX,XX @@ static const IMXClk imx6_gpt_clocks[] = {
62
CLK_HIGH, /* 111 reference clock */
63
};
64
65
+static const IMXClk imx6ul_gpt_clocks[] = {
66
+ CLK_NONE, /* 000 No clock source */
67
+ CLK_IPG, /* 001 ipg_clk, 532MHz*/
68
+ CLK_IPG_HIGH, /* 010 ipg_clk_highfreq */
69
+ CLK_EXT, /* 011 External clock */
70
+ CLK_32k, /* 100 ipg_clk_32k */
71
+ CLK_NONE, /* 101 not defined */
72
+ CLK_NONE, /* 110 not defined */
73
+ CLK_NONE, /* 111 not defined */
74
+};
75
+
76
static const IMXClk imx7_gpt_clocks[] = {
77
CLK_NONE, /* 000 No clock source */
78
CLK_IPG, /* 001 ipg_clk, 532MHz*/
79
@@ -XXX,XX +XXX,XX @@ static void imx6_gpt_init(Object *obj)
80
s->clocks = imx6_gpt_clocks;
19
}
81
}
20
82
21
+static void pmovsset_write(CPUARMState *env, const ARMCPRegInfo *ri,
83
+static void imx6ul_gpt_init(Object *obj)
22
+ uint64_t value)
23
+{
84
+{
24
+ value &= pmu_counter_mask(env);
85
+ IMXGPTState *s = IMX_GPT(obj);
25
+ env->cp15.c9_pmovsr |= value;
86
+
87
+ s->clocks = imx6ul_gpt_clocks;
26
+}
88
+}
27
+
89
+
28
static void pmxevtyper_write(CPUARMState *env, const ARMCPRegInfo *ri,
90
static void imx7_gpt_init(Object *obj)
29
uint64_t value)
30
{
91
{
31
@@ -XXX,XX +XXX,XX @@ static const ARMCPRegInfo v7mp_cp_reginfo[] = {
92
IMXGPTState *s = IMX_GPT(obj);
32
REGINFO_SENTINEL
93
@@ -XXX,XX +XXX,XX @@ static const TypeInfo imx6_gpt_info = {
94
.instance_init = imx6_gpt_init,
33
};
95
};
34
96
35
+static const ARMCPRegInfo pmovsset_cp_reginfo[] = {
97
+static const TypeInfo imx6ul_gpt_info = {
36
+ /* PMOVSSET is not implemented in v7 before v7ve */
98
+ .name = TYPE_IMX6UL_GPT,
37
+ { .name = "PMOVSSET", .cp = 15, .opc1 = 0, .crn = 9, .crm = 14, .opc2 = 3,
99
+ .parent = TYPE_IMX25_GPT,
38
+ .access = PL0_RW, .accessfn = pmreg_access,
100
+ .instance_init = imx6ul_gpt_init,
39
+ .type = ARM_CP_ALIAS,
40
+ .fieldoffset = offsetoflow32(CPUARMState, cp15.c9_pmovsr),
41
+ .writefn = pmovsset_write,
42
+ .raw_writefn = raw_write },
43
+ { .name = "PMOVSSET_EL0", .state = ARM_CP_STATE_AA64,
44
+ .opc0 = 3, .opc1 = 3, .crn = 9, .crm = 14, .opc2 = 3,
45
+ .access = PL0_RW, .accessfn = pmreg_access,
46
+ .type = ARM_CP_ALIAS,
47
+ .fieldoffset = offsetof(CPUARMState, cp15.c9_pmovsr),
48
+ .writefn = pmovsset_write,
49
+ .raw_writefn = raw_write },
50
+ REGINFO_SENTINEL
51
+};
101
+};
52
+
102
+
53
static void teecr_write(CPUARMState *env, const ARMCPRegInfo *ri,
103
static const TypeInfo imx7_gpt_info = {
54
uint64_t value)
104
.name = TYPE_IMX7_GPT,
55
{
105
.parent = TYPE_IMX25_GPT,
56
@@ -XXX,XX +XXX,XX @@ void register_cp_regs_for_features(ARMCPU *cpu)
106
@@ -XXX,XX +XXX,XX @@ static void imx_gpt_register_types(void)
57
!arm_feature(env, ARM_FEATURE_PMSA)) {
107
type_register_static(&imx25_gpt_info);
58
define_arm_cp_regs(cpu, v7mp_cp_reginfo);
108
type_register_static(&imx31_gpt_info);
59
}
109
type_register_static(&imx6_gpt_info);
60
+ if (arm_feature(env, ARM_FEATURE_V7VE)) {
110
+ type_register_static(&imx6ul_gpt_info);
61
+ define_arm_cp_regs(cpu, pmovsset_cp_reginfo);
111
type_register_static(&imx7_gpt_info);
62
+ }
112
}
63
if (arm_feature(env, ARM_FEATURE_V7)) {
113
64
/* v7 performance monitor control register: same implementor
65
* field as main ID register, and we implement only the cycle
66
--
114
--
67
2.20.1
115
2.25.1
68
69
diff view generated by jsdifflib
1
From: Philippe Mathieu-Daudé <philmd@redhat.com>
1
From: Jean-Christophe Dubois <jcd@tribudubois.net>
2
2
3
When the device is disabled, the internal circuitry keeps the data
3
IRQs were not associated to the various GPIO devices inside i.MX7D.
4
register loaded and doesn't update it.
4
This patch brings the i.MX7D on par with i.MX6.
5
5
6
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
6
Signed-off-by: Jean-Christophe Dubois <jcd@tribudubois.net>
7
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
7
Message-id: 20221226101418.415170-1-jcd@tribudubois.net
8
Message-id: 20190104182057.8778-1-philmd@redhat.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
10
---
11
hw/char/stm32f2xx_usart.c | 3 +--
11
include/hw/arm/fsl-imx7.h | 15 +++++++++++++++
12
1 file changed, 1 insertion(+), 2 deletions(-)
12
hw/arm/fsl-imx7.c | 31 ++++++++++++++++++++++++++++++-
13
2 files changed, 45 insertions(+), 1 deletion(-)
13
14
14
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
15
diff --git a/include/hw/arm/fsl-imx7.h b/include/hw/arm/fsl-imx7.h
15
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
16
--- a/hw/char/stm32f2xx_usart.c
17
--- a/include/hw/arm/fsl-imx7.h
17
+++ b/hw/char/stm32f2xx_usart.c
18
+++ b/include/hw/arm/fsl-imx7.h
18
@@ -XXX,XX +XXX,XX @@ static void stm32f2xx_usart_receive(void *opaque, const uint8_t *buf, int size)
19
@@ -XXX,XX +XXX,XX @@ enum FslIMX7IRQs {
19
{
20
FSL_IMX7_GPT3_IRQ = 53,
20
STM32F2XXUsartState *s = opaque;
21
FSL_IMX7_GPT4_IRQ = 52,
21
22
22
- s->usart_dr = *buf;
23
+ FSL_IMX7_GPIO1_LOW_IRQ = 64,
23
-
24
+ FSL_IMX7_GPIO1_HIGH_IRQ = 65,
24
if (!(s->usart_cr1 & USART_CR1_UE && s->usart_cr1 & USART_CR1_RE)) {
25
+ FSL_IMX7_GPIO2_LOW_IRQ = 66,
25
/* USART not enabled - drop the chars */
26
+ FSL_IMX7_GPIO2_HIGH_IRQ = 67,
26
DB_PRINT("Dropping the chars\n");
27
+ FSL_IMX7_GPIO3_LOW_IRQ = 68,
27
return;
28
+ FSL_IMX7_GPIO3_HIGH_IRQ = 69,
29
+ FSL_IMX7_GPIO4_LOW_IRQ = 70,
30
+ FSL_IMX7_GPIO4_HIGH_IRQ = 71,
31
+ FSL_IMX7_GPIO5_LOW_IRQ = 72,
32
+ FSL_IMX7_GPIO5_HIGH_IRQ = 73,
33
+ FSL_IMX7_GPIO6_LOW_IRQ = 74,
34
+ FSL_IMX7_GPIO6_HIGH_IRQ = 75,
35
+ FSL_IMX7_GPIO7_LOW_IRQ = 76,
36
+ FSL_IMX7_GPIO7_HIGH_IRQ = 77,
37
+
38
FSL_IMX7_WDOG1_IRQ = 78,
39
FSL_IMX7_WDOG2_IRQ = 79,
40
FSL_IMX7_WDOG3_IRQ = 10,
41
diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c
42
index XXXXXXX..XXXXXXX 100644
43
--- a/hw/arm/fsl-imx7.c
44
+++ b/hw/arm/fsl-imx7.c
45
@@ -XXX,XX +XXX,XX @@ static void fsl_imx7_realize(DeviceState *dev, Error **errp)
46
FSL_IMX7_GPIO7_ADDR,
47
};
48
49
+ static const int FSL_IMX7_GPIOn_LOW_IRQ[FSL_IMX7_NUM_GPIOS] = {
50
+ FSL_IMX7_GPIO1_LOW_IRQ,
51
+ FSL_IMX7_GPIO2_LOW_IRQ,
52
+ FSL_IMX7_GPIO3_LOW_IRQ,
53
+ FSL_IMX7_GPIO4_LOW_IRQ,
54
+ FSL_IMX7_GPIO5_LOW_IRQ,
55
+ FSL_IMX7_GPIO6_LOW_IRQ,
56
+ FSL_IMX7_GPIO7_LOW_IRQ,
57
+ };
58
+
59
+ static const int FSL_IMX7_GPIOn_HIGH_IRQ[FSL_IMX7_NUM_GPIOS] = {
60
+ FSL_IMX7_GPIO1_HIGH_IRQ,
61
+ FSL_IMX7_GPIO2_HIGH_IRQ,
62
+ FSL_IMX7_GPIO3_HIGH_IRQ,
63
+ FSL_IMX7_GPIO4_HIGH_IRQ,
64
+ FSL_IMX7_GPIO5_HIGH_IRQ,
65
+ FSL_IMX7_GPIO6_HIGH_IRQ,
66
+ FSL_IMX7_GPIO7_HIGH_IRQ,
67
+ };
68
+
69
sysbus_realize(SYS_BUS_DEVICE(&s->gpio[i]), &error_abort);
70
- sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0, FSL_IMX7_GPIOn_ADDR[i]);
71
+ sysbus_mmio_map(SYS_BUS_DEVICE(&s->gpio[i]), 0,
72
+ FSL_IMX7_GPIOn_ADDR[i]);
73
+
74
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 0,
75
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
76
+ FSL_IMX7_GPIOn_LOW_IRQ[i]));
77
+
78
+ sysbus_connect_irq(SYS_BUS_DEVICE(&s->gpio[i]), 1,
79
+ qdev_get_gpio_in(DEVICE(&s->a7mpcore),
80
+ FSL_IMX7_GPIOn_HIGH_IRQ[i]));
28
}
81
}
29
82
30
+ s->usart_dr = *buf;
83
/*
31
s->usart_sr |= USART_SR_RXNE;
32
33
if (s->usart_cr1 & USART_CR1_RXNEIE) {
34
--
84
--
35
2.20.1
85
2.25.1
36
37
diff view generated by jsdifflib
Deleted patch
1
From: Eric Auger <eric.auger@redhat.com>
2
1
3
Let's report IO-coherent access is supported for translation
4
table walks, descriptor fetches and queues by setting the COHACC
5
override flag. Without that, we observe wrong command opcodes.
6
The DT description also advertises the dma coherency.
7
8
Fixes a703b4f6c1ee ("hw/arm/virt-acpi-build: Add smmuv3 node in IORT table")
9
10
Signed-off-by: Eric Auger <eric.auger@redhat.com>
11
Reported-by: Shameerali Kolothum Thodi <shameerali.kolothum.thodi@huawei.com>
12
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
13
Reviewed-by: Andrew Jones <drjones@redhat.com>
14
Message-id: 20190107101041.765-1-eric.auger@redhat.com
15
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
---
17
include/hw/acpi/acpi-defs.h | 2 ++
18
hw/arm/virt-acpi-build.c | 1 +
19
2 files changed, 3 insertions(+)
20
21
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
22
index XXXXXXX..XXXXXXX 100644
23
--- a/include/hw/acpi/acpi-defs.h
24
+++ b/include/hw/acpi/acpi-defs.h
25
@@ -XXX,XX +XXX,XX @@ struct AcpiIortItsGroup {
26
} QEMU_PACKED;
27
typedef struct AcpiIortItsGroup AcpiIortItsGroup;
28
29
+#define ACPI_IORT_SMMU_V3_COHACC_OVERRIDE 1
30
+
31
struct AcpiIortSmmu3 {
32
ACPI_IORT_NODE_HEADER_DEF
33
uint64_t base_address;
34
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/hw/arm/virt-acpi-build.c
37
+++ b/hw/arm/virt-acpi-build.c
38
@@ -XXX,XX +XXX,XX @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
39
smmu->mapping_count = cpu_to_le32(1);
40
smmu->mapping_offset = cpu_to_le32(sizeof(*smmu));
41
smmu->base_address = cpu_to_le64(vms->memmap[VIRT_SMMU].base);
42
+ smmu->flags = cpu_to_le32(ACPI_IORT_SMMU_V3_COHACC_OVERRIDE);
43
smmu->event_gsiv = cpu_to_le32(irq);
44
smmu->pri_gsiv = cpu_to_le32(irq + 1);
45
smmu->gerr_gsiv = cpu_to_le32(irq + 2);
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Add storage space for the 5 encryption keys.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-2-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 30 +++++++++++++++++++++++++++++-
11
1 file changed, 29 insertions(+), 1 deletion(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ typedef struct ARMVectorReg {
18
uint64_t d[2 * ARM_MAX_VQ] QEMU_ALIGNED(16);
19
} ARMVectorReg;
20
21
-/* In AArch32 mode, predicate registers do not exist at all. */
22
#ifdef TARGET_AARCH64
23
+/* In AArch32 mode, predicate registers do not exist at all. */
24
typedef struct ARMPredicateReg {
25
uint64_t p[2 * ARM_MAX_VQ / 8] QEMU_ALIGNED(16);
26
} ARMPredicateReg;
27
+
28
+/* In AArch32 mode, PAC keys do not exist at all. */
29
+typedef struct ARMPACKey {
30
+ uint64_t lo, hi;
31
+} ARMPACKey;
32
#endif
33
34
35
@@ -XXX,XX +XXX,XX @@ typedef struct CPUARMState {
36
uint32_t cregs[16];
37
} iwmmxt;
38
39
+#ifdef TARGET_AARCH64
40
+ ARMPACKey apia_key;
41
+ ARMPACKey apib_key;
42
+ ARMPACKey apda_key;
43
+ ARMPACKey apdb_key;
44
+ ARMPACKey apga_key;
45
+#endif
46
+
47
#if defined(CONFIG_USER_ONLY)
48
/* For usermode syscall translation. */
49
int eabi;
50
@@ -XXX,XX +XXX,XX @@ static inline bool isar_feature_aa64_fcma(const ARMISARegisters *id)
51
return FIELD_EX64(id->id_aa64isar1, ID_AA64ISAR1, FCMA) != 0;
52
}
53
54
+static inline bool isar_feature_aa64_pauth(const ARMISARegisters *id)
55
+{
56
+ /*
57
+ * Note that while QEMU will only implement the architected algorithm
58
+ * QARMA, and thus APA+GPA, the host cpu for kvm may use implementation
59
+ * defined algorithms, and thus API+GPI, and this predicate controls
60
+ * migration of the 128-bit keys.
61
+ */
62
+ return (id->id_aa64isar1 &
63
+ (FIELD_DP64(0, ID_AA64ISAR1, APA, -1) |
64
+ FIELD_DP64(0, ID_AA64ISAR1, API, -1) |
65
+ FIELD_DP64(0, ID_AA64ISAR1, GPA, -1) |
66
+ FIELD_DP64(0, ID_AA64ISAR1, GPI, -1))) != 0;
67
+}
68
+
69
static inline bool isar_feature_aa64_fp16(const ARMISARegisters *id)
70
{
71
/* We always set the AdvSIMD and FP fields identically wrt FP16. */
72
--
73
2.20.1
74
75
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Post v8.4 bits taken from SysReg_v85_xml-00bet8.
4
5
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Message-id: 20190108223129.5570-3-richard.henderson@linaro.org
8
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
9
---
10
target/arm/cpu.h | 45 +++++++++++++++++++++++++++++++++------------
11
1 file changed, 33 insertions(+), 12 deletions(-)
12
13
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/cpu.h
16
+++ b/target/arm/cpu.h
17
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
18
#define SCTLR_A (1U << 1)
19
#define SCTLR_C (1U << 2)
20
#define SCTLR_W (1U << 3) /* up to v6; RAO in v7 */
21
-#define SCTLR_SA (1U << 3)
22
+#define SCTLR_nTLSMD_32 (1U << 3) /* v8.2-LSMAOC, AArch32 only */
23
+#define SCTLR_SA (1U << 3) /* AArch64 only */
24
#define SCTLR_P (1U << 4) /* up to v5; RAO in v6 and v7 */
25
+#define SCTLR_LSMAOE_32 (1U << 4) /* v8.2-LSMAOC, AArch32 only */
26
#define SCTLR_SA0 (1U << 4) /* v8 onward, AArch64 only */
27
#define SCTLR_D (1U << 5) /* up to v5; RAO in v6 */
28
#define SCTLR_CP15BEN (1U << 5) /* v7 onward */
29
#define SCTLR_L (1U << 6) /* up to v5; RAO in v6 and v7; RAZ in v8 */
30
+#define SCTLR_nAA (1U << 6) /* when v8.4-LSE is implemented */
31
#define SCTLR_B (1U << 7) /* up to v6; RAZ in v7 */
32
#define SCTLR_ITD (1U << 7) /* v8 onward */
33
#define SCTLR_S (1U << 8) /* up to v6; RAZ in v7 */
34
@@ -XXX,XX +XXX,XX @@ void pmccntr_sync(CPUARMState *env);
35
#define SCTLR_R (1U << 9) /* up to v6; RAZ in v7 */
36
#define SCTLR_UMA (1U << 9) /* v8 onward, AArch64 only */
37
#define SCTLR_F (1U << 10) /* up to v6 */
38
-#define SCTLR_SW (1U << 10) /* v7 onward */
39
-#define SCTLR_Z (1U << 11)
40
+#define SCTLR_SW (1U << 10) /* v7, RES0 in v8 */
41
+#define SCTLR_Z (1U << 11) /* in v7, RES1 in v8 */
42
+#define SCTLR_EOS (1U << 11) /* v8.5-ExS */
43
#define SCTLR_I (1U << 12)
44
-#define SCTLR_V (1U << 13)
45
+#define SCTLR_V (1U << 13) /* AArch32 only */
46
+#define SCTLR_EnDB (1U << 13) /* v8.3, AArch64 only */
47
#define SCTLR_RR (1U << 14) /* up to v7 */
48
#define SCTLR_DZE (1U << 14) /* v8 onward, AArch64 only */
49
#define SCTLR_L4 (1U << 15) /* up to v6; RAZ in v7 */
50
#define SCTLR_UCT (1U << 15) /* v8 onward, AArch64 only */
51
#define SCTLR_DT (1U << 16) /* up to ??, RAO in v6 and v7 */
52
#define SCTLR_nTWI (1U << 16) /* v8 onward */
53
-#define SCTLR_HA (1U << 17)
54
+#define SCTLR_HA (1U << 17) /* up to v7, RES0 in v8 */
55
#define SCTLR_BR (1U << 17) /* PMSA only */
56
#define SCTLR_IT (1U << 18) /* up to ??, RAO in v6 and v7 */
57
#define SCTLR_nTWE (1U << 18) /* v8 onward */
58
#define SCTLR_WXN (1U << 19)
59
#define SCTLR_ST (1U << 20) /* up to ??, RAZ in v6 */
60
-#define SCTLR_UWXN (1U << 20) /* v7 onward */
61
-#define SCTLR_FI (1U << 21)
62
-#define SCTLR_U (1U << 22)
63
+#define SCTLR_UWXN (1U << 20) /* v7 onward, AArch32 only */
64
+#define SCTLR_FI (1U << 21) /* up to v7, v8 RES0 */
65
+#define SCTLR_IESB (1U << 21) /* v8.2-IESB, AArch64 only */
66
+#define SCTLR_U (1U << 22) /* up to v6, RAO in v7 */
67
+#define SCTLR_EIS (1U << 22) /* v8.5-ExS */
68
#define SCTLR_XP (1U << 23) /* up to v6; v7 onward RAO */
69
+#define SCTLR_SPAN (1U << 23) /* v8.1-PAN */
70
#define SCTLR_VE (1U << 24) /* up to v7 */
71
#define SCTLR_E0E (1U << 24) /* v8 onward, AArch64 only */
72
#define SCTLR_EE (1U << 25)
73
#define SCTLR_L2 (1U << 26) /* up to v6, RAZ in v7 */
74
#define SCTLR_UCI (1U << 26) /* v8 onward, AArch64 only */
75
-#define SCTLR_NMFI (1U << 27)
76
-#define SCTLR_TRE (1U << 28)
77
-#define SCTLR_AFE (1U << 29)
78
-#define SCTLR_TE (1U << 30)
79
+#define SCTLR_NMFI (1U << 27) /* up to v7, RAZ in v7VE and v8 */
80
+#define SCTLR_EnDA (1U << 27) /* v8.3, AArch64 only */
81
+#define SCTLR_TRE (1U << 28) /* AArch32 only */
82
+#define SCTLR_nTLSMD_64 (1U << 28) /* v8.2-LSMAOC, AArch64 only */
83
+#define SCTLR_AFE (1U << 29) /* AArch32 only */
84
+#define SCTLR_LSMAOE_64 (1U << 29) /* v8.2-LSMAOC, AArch64 only */
85
+#define SCTLR_TE (1U << 30) /* AArch32 only */
86
+#define SCTLR_EnIB (1U << 30) /* v8.3, AArch64 only */
87
+#define SCTLR_EnIA (1U << 31) /* v8.3, AArch64 only */
88
+#define SCTLR_BT0 (1ULL << 35) /* v8.5-BTI */
89
+#define SCTLR_BT1 (1ULL << 36) /* v8.5-BTI */
90
+#define SCTLR_ITFSB (1ULL << 37) /* v8.5-MemTag */
91
+#define SCTLR_TCF0 (3ULL << 38) /* v8.5-MemTag */
92
+#define SCTLR_TCF (3ULL << 40) /* v8.5-MemTag */
93
+#define SCTLR_ATA0 (1ULL << 42) /* v8.5-MemTag */
94
+#define SCTLR_ATA (1ULL << 43) /* v8.5-MemTag */
95
+#define SCTLR_DSSBS (1ULL << 44) /* v8.5 */
96
97
#define CPTR_TCPAC (1U << 31)
98
#define CPTR_TTA (1U << 20)
99
--
100
2.20.1
101
102
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
There are 5 bits of state that could be added, but to save
4
space within tbflags, add only a single enable bit.
5
Helpers will determine the rest of the state at runtime.
6
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
9
Message-id: 20190108223129.5570-4-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 1 +
13
target/arm/translate.h | 2 ++
14
target/arm/helper.c | 19 +++++++++++++++++++
15
target/arm/translate-a64.c | 1 +
16
4 files changed, 23 insertions(+)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A64, TBI0, 0, 1)
23
FIELD(TBFLAG_A64, TBI1, 1, 1)
24
FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
25
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
26
+FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
27
28
static inline bool bswap_code(bool sctlr_b)
29
{
30
diff --git a/target/arm/translate.h b/target/arm/translate.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/translate.h
33
+++ b/target/arm/translate.h
34
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
35
bool is_ldex;
36
/* True if a single-step exception will be taken to the current EL */
37
bool ss_same_el;
38
+ /* True if v8.3-PAuth is active. */
39
+ bool pauth_active;
40
/* Bottom two bits of XScale c15_cpar coprocessor access control reg */
41
int c15_cpar;
42
/* TCG op of the current insn_start. */
43
diff --git a/target/arm/helper.c b/target/arm/helper.c
44
index XXXXXXX..XXXXXXX 100644
45
--- a/target/arm/helper.c
46
+++ b/target/arm/helper.c
47
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
48
flags = FIELD_DP32(flags, TBFLAG_A64, SVEEXC_EL, sve_el);
49
flags = FIELD_DP32(flags, TBFLAG_A64, ZCR_LEN, zcr_len);
50
}
51
+
52
+ if (cpu_isar_feature(aa64_pauth, cpu)) {
53
+ /*
54
+ * In order to save space in flags, we record only whether
55
+ * pauth is "inactive", meaning all insns are implemented as
56
+ * a nop, or "active" when some action must be performed.
57
+ * The decision of which action to take is left to a helper.
58
+ */
59
+ uint64_t sctlr;
60
+ if (current_el == 0) {
61
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
62
+ sctlr = env->cp15.sctlr_el[1];
63
+ } else {
64
+ sctlr = env->cp15.sctlr_el[current_el];
65
+ }
66
+ if (sctlr & (SCTLR_EnIA | SCTLR_EnIB | SCTLR_EnDA | SCTLR_EnDB)) {
67
+ flags = FIELD_DP32(flags, TBFLAG_A64, PAUTH_ACTIVE, 1);
68
+ }
69
+ }
70
} else {
71
*pc = env->regs[15];
72
flags = FIELD_DP32(flags, TBFLAG_A32, THUMB, env->thumb);
73
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/target/arm/translate-a64.c
76
+++ b/target/arm/translate-a64.c
77
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
78
dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
79
dc->sve_excp_el = FIELD_EX32(tb_flags, TBFLAG_A64, SVEEXC_EL);
80
dc->sve_len = (FIELD_EX32(tb_flags, TBFLAG_A64, ZCR_LEN) + 1) * 16;
81
+ dc->pauth_active = FIELD_EX32(tb_flags, TBFLAG_A64, PAUTH_ACTIVE);
82
dc->vec_len = 0;
83
dc->vec_stride = 0;
84
dc->cp_regs = arm_cpu->cp_regs;
85
--
86
2.20.1
87
88
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This path uses cpu_loop_exit_restore to unwind current processor state.
4
5
Suggested-by: Peter Maydell <peter.maydell@linaro.org>
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-5-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/internals.h | 7 +++++++
12
target/arm/op_helper.c | 19 +++++++++++++++++--
13
2 files changed, 24 insertions(+), 2 deletions(-)
14
15
diff --git a/target/arm/internals.h b/target/arm/internals.h
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/internals.h
18
+++ b/target/arm/internals.h
19
@@ -XXX,XX +XXX,XX @@ FIELD(V7M_EXCRET, RES1, 7, 25) /* including the must-be-1 prefix */
20
void QEMU_NORETURN raise_exception(CPUARMState *env, uint32_t excp,
21
uint32_t syndrome, uint32_t target_el);
22
23
+/*
24
+ * Similarly, but also use unwinding to restore cpu state.
25
+ */
26
+void QEMU_NORETURN raise_exception_ra(CPUARMState *env, uint32_t excp,
27
+ uint32_t syndrome, uint32_t target_el,
28
+ uintptr_t ra);
29
+
30
/*
31
* For AArch64, map a given EL to an index in the banked_spsr array.
32
* Note that this mapping and the AArch32 mapping defined in bank_number()
33
diff --git a/target/arm/op_helper.c b/target/arm/op_helper.c
34
index XXXXXXX..XXXXXXX 100644
35
--- a/target/arm/op_helper.c
36
+++ b/target/arm/op_helper.c
37
@@ -XXX,XX +XXX,XX @@
38
#define SIGNBIT (uint32_t)0x80000000
39
#define SIGNBIT64 ((uint64_t)1 << 63)
40
41
-void raise_exception(CPUARMState *env, uint32_t excp,
42
- uint32_t syndrome, uint32_t target_el)
43
+static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
44
+ uint32_t syndrome, uint32_t target_el)
45
{
46
CPUState *cs = CPU(arm_env_get_cpu(env));
47
48
@@ -XXX,XX +XXX,XX @@ void raise_exception(CPUARMState *env, uint32_t excp,
49
cs->exception_index = excp;
50
env->exception.syndrome = syndrome;
51
env->exception.target_el = target_el;
52
+
53
+ return cs;
54
+}
55
+
56
+void raise_exception(CPUARMState *env, uint32_t excp,
57
+ uint32_t syndrome, uint32_t target_el)
58
+{
59
+ CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
60
cpu_loop_exit(cs);
61
}
62
63
+void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
64
+ uint32_t target_el, uintptr_t ra)
65
+{
66
+ CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
67
+ cpu_loop_exit_restore(cs, ra);
68
+}
69
+
70
static int exception_target_el(CPUARMState *env)
71
{
72
int target_el = MAX(1, arm_current_el(env));
73
--
74
2.20.1
75
76
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
The cryptographic internals are stubbed out for now,
4
but the enable and trap bits are checked.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-6-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/Makefile.objs | 1 +
12
target/arm/helper-a64.h | 12 +++
13
target/arm/internals.h | 6 ++
14
target/arm/pauth_helper.c | 186 ++++++++++++++++++++++++++++++++++++++
15
4 files changed, 205 insertions(+)
16
create mode 100644 target/arm/pauth_helper.c
17
18
diff --git a/target/arm/Makefile.objs b/target/arm/Makefile.objs
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/Makefile.objs
21
+++ b/target/arm/Makefile.objs
22
@@ -XXX,XX +XXX,XX @@ obj-y += translate.o op_helper.o helper.o cpu.o
23
obj-y += neon_helper.o iwmmxt_helper.o vec_helper.o
24
obj-y += gdbstub.o
25
obj-$(TARGET_AARCH64) += cpu64.o translate-a64.o helper-a64.o gdbstub64.o
26
+obj-$(TARGET_AARCH64) += pauth_helper.o
27
obj-y += crypto_helper.o
28
obj-$(CONFIG_SOFTMMU) += arm-powerctl.o
29
30
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
31
index XXXXXXX..XXXXXXX 100644
32
--- a/target/arm/helper-a64.h
33
+++ b/target/arm/helper-a64.h
34
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_rinth, f16, f16, ptr)
35
DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
36
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
37
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
38
+
39
+DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
40
+DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
41
+DEF_HELPER_FLAGS_3(pacda, TCG_CALL_NO_WG, i64, env, i64, i64)
42
+DEF_HELPER_FLAGS_3(pacdb, TCG_CALL_NO_WG, i64, env, i64, i64)
43
+DEF_HELPER_FLAGS_3(pacga, TCG_CALL_NO_WG, i64, env, i64, i64)
44
+DEF_HELPER_FLAGS_3(autia, TCG_CALL_NO_WG, i64, env, i64, i64)
45
+DEF_HELPER_FLAGS_3(autib, TCG_CALL_NO_WG, i64, env, i64, i64)
46
+DEF_HELPER_FLAGS_3(autda, TCG_CALL_NO_WG, i64, env, i64, i64)
47
+DEF_HELPER_FLAGS_3(autdb, TCG_CALL_NO_WG, i64, env, i64, i64)
48
+DEF_HELPER_FLAGS_2(xpaci, TCG_CALL_NO_RWG_SE, i64, env, i64)
49
+DEF_HELPER_FLAGS_2(xpacd, TCG_CALL_NO_RWG_SE, i64, env, i64)
50
diff --git a/target/arm/internals.h b/target/arm/internals.h
51
index XXXXXXX..XXXXXXX 100644
52
--- a/target/arm/internals.h
53
+++ b/target/arm/internals.h
54
@@ -XXX,XX +XXX,XX @@ enum arm_exception_class {
55
EC_CP14DTTRAP = 0x06,
56
EC_ADVSIMDFPACCESSTRAP = 0x07,
57
EC_FPIDTRAP = 0x08,
58
+ EC_PACTRAP = 0x09,
59
EC_CP14RRTTRAP = 0x0c,
60
EC_ILLEGALSTATE = 0x0e,
61
EC_AA32_SVC = 0x11,
62
@@ -XXX,XX +XXX,XX @@ static inline uint32_t syn_sve_access_trap(void)
63
return EC_SVEACCESSTRAP << ARM_EL_EC_SHIFT;
64
}
65
66
+static inline uint32_t syn_pactrap(void)
67
+{
68
+ return EC_PACTRAP << ARM_EL_EC_SHIFT;
69
+}
70
+
71
static inline uint32_t syn_insn_abort(int same_el, int ea, int s1ptw, int fsc)
72
{
73
return (EC_INSNABORT << ARM_EL_EC_SHIFT) | (same_el << ARM_EL_EC_SHIFT)
74
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
75
new file mode 100644
76
index XXXXXXX..XXXXXXX
77
--- /dev/null
78
+++ b/target/arm/pauth_helper.c
79
@@ -XXX,XX +XXX,XX @@
80
+/*
81
+ * ARM v8.3-PAuth Operations
82
+ *
83
+ * Copyright (c) 2019 Linaro, Ltd.
84
+ *
85
+ * This library is free software; you can redistribute it and/or
86
+ * modify it under the terms of the GNU Lesser General Public
87
+ * License as published by the Free Software Foundation; either
88
+ * version 2 of the License, or (at your option) any later version.
89
+ *
90
+ * This library is distributed in the hope that it will be useful,
91
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
92
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
93
+ * Lesser General Public License for more details.
94
+ *
95
+ * You should have received a copy of the GNU Lesser General Public
96
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
97
+ */
98
+
99
+#include "qemu/osdep.h"
100
+#include "cpu.h"
101
+#include "internals.h"
102
+#include "exec/exec-all.h"
103
+#include "exec/cpu_ldst.h"
104
+#include "exec/helper-proto.h"
105
+#include "tcg/tcg-gvec-desc.h"
106
+
107
+
108
+static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
109
+ ARMPACKey key)
110
+{
111
+ g_assert_not_reached(); /* FIXME */
112
+}
113
+
114
+static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
115
+ ARMPACKey *key, bool data)
116
+{
117
+ g_assert_not_reached(); /* FIXME */
118
+}
119
+
120
+static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
121
+ ARMPACKey *key, bool data, int keynumber)
122
+{
123
+ g_assert_not_reached(); /* FIXME */
124
+}
125
+
126
+static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
127
+{
128
+ g_assert_not_reached(); /* FIXME */
129
+}
130
+
131
+static void QEMU_NORETURN pauth_trap(CPUARMState *env, int target_el,
132
+ uintptr_t ra)
133
+{
134
+ raise_exception_ra(env, EXCP_UDEF, syn_pactrap(), target_el, ra);
135
+}
136
+
137
+static void pauth_check_trap(CPUARMState *env, int el, uintptr_t ra)
138
+{
139
+ if (el < 2 && arm_feature(env, ARM_FEATURE_EL2)) {
140
+ uint64_t hcr = arm_hcr_el2_eff(env);
141
+ bool trap = !(hcr & HCR_API);
142
+ /* FIXME: ARMv8.1-VHE: trap only applies to EL1&0 regime. */
143
+ /* FIXME: ARMv8.3-NV: HCR_NV trap takes precedence for ERETA[AB]. */
144
+ if (trap) {
145
+ pauth_trap(env, 2, ra);
146
+ }
147
+ }
148
+ if (el < 3 && arm_feature(env, ARM_FEATURE_EL3)) {
149
+ if (!(env->cp15.scr_el3 & SCR_API)) {
150
+ pauth_trap(env, 3, ra);
151
+ }
152
+ }
153
+}
154
+
155
+static bool pauth_key_enabled(CPUARMState *env, int el, uint32_t bit)
156
+{
157
+ uint32_t sctlr;
158
+ if (el == 0) {
159
+ /* FIXME: ARMv8.1-VHE S2 translation regime. */
160
+ sctlr = env->cp15.sctlr_el[1];
161
+ } else {
162
+ sctlr = env->cp15.sctlr_el[el];
163
+ }
164
+ return (sctlr & bit) != 0;
165
+}
166
+
167
+uint64_t HELPER(pacia)(CPUARMState *env, uint64_t x, uint64_t y)
168
+{
169
+ int el = arm_current_el(env);
170
+ if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
171
+ return x;
172
+ }
173
+ pauth_check_trap(env, el, GETPC());
174
+ return pauth_addpac(env, x, y, &env->apia_key, false);
175
+}
176
+
177
+uint64_t HELPER(pacib)(CPUARMState *env, uint64_t x, uint64_t y)
178
+{
179
+ int el = arm_current_el(env);
180
+ if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
181
+ return x;
182
+ }
183
+ pauth_check_trap(env, el, GETPC());
184
+ return pauth_addpac(env, x, y, &env->apib_key, false);
185
+}
186
+
187
+uint64_t HELPER(pacda)(CPUARMState *env, uint64_t x, uint64_t y)
188
+{
189
+ int el = arm_current_el(env);
190
+ if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
191
+ return x;
192
+ }
193
+ pauth_check_trap(env, el, GETPC());
194
+ return pauth_addpac(env, x, y, &env->apda_key, true);
195
+}
196
+
197
+uint64_t HELPER(pacdb)(CPUARMState *env, uint64_t x, uint64_t y)
198
+{
199
+ int el = arm_current_el(env);
200
+ if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
201
+ return x;
202
+ }
203
+ pauth_check_trap(env, el, GETPC());
204
+ return pauth_addpac(env, x, y, &env->apdb_key, true);
205
+}
206
+
207
+uint64_t HELPER(pacga)(CPUARMState *env, uint64_t x, uint64_t y)
208
+{
209
+ uint64_t pac;
210
+
211
+ pauth_check_trap(env, arm_current_el(env), GETPC());
212
+ pac = pauth_computepac(x, y, env->apga_key);
213
+
214
+ return pac & 0xffffffff00000000ull;
215
+}
216
+
217
+uint64_t HELPER(autia)(CPUARMState *env, uint64_t x, uint64_t y)
218
+{
219
+ int el = arm_current_el(env);
220
+ if (!pauth_key_enabled(env, el, SCTLR_EnIA)) {
221
+ return x;
222
+ }
223
+ pauth_check_trap(env, el, GETPC());
224
+ return pauth_auth(env, x, y, &env->apia_key, false, 0);
225
+}
226
+
227
+uint64_t HELPER(autib)(CPUARMState *env, uint64_t x, uint64_t y)
228
+{
229
+ int el = arm_current_el(env);
230
+ if (!pauth_key_enabled(env, el, SCTLR_EnIB)) {
231
+ return x;
232
+ }
233
+ pauth_check_trap(env, el, GETPC());
234
+ return pauth_auth(env, x, y, &env->apib_key, false, 1);
235
+}
236
+
237
+uint64_t HELPER(autda)(CPUARMState *env, uint64_t x, uint64_t y)
238
+{
239
+ int el = arm_current_el(env);
240
+ if (!pauth_key_enabled(env, el, SCTLR_EnDA)) {
241
+ return x;
242
+ }
243
+ pauth_check_trap(env, el, GETPC());
244
+ return pauth_auth(env, x, y, &env->apda_key, true, 0);
245
+}
246
+
247
+uint64_t HELPER(autdb)(CPUARMState *env, uint64_t x, uint64_t y)
248
+{
249
+ int el = arm_current_el(env);
250
+ if (!pauth_key_enabled(env, el, SCTLR_EnDB)) {
251
+ return x;
252
+ }
253
+ pauth_check_trap(env, el, GETPC());
254
+ return pauth_auth(env, x, y, &env->apdb_key, true, 1);
255
+}
256
+
257
+uint64_t HELPER(xpaci)(CPUARMState *env, uint64_t a)
258
+{
259
+ return pauth_strip(env, a, false);
260
+}
261
+
262
+uint64_t HELPER(xpacd)(CPUARMState *env, uint64_t a)
263
+{
264
+ return pauth_strip(env, a, true);
265
+}
266
--
267
2.20.1
268
269
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Now properly signals unallocated for REV64 with SF=0.
4
Allows for the opcode2 field to be decoded shortly.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-8-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/translate-a64.c | 31 ++++++++++++++++++++++---------
12
1 file changed, 22 insertions(+), 9 deletions(-)
13
14
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/translate-a64.c
17
+++ b/target/arm/translate-a64.c
18
@@ -XXX,XX +XXX,XX @@ static void handle_rev16(DisasContext *s, unsigned int sf,
19
*/
20
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
21
{
22
- unsigned int sf, opcode, rn, rd;
23
+ unsigned int sf, opcode, opcode2, rn, rd;
24
25
- if (extract32(insn, 29, 1) || extract32(insn, 16, 5)) {
26
+ if (extract32(insn, 29, 1)) {
27
unallocated_encoding(s);
28
return;
29
}
30
31
sf = extract32(insn, 31, 1);
32
opcode = extract32(insn, 10, 6);
33
+ opcode2 = extract32(insn, 16, 5);
34
rn = extract32(insn, 5, 5);
35
rd = extract32(insn, 0, 5);
36
37
- switch (opcode) {
38
- case 0: /* RBIT */
39
+#define MAP(SF, O2, O1) ((SF) | (O1 << 1) | (O2 << 7))
40
+
41
+ switch (MAP(sf, opcode2, opcode)) {
42
+ case MAP(0, 0x00, 0x00): /* RBIT */
43
+ case MAP(1, 0x00, 0x00):
44
handle_rbit(s, sf, rn, rd);
45
break;
46
- case 1: /* REV16 */
47
+ case MAP(0, 0x00, 0x01): /* REV16 */
48
+ case MAP(1, 0x00, 0x01):
49
handle_rev16(s, sf, rn, rd);
50
break;
51
- case 2: /* REV32 */
52
+ case MAP(0, 0x00, 0x02): /* REV/REV32 */
53
+ case MAP(1, 0x00, 0x02):
54
handle_rev32(s, sf, rn, rd);
55
break;
56
- case 3: /* REV64 */
57
+ case MAP(1, 0x00, 0x03): /* REV64 */
58
handle_rev64(s, sf, rn, rd);
59
break;
60
- case 4: /* CLZ */
61
+ case MAP(0, 0x00, 0x04): /* CLZ */
62
+ case MAP(1, 0x00, 0x04):
63
handle_clz(s, sf, rn, rd);
64
break;
65
- case 5: /* CLS */
66
+ case MAP(0, 0x00, 0x05): /* CLS */
67
+ case MAP(1, 0x00, 0x05):
68
handle_cls(s, sf, rn, rd);
69
break;
70
+ default:
71
+ unallocated_encoding(s);
72
+ break;
73
}
74
+
75
+#undef MAP
76
}
77
78
static void handle_div(DisasContext *s, bool is_signed, unsigned int sf,
79
--
80
2.20.1
81
82
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-9-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 146 +++++++++++++++++++++++++++++++++++++
9
1 file changed, 146 insertions(+)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void handle_rev16(DisasContext *s, unsigned int sf,
16
static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
17
{
18
unsigned int sf, opcode, opcode2, rn, rd;
19
+ TCGv_i64 tcg_rd;
20
21
if (extract32(insn, 29, 1)) {
22
unallocated_encoding(s);
23
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_1src(DisasContext *s, uint32_t insn)
24
case MAP(1, 0x00, 0x05):
25
handle_cls(s, sf, rn, rd);
26
break;
27
+ case MAP(1, 0x01, 0x00): /* PACIA */
28
+ if (s->pauth_active) {
29
+ tcg_rd = cpu_reg(s, rd);
30
+ gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
31
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
32
+ goto do_unallocated;
33
+ }
34
+ break;
35
+ case MAP(1, 0x01, 0x01): /* PACIB */
36
+ if (s->pauth_active) {
37
+ tcg_rd = cpu_reg(s, rd);
38
+ gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
39
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
40
+ goto do_unallocated;
41
+ }
42
+ break;
43
+ case MAP(1, 0x01, 0x02): /* PACDA */
44
+ if (s->pauth_active) {
45
+ tcg_rd = cpu_reg(s, rd);
46
+ gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
47
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
48
+ goto do_unallocated;
49
+ }
50
+ break;
51
+ case MAP(1, 0x01, 0x03): /* PACDB */
52
+ if (s->pauth_active) {
53
+ tcg_rd = cpu_reg(s, rd);
54
+ gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
55
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
56
+ goto do_unallocated;
57
+ }
58
+ break;
59
+ case MAP(1, 0x01, 0x04): /* AUTIA */
60
+ if (s->pauth_active) {
61
+ tcg_rd = cpu_reg(s, rd);
62
+ gen_helper_autia(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
63
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
64
+ goto do_unallocated;
65
+ }
66
+ break;
67
+ case MAP(1, 0x01, 0x05): /* AUTIB */
68
+ if (s->pauth_active) {
69
+ tcg_rd = cpu_reg(s, rd);
70
+ gen_helper_autib(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
71
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
72
+ goto do_unallocated;
73
+ }
74
+ break;
75
+ case MAP(1, 0x01, 0x06): /* AUTDA */
76
+ if (s->pauth_active) {
77
+ tcg_rd = cpu_reg(s, rd);
78
+ gen_helper_autda(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
79
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
80
+ goto do_unallocated;
81
+ }
82
+ break;
83
+ case MAP(1, 0x01, 0x07): /* AUTDB */
84
+ if (s->pauth_active) {
85
+ tcg_rd = cpu_reg(s, rd);
86
+ gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, cpu_reg_sp(s, rn));
87
+ } else if (!dc_isar_feature(aa64_pauth, s)) {
88
+ goto do_unallocated;
89
+ }
90
+ break;
91
+ case MAP(1, 0x01, 0x08): /* PACIZA */
92
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
93
+ goto do_unallocated;
94
+ } else if (s->pauth_active) {
95
+ tcg_rd = cpu_reg(s, rd);
96
+ gen_helper_pacia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
97
+ }
98
+ break;
99
+ case MAP(1, 0x01, 0x09): /* PACIZB */
100
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
101
+ goto do_unallocated;
102
+ } else if (s->pauth_active) {
103
+ tcg_rd = cpu_reg(s, rd);
104
+ gen_helper_pacib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
105
+ }
106
+ break;
107
+ case MAP(1, 0x01, 0x0a): /* PACDZA */
108
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
109
+ goto do_unallocated;
110
+ } else if (s->pauth_active) {
111
+ tcg_rd = cpu_reg(s, rd);
112
+ gen_helper_pacda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
113
+ }
114
+ break;
115
+ case MAP(1, 0x01, 0x0b): /* PACDZB */
116
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
117
+ goto do_unallocated;
118
+ } else if (s->pauth_active) {
119
+ tcg_rd = cpu_reg(s, rd);
120
+ gen_helper_pacdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
121
+ }
122
+ break;
123
+ case MAP(1, 0x01, 0x0c): /* AUTIZA */
124
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
125
+ goto do_unallocated;
126
+ } else if (s->pauth_active) {
127
+ tcg_rd = cpu_reg(s, rd);
128
+ gen_helper_autia(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
129
+ }
130
+ break;
131
+ case MAP(1, 0x01, 0x0d): /* AUTIZB */
132
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
133
+ goto do_unallocated;
134
+ } else if (s->pauth_active) {
135
+ tcg_rd = cpu_reg(s, rd);
136
+ gen_helper_autib(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
137
+ }
138
+ break;
139
+ case MAP(1, 0x01, 0x0e): /* AUTDZA */
140
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
141
+ goto do_unallocated;
142
+ } else if (s->pauth_active) {
143
+ tcg_rd = cpu_reg(s, rd);
144
+ gen_helper_autda(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
145
+ }
146
+ break;
147
+ case MAP(1, 0x01, 0x0f): /* AUTDZB */
148
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
149
+ goto do_unallocated;
150
+ } else if (s->pauth_active) {
151
+ tcg_rd = cpu_reg(s, rd);
152
+ gen_helper_autdb(tcg_rd, cpu_env, tcg_rd, new_tmp_a64_zero(s));
153
+ }
154
+ break;
155
+ case MAP(1, 0x01, 0x10): /* XPACI */
156
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
157
+ goto do_unallocated;
158
+ } else if (s->pauth_active) {
159
+ tcg_rd = cpu_reg(s, rd);
160
+ gen_helper_xpaci(tcg_rd, cpu_env, tcg_rd);
161
+ }
162
+ break;
163
+ case MAP(1, 0x01, 0x11): /* XPACD */
164
+ if (!dc_isar_feature(aa64_pauth, s) || rn != 31) {
165
+ goto do_unallocated;
166
+ } else if (s->pauth_active) {
167
+ tcg_rd = cpu_reg(s, rd);
168
+ gen_helper_xpacd(tcg_rd, cpu_env, tcg_rd);
169
+ }
170
+ break;
171
default:
172
+ do_unallocated:
173
unallocated_encoding(s);
174
break;
175
}
176
--
177
2.20.1
178
179
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-10-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 8 ++++++++
9
1 file changed, 8 insertions(+)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
16
case 11: /* RORV */
17
handle_shift_reg(s, A64_SHIFT_TYPE_ROR, sf, rm, rn, rd);
18
break;
19
+ case 12: /* PACGA */
20
+ if (sf == 0 || !dc_isar_feature(aa64_pauth, s)) {
21
+ goto do_unallocated;
22
+ }
23
+ gen_helper_pacga(cpu_reg(s, rd), cpu_env,
24
+ cpu_reg(s, rn), cpu_reg_sp(s, rm));
25
+ break;
26
case 16:
27
case 17:
28
case 18:
29
@@ -XXX,XX +XXX,XX @@ static void disas_data_proc_2src(DisasContext *s, uint32_t insn)
30
break;
31
}
32
default:
33
+ do_unallocated:
34
unallocated_encoding(s);
35
break;
36
}
37
--
38
2.20.1
39
40
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-12-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/helper-a64.h | 2 +-
9
target/arm/helper-a64.c | 10 +++++-----
10
target/arm/translate-a64.c | 7 ++++++-
11
3 files changed, 12 insertions(+), 7 deletions(-)
12
13
diff --git a/target/arm/helper-a64.h b/target/arm/helper-a64.h
14
index XXXXXXX..XXXXXXX 100644
15
--- a/target/arm/helper-a64.h
16
+++ b/target/arm/helper-a64.h
17
@@ -XXX,XX +XXX,XX @@ DEF_HELPER_2(advsimd_f16tosinth, i32, f16, ptr)
18
DEF_HELPER_2(advsimd_f16touinth, i32, f16, ptr)
19
DEF_HELPER_2(sqrt_f16, f16, f16, ptr)
20
21
-DEF_HELPER_1(exception_return, void, env)
22
+DEF_HELPER_2(exception_return, void, env, i64)
23
24
DEF_HELPER_FLAGS_3(pacia, TCG_CALL_NO_WG, i64, env, i64, i64)
25
DEF_HELPER_FLAGS_3(pacib, TCG_CALL_NO_WG, i64, env, i64, i64)
26
diff --git a/target/arm/helper-a64.c b/target/arm/helper-a64.c
27
index XXXXXXX..XXXXXXX 100644
28
--- a/target/arm/helper-a64.c
29
+++ b/target/arm/helper-a64.c
30
@@ -XXX,XX +XXX,XX @@ static int el_from_spsr(uint32_t spsr)
31
}
32
}
33
34
-void HELPER(exception_return)(CPUARMState *env)
35
+void HELPER(exception_return)(CPUARMState *env, uint64_t new_pc)
36
{
37
int cur_el = arm_current_el(env);
38
unsigned int spsr_idx = aarch64_banked_spsr_index(cur_el);
39
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env)
40
aarch64_sync_64_to_32(env);
41
42
if (spsr & CPSR_T) {
43
- env->regs[15] = env->elr_el[cur_el] & ~0x1;
44
+ env->regs[15] = new_pc & ~0x1;
45
} else {
46
- env->regs[15] = env->elr_el[cur_el] & ~0x3;
47
+ env->regs[15] = new_pc & ~0x3;
48
}
49
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
50
"AArch32 EL%d PC 0x%" PRIx32 "\n",
51
@@ -XXX,XX +XXX,XX @@ void HELPER(exception_return)(CPUARMState *env)
52
env->pstate &= ~PSTATE_SS;
53
}
54
aarch64_restore_sp(env, new_el);
55
- env->pc = env->elr_el[cur_el];
56
+ env->pc = new_pc;
57
qemu_log_mask(CPU_LOG_INT, "Exception return from AArch64 EL%d to "
58
"AArch64 EL%d PC 0x%" PRIx64 "\n",
59
cur_el, new_el, env->pc);
60
@@ -XXX,XX +XXX,XX @@ illegal_return:
61
* no change to exception level, execution state or stack pointer
62
*/
63
env->pstate |= PSTATE_IL;
64
- env->pc = env->elr_el[cur_el];
65
+ env->pc = new_pc;
66
spsr &= PSTATE_NZCV | PSTATE_DAIF;
67
spsr |= pstate_read(env) & ~(PSTATE_NZCV | PSTATE_DAIF);
68
pstate_write(env, spsr);
69
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
70
index XXXXXXX..XXXXXXX 100644
71
--- a/target/arm/translate-a64.c
72
+++ b/target/arm/translate-a64.c
73
@@ -XXX,XX +XXX,XX @@ static void disas_exc(DisasContext *s, uint32_t insn)
74
static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
75
{
76
unsigned int opc, op2, op3, rn, op4;
77
+ TCGv_i64 dst;
78
79
opc = extract32(insn, 21, 4);
80
op2 = extract32(insn, 16, 5);
81
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
82
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
83
gen_io_start();
84
}
85
- gen_helper_exception_return(cpu_env);
86
+ dst = tcg_temp_new_i64();
87
+ tcg_gen_ld_i64(dst, cpu_env,
88
+ offsetof(CPUARMState, elr_el[s->current_el]));
89
+ gen_helper_exception_return(cpu_env, dst);
90
+ tcg_temp_free_i64(dst);
91
if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
92
gen_io_end();
93
}
94
--
95
2.20.1
96
97
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
4
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
5
Message-id: 20190108223129.5570-14-richard.henderson@linaro.org
6
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
7
---
8
target/arm/translate-a64.c | 82 +++++++++++++++++++++++++++++++++++++-
9
1 file changed, 81 insertions(+), 1 deletion(-)
10
11
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/target/arm/translate-a64.c
14
+++ b/target/arm/translate-a64.c
15
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
16
{
17
unsigned int opc, op2, op3, rn, op4;
18
TCGv_i64 dst;
19
+ TCGv_i64 modifier;
20
21
opc = extract32(insn, 21, 4);
22
op2 = extract32(insn, 16, 5);
23
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
24
case 2: /* RET */
25
switch (op3) {
26
case 0:
27
+ /* BR, BLR, RET */
28
if (op4 != 0) {
29
goto do_unallocated;
30
}
31
dst = cpu_reg(s, rn);
32
break;
33
34
+ case 2:
35
+ case 3:
36
+ if (!dc_isar_feature(aa64_pauth, s)) {
37
+ goto do_unallocated;
38
+ }
39
+ if (opc == 2) {
40
+ /* RETAA, RETAB */
41
+ if (rn != 0x1f || op4 != 0x1f) {
42
+ goto do_unallocated;
43
+ }
44
+ rn = 30;
45
+ modifier = cpu_X[31];
46
+ } else {
47
+ /* BRAAZ, BRABZ, BLRAAZ, BLRABZ */
48
+ if (op4 != 0x1f) {
49
+ goto do_unallocated;
50
+ }
51
+ modifier = new_tmp_a64_zero(s);
52
+ }
53
+ if (s->pauth_active) {
54
+ dst = new_tmp_a64(s);
55
+ if (op3 == 2) {
56
+ gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
57
+ } else {
58
+ gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
59
+ }
60
+ } else {
61
+ dst = cpu_reg(s, rn);
62
+ }
63
+ break;
64
+
65
default:
66
goto do_unallocated;
67
}
68
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
69
}
70
break;
71
72
+ case 8: /* BRAA */
73
+ case 9: /* BLRAA */
74
+ if (!dc_isar_feature(aa64_pauth, s)) {
75
+ goto do_unallocated;
76
+ }
77
+ if (op3 != 2 || op3 != 3) {
78
+ goto do_unallocated;
79
+ }
80
+ if (s->pauth_active) {
81
+ dst = new_tmp_a64(s);
82
+ modifier = cpu_reg_sp(s, op4);
83
+ if (op3 == 2) {
84
+ gen_helper_autia(dst, cpu_env, cpu_reg(s, rn), modifier);
85
+ } else {
86
+ gen_helper_autib(dst, cpu_env, cpu_reg(s, rn), modifier);
87
+ }
88
+ } else {
89
+ dst = cpu_reg(s, rn);
90
+ }
91
+ gen_a64_set_pc(s, dst);
92
+ /* BLRAA also needs to load return address */
93
+ if (opc == 9) {
94
+ tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
95
+ }
96
+ break;
97
+
98
case 4: /* ERET */
99
if (s->current_el == 0) {
100
goto do_unallocated;
101
}
102
switch (op3) {
103
- case 0:
104
+ case 0: /* ERET */
105
if (op4 != 0) {
106
goto do_unallocated;
107
}
108
@@ -XXX,XX +XXX,XX @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
109
offsetof(CPUARMState, elr_el[s->current_el]));
110
break;
111
112
+ case 2: /* ERETAA */
113
+ case 3: /* ERETAB */
114
+ if (!dc_isar_feature(aa64_pauth, s)) {
115
+ goto do_unallocated;
116
+ }
117
+ if (rn != 0x1f || op4 != 0x1f) {
118
+ goto do_unallocated;
119
+ }
120
+ dst = tcg_temp_new_i64();
121
+ tcg_gen_ld_i64(dst, cpu_env,
122
+ offsetof(CPUARMState, elr_el[s->current_el]));
123
+ if (s->pauth_active) {
124
+ modifier = cpu_X[31];
125
+ if (op3 == 2) {
126
+ gen_helper_autia(dst, cpu_env, dst, modifier);
127
+ } else {
128
+ gen_helper_autib(dst, cpu_env, dst, modifier);
129
+ }
130
+ }
131
+ break;
132
+
133
default:
134
goto do_unallocated;
135
}
136
--
137
2.20.1
138
139
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
Not that there are any stores involved, but why argue with ARM's
4
naming convention.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-15-richard.henderson@linaro.org
9
[fixed trivial comment nit]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/translate-a64.c | 61 ++++++++++++++++++++++++++++++++++++++
13
1 file changed, 61 insertions(+)
14
15
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/translate-a64.c
18
+++ b/target/arm/translate-a64.c
19
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_atomic(DisasContext *s, uint32_t insn,
20
s->be_data | size | MO_ALIGN);
21
}
22
23
+/*
24
+ * PAC memory operations
25
+ *
26
+ * 31 30 27 26 24 22 21 12 11 10 5 0
27
+ * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
28
+ * | size | 1 1 1 | V | 0 0 | M S | 1 | imm9 | W | 1 | Rn | Rt |
29
+ * +------+-------+---+-----+-----+---+--------+---+---+----+-----+
30
+ *
31
+ * Rt: the result register
32
+ * Rn: base address or SP
33
+ * V: vector flag (always 0 as of v8.3)
34
+ * M: clear for key DA, set for key DB
35
+ * W: pre-indexing flag
36
+ * S: sign for imm9.
37
+ */
38
+static void disas_ldst_pac(DisasContext *s, uint32_t insn,
39
+ int size, int rt, bool is_vector)
40
+{
41
+ int rn = extract32(insn, 5, 5);
42
+ bool is_wback = extract32(insn, 11, 1);
43
+ bool use_key_a = !extract32(insn, 23, 1);
44
+ int offset;
45
+ TCGv_i64 tcg_addr, tcg_rt;
46
+
47
+ if (size != 3 || is_vector || !dc_isar_feature(aa64_pauth, s)) {
48
+ unallocated_encoding(s);
49
+ return;
50
+ }
51
+
52
+ if (rn == 31) {
53
+ gen_check_sp_alignment(s);
54
+ }
55
+ tcg_addr = read_cpu_reg_sp(s, rn, 1);
56
+
57
+ if (s->pauth_active) {
58
+ if (use_key_a) {
59
+ gen_helper_autda(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
60
+ } else {
61
+ gen_helper_autdb(tcg_addr, cpu_env, tcg_addr, cpu_X[31]);
62
+ }
63
+ }
64
+
65
+ /* Form the 10-bit signed, scaled offset. */
66
+ offset = (extract32(insn, 22, 1) << 9) | extract32(insn, 12, 9);
67
+ offset = sextract32(offset << size, 0, 10 + size);
68
+ tcg_gen_addi_i64(tcg_addr, tcg_addr, offset);
69
+
70
+ tcg_rt = cpu_reg(s, rt);
71
+
72
+ do_gpr_ld(s, tcg_rt, tcg_addr, size, /* is_signed */ false,
73
+ /* extend */ false, /* iss_valid */ !is_wback,
74
+ /* iss_srt */ rt, /* iss_sf */ true, /* iss_ar */ false);
75
+
76
+ if (is_wback) {
77
+ tcg_gen_mov_i64(cpu_reg_sp(s, rn), tcg_addr);
78
+ }
79
+}
80
+
81
/* Load/store register (all forms) */
82
static void disas_ldst_reg(DisasContext *s, uint32_t insn)
83
{
84
@@ -XXX,XX +XXX,XX @@ static void disas_ldst_reg(DisasContext *s, uint32_t insn)
85
case 2:
86
disas_ldst_reg_roffset(s, insn, opc, size, rt, is_vector);
87
return;
88
+ default:
89
+ disas_ldst_pac(s, insn, size, rt, is_vector);
90
+ return;
91
}
92
break;
93
case 1:
94
--
95
2.20.1
96
97
diff view generated by jsdifflib
1
From: Richard Henderson <richard.henderson@linaro.org>
1
From: Stephen Longfield <slongfield@google.com>
2
2
3
Split out functions to extract the virtual address parameters.
3
Size is used at lines 1088/1188 for the loop, which reads the last 4
4
Let the functions choose T0 or T1 address space half, if present.
4
bytes from the crc_ptr so it does need to get increased, however it
5
Extract (most of) the control bits that vary between EL or Tx.
5
shouldn't be increased before the buffer is passed to CRC computation,
6
or the crc32 function will access uninitialized memory.
6
7
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
This was pointed out to me by clg@kaod.org during the code review of
9
a similar patch to hw/net/ftgmac100.c
10
11
Change-Id: Ib0464303b191af1e28abeb2f5105eb25aadb5e9b
12
Signed-off-by: Stephen Longfield <slongfield@google.com>
13
Reviewed-by: Patrick Venture <venture@google.com>
14
Message-id: 20221221183202.3788132-1-slongfield@google.com
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
15
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190108223129.5570-19-richard.henderson@linaro.org
10
[PMM: fixed minor checkpatch comment nits]
11
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
16
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
12
---
17
---
13
target/arm/internals.h | 14 +++
18
hw/net/imx_fec.c | 8 ++++----
14
target/arm/helper.c | 278 ++++++++++++++++++++++-------------------
19
1 file changed, 4 insertions(+), 4 deletions(-)
15
2 files changed, 164 insertions(+), 128 deletions(-)
16
20
17
diff --git a/target/arm/internals.h b/target/arm/internals.h
21
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
18
index XXXXXXX..XXXXXXX 100644
22
index XXXXXXX..XXXXXXX 100644
19
--- a/target/arm/internals.h
23
--- a/hw/net/imx_fec.c
20
+++ b/target/arm/internals.h
24
+++ b/hw/net/imx_fec.c
21
@@ -XXX,XX +XXX,XX @@ static inline ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env)
25
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_fec_receive(NetClientState *nc, const uint8_t *buf,
22
ARMMMUIdx arm_stage1_mmu_idx(CPUARMState *env);
26
return 0;
23
#endif
24
25
+/*
26
+ * Parameters of a given virtual address, as extracted from the
27
+ * translation control register (TCR) for a given regime.
28
+ */
29
+typedef struct ARMVAParameters {
30
+ unsigned tsz : 8;
31
+ unsigned select : 1;
32
+ bool tbi : 1;
33
+ bool epd : 1;
34
+ bool hpd : 1;
35
+ bool using16k : 1;
36
+ bool using64k : 1;
37
+} ARMVAParameters;
38
+
39
#endif
40
diff --git a/target/arm/helper.c b/target/arm/helper.c
41
index XXXXXXX..XXXXXXX 100644
42
--- a/target/arm/helper.c
43
+++ b/target/arm/helper.c
44
@@ -XXX,XX +XXX,XX @@ static uint8_t convert_stage2_attrs(CPUARMState *env, uint8_t s2attrs)
45
return (hiattr << 6) | (hihint << 4) | (loattr << 2) | lohint;
46
}
47
48
+static ARMVAParameters aa64_va_parameters(CPUARMState *env, uint64_t va,
49
+ ARMMMUIdx mmu_idx, bool data)
50
+{
51
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
52
+ uint32_t el = regime_el(env, mmu_idx);
53
+ bool tbi, epd, hpd, using16k, using64k;
54
+ int select, tsz;
55
+
56
+ /*
57
+ * Bit 55 is always between the two regions, and is canonical for
58
+ * determining if address tagging is enabled.
59
+ */
60
+ select = extract64(va, 55, 1);
61
+
62
+ if (el > 1) {
63
+ tsz = extract32(tcr, 0, 6);
64
+ using64k = extract32(tcr, 14, 1);
65
+ using16k = extract32(tcr, 15, 1);
66
+ if (mmu_idx == ARMMMUIdx_S2NS) {
67
+ /* VTCR_EL2 */
68
+ tbi = hpd = false;
69
+ } else {
70
+ tbi = extract32(tcr, 20, 1);
71
+ hpd = extract32(tcr, 24, 1);
72
+ }
73
+ epd = false;
74
+ } else if (!select) {
75
+ tsz = extract32(tcr, 0, 6);
76
+ epd = extract32(tcr, 7, 1);
77
+ using64k = extract32(tcr, 14, 1);
78
+ using16k = extract32(tcr, 15, 1);
79
+ tbi = extract64(tcr, 37, 1);
80
+ hpd = extract64(tcr, 41, 1);
81
+ } else {
82
+ int tg = extract32(tcr, 30, 2);
83
+ using16k = tg == 1;
84
+ using64k = tg == 3;
85
+ tsz = extract32(tcr, 16, 6);
86
+ epd = extract32(tcr, 23, 1);
87
+ tbi = extract64(tcr, 38, 1);
88
+ hpd = extract64(tcr, 42, 1);
89
+ }
90
+ tsz = MIN(tsz, 39); /* TODO: ARMv8.4-TTST */
91
+ tsz = MAX(tsz, 16); /* TODO: ARMv8.2-LVA */
92
+
93
+ return (ARMVAParameters) {
94
+ .tsz = tsz,
95
+ .select = select,
96
+ .tbi = tbi,
97
+ .epd = epd,
98
+ .hpd = hpd,
99
+ .using16k = using16k,
100
+ .using64k = using64k,
101
+ };
102
+}
103
+
104
+static ARMVAParameters aa32_va_parameters(CPUARMState *env, uint32_t va,
105
+ ARMMMUIdx mmu_idx)
106
+{
107
+ uint64_t tcr = regime_tcr(env, mmu_idx)->raw_tcr;
108
+ uint32_t el = regime_el(env, mmu_idx);
109
+ int select, tsz;
110
+ bool epd, hpd;
111
+
112
+ if (mmu_idx == ARMMMUIdx_S2NS) {
113
+ /* VTCR */
114
+ bool sext = extract32(tcr, 4, 1);
115
+ bool sign = extract32(tcr, 3, 1);
116
+
117
+ /*
118
+ * If the sign-extend bit is not the same as t0sz[3], the result
119
+ * is unpredictable. Flag this as a guest error.
120
+ */
121
+ if (sign != sext) {
122
+ qemu_log_mask(LOG_GUEST_ERROR,
123
+ "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
124
+ }
125
+ tsz = sextract32(tcr, 0, 4) + 8;
126
+ select = 0;
127
+ hpd = false;
128
+ epd = false;
129
+ } else if (el == 2) {
130
+ /* HTCR */
131
+ tsz = extract32(tcr, 0, 3);
132
+ select = 0;
133
+ hpd = extract64(tcr, 24, 1);
134
+ epd = false;
135
+ } else {
136
+ int t0sz = extract32(tcr, 0, 3);
137
+ int t1sz = extract32(tcr, 16, 3);
138
+
139
+ if (t1sz == 0) {
140
+ select = va > (0xffffffffu >> t0sz);
141
+ } else {
142
+ /* Note that we will detect errors later. */
143
+ select = va >= ~(0xffffffffu >> t1sz);
144
+ }
145
+ if (!select) {
146
+ tsz = t0sz;
147
+ epd = extract32(tcr, 7, 1);
148
+ hpd = extract64(tcr, 41, 1);
149
+ } else {
150
+ tsz = t1sz;
151
+ epd = extract32(tcr, 23, 1);
152
+ hpd = extract64(tcr, 42, 1);
153
+ }
154
+ /* For aarch32, hpd0 is not enabled without t2e as well. */
155
+ hpd &= extract32(tcr, 6, 1);
156
+ }
157
+
158
+ return (ARMVAParameters) {
159
+ .tsz = tsz,
160
+ .select = select,
161
+ .epd = epd,
162
+ .hpd = hpd,
163
+ };
164
+}
165
+
166
static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
167
MMUAccessType access_type, ARMMMUIdx mmu_idx,
168
hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,
169
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
170
/* Read an LPAE long-descriptor translation table. */
171
ARMFaultType fault_type = ARMFault_Translation;
172
uint32_t level;
173
- uint32_t epd = 0;
174
- int32_t t0sz, t1sz;
175
- uint32_t tg;
176
+ ARMVAParameters param;
177
uint64_t ttbr;
178
- int ttbr_select;
179
hwaddr descaddr, indexmask, indexmask_grainsize;
180
uint32_t tableattrs;
181
- target_ulong page_size;
182
+ target_ulong page_size, top_bits;
183
uint32_t attrs;
184
- int32_t stride = 9;
185
- int32_t addrsize;
186
- int inputsize;
187
- int32_t tbi = 0;
188
+ int32_t stride;
189
+ int addrsize, inputsize;
190
TCR *tcr = regime_tcr(env, mmu_idx);
191
int ap, ns, xn, pxn;
192
uint32_t el = regime_el(env, mmu_idx);
193
- bool ttbr1_valid = true;
194
+ bool ttbr1_valid;
195
uint64_t descaddrmask;
196
bool aarch64 = arm_el_is_aa64(env, el);
197
- bool hpd = false;
198
199
/* TODO:
200
* This code does not handle the different format TCR for VTCR_EL2.
201
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
202
* support for those page table walks.
203
*/
204
if (aarch64) {
205
+ param = aa64_va_parameters(env, address, mmu_idx,
206
+ access_type != MMU_INST_FETCH);
207
level = 0;
208
- addrsize = 64;
209
- if (el > 1) {
210
- if (mmu_idx != ARMMMUIdx_S2NS) {
211
- tbi = extract64(tcr->raw_tcr, 20, 1);
212
- }
213
- } else {
214
- if (extract64(address, 55, 1)) {
215
- tbi = extract64(tcr->raw_tcr, 38, 1);
216
- } else {
217
- tbi = extract64(tcr->raw_tcr, 37, 1);
218
- }
219
- }
220
- tbi *= 8;
221
-
222
/* If we are in 64-bit EL2 or EL3 then there is no TTBR1, so mark it
223
* invalid.
224
*/
225
- if (el > 1) {
226
- ttbr1_valid = false;
227
- }
228
+ ttbr1_valid = (el < 2);
229
+ addrsize = 64 - 8 * param.tbi;
230
+ inputsize = 64 - param.tsz;
231
} else {
232
+ param = aa32_va_parameters(env, address, mmu_idx);
233
level = 1;
234
- addrsize = 32;
235
/* There is no TTBR1 for EL2 */
236
- if (el == 2) {
237
- ttbr1_valid = false;
238
- }
239
+ ttbr1_valid = (el != 2);
240
+ addrsize = (mmu_idx == ARMMMUIdx_S2NS ? 40 : 32);
241
+ inputsize = addrsize - param.tsz;
242
}
27
}
243
28
244
- /* Determine whether this address is in the region controlled by
29
- /* 4 bytes for the CRC. */
245
- * TTBR0 or TTBR1 (or if it is in neither region and should fault).
30
- size += 4;
246
- * This is a Non-secure PL0/1 stage 1 translation, so controlled by
31
crc = cpu_to_be32(crc32(~0, buf, size));
247
- * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:
32
+ /* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
248
+ /*
33
+ size += 4;
249
+ * We determined the region when collecting the parameters, but we
34
crc_ptr = (uint8_t *) &crc;
250
+ * have not yet validated that the address is valid for the region.
35
251
+ * Extract the top bits and verify that they all match select.
36
/* Huge frames are truncated. */
252
*/
37
@@ -XXX,XX +XXX,XX @@ static ssize_t imx_enet_receive(NetClientState *nc, const uint8_t *buf,
253
- if (aarch64) {
38
return 0;
254
- /* AArch64 translation. */
255
- t0sz = extract32(tcr->raw_tcr, 0, 6);
256
- t0sz = MIN(t0sz, 39);
257
- t0sz = MAX(t0sz, 16);
258
- } else if (mmu_idx != ARMMMUIdx_S2NS) {
259
- /* AArch32 stage 1 translation. */
260
- t0sz = extract32(tcr->raw_tcr, 0, 3);
261
- } else {
262
- /* AArch32 stage 2 translation. */
263
- bool sext = extract32(tcr->raw_tcr, 4, 1);
264
- bool sign = extract32(tcr->raw_tcr, 3, 1);
265
- /* Address size is 40-bit for a stage 2 translation,
266
- * and t0sz can be negative (from -8 to 7),
267
- * so we need to adjust it to use the TTBR selecting logic below.
268
- */
269
- addrsize = 40;
270
- t0sz = sextract32(tcr->raw_tcr, 0, 4) + 8;
271
-
272
- /* If the sign-extend bit is not the same as t0sz[3], the result
273
- * is unpredictable. Flag this as a guest error. */
274
- if (sign != sext) {
275
- qemu_log_mask(LOG_GUEST_ERROR,
276
- "AArch32: VTCR.S / VTCR.T0SZ[3] mismatch\n");
277
- }
278
- }
279
- t1sz = extract32(tcr->raw_tcr, 16, 6);
280
- if (aarch64) {
281
- t1sz = MIN(t1sz, 39);
282
- t1sz = MAX(t1sz, 16);
283
- }
284
- if (t0sz && !extract64(address, addrsize - t0sz, t0sz - tbi)) {
285
- /* there is a ttbr0 region and we are in it (high bits all zero) */
286
- ttbr_select = 0;
287
- } else if (ttbr1_valid && t1sz &&
288
- !extract64(~address, addrsize - t1sz, t1sz - tbi)) {
289
- /* there is a ttbr1 region and we are in it (high bits all one) */
290
- ttbr_select = 1;
291
- } else if (!t0sz) {
292
- /* ttbr0 region is "everything not in the ttbr1 region" */
293
- ttbr_select = 0;
294
- } else if (!t1sz && ttbr1_valid) {
295
- /* ttbr1 region is "everything not in the ttbr0 region" */
296
- ttbr_select = 1;
297
- } else {
298
- /* in the gap between the two regions, this is a Translation fault */
299
+ top_bits = sextract64(address, inputsize, addrsize - inputsize);
300
+ if (-top_bits != param.select || (param.select && !ttbr1_valid)) {
301
+ /* In the gap between the two regions, this is a Translation fault */
302
fault_type = ARMFault_Translation;
303
goto do_fault;
304
}
39
}
305
40
306
+ if (param.using64k) {
41
- /* 4 bytes for the CRC. */
307
+ stride = 13;
42
- size += 4;
308
+ } else if (param.using16k) {
43
crc = cpu_to_be32(crc32(~0, buf, size));
309
+ stride = 11;
44
+ /* Increase size by 4, loop below reads the last 4 bytes from crc_ptr. */
310
+ } else {
45
+ size += 4;
311
+ stride = 9;
46
crc_ptr = (uint8_t *) &crc;
312
+ }
47
313
+
48
if (shift16) {
314
/* Note that QEMU ignores shareability and cacheability attributes,
315
* so we don't need to do anything with the SH, ORGN, IRGN fields
316
* in the TTBCR. Similarly, TTBCR:A1 selects whether we get the
317
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
318
* implement any ASID-like capability so we can ignore it (instead
319
* we will always flush the TLB any time the ASID is changed).
320
*/
321
- if (ttbr_select == 0) {
322
- ttbr = regime_ttbr(env, mmu_idx, 0);
323
- if (el < 2) {
324
- epd = extract32(tcr->raw_tcr, 7, 1);
325
- }
326
- inputsize = addrsize - t0sz;
327
-
328
- tg = extract32(tcr->raw_tcr, 14, 2);
329
- if (tg == 1) { /* 64KB pages */
330
- stride = 13;
331
- }
332
- if (tg == 2) { /* 16KB pages */
333
- stride = 11;
334
- }
335
- if (aarch64 && el > 1) {
336
- hpd = extract64(tcr->raw_tcr, 24, 1);
337
- } else {
338
- hpd = extract64(tcr->raw_tcr, 41, 1);
339
- }
340
- if (!aarch64) {
341
- /* For aarch32, hpd0 is not enabled without t2e as well. */
342
- hpd &= extract64(tcr->raw_tcr, 6, 1);
343
- }
344
- } else {
345
- /* We should only be here if TTBR1 is valid */
346
- assert(ttbr1_valid);
347
-
348
- ttbr = regime_ttbr(env, mmu_idx, 1);
349
- epd = extract32(tcr->raw_tcr, 23, 1);
350
- inputsize = addrsize - t1sz;
351
-
352
- tg = extract32(tcr->raw_tcr, 30, 2);
353
- if (tg == 3) { /* 64KB pages */
354
- stride = 13;
355
- }
356
- if (tg == 1) { /* 16KB pages */
357
- stride = 11;
358
- }
359
- hpd = extract64(tcr->raw_tcr, 42, 1);
360
- if (!aarch64) {
361
- /* For aarch32, hpd1 is not enabled without t2e as well. */
362
- hpd &= extract64(tcr->raw_tcr, 6, 1);
363
- }
364
- }
365
+ ttbr = regime_ttbr(env, mmu_idx, param.select);
366
367
/* Here we should have set up all the parameters for the translation:
368
* inputsize, ttbr, epd, stride, tbi
369
*/
370
371
- if (epd) {
372
+ if (param.epd) {
373
/* Translation table walk disabled => Translation fault on TLB miss
374
* Note: This is always 0 on 64-bit EL2 and EL3.
375
*/
376
@@ -XXX,XX +XXX,XX @@ static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,
377
}
378
/* Merge in attributes from table descriptors */
379
attrs |= nstable << 3; /* NS */
380
- if (hpd) {
381
+ if (param.hpd) {
382
/* HPD disables all the table attributes except NSTable. */
383
break;
384
}
385
--
49
--
386
2.20.1
50
2.25.1
387
388
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
We will shortly want to talk about TBI as it relates to data.
4
Passing around a pair of variables is less convenient than a
5
single variable.
6
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
9
Message-id: 20190108223129.5570-20-richard.henderson@linaro.org
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/cpu.h | 3 +--
13
target/arm/translate.h | 3 +--
14
target/arm/helper.c | 5 ++---
15
target/arm/translate-a64.c | 13 +++++++------
16
4 files changed, 11 insertions(+), 13 deletions(-)
17
18
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
19
index XXXXXXX..XXXXXXX 100644
20
--- a/target/arm/cpu.h
21
+++ b/target/arm/cpu.h
22
@@ -XXX,XX +XXX,XX @@ FIELD(TBFLAG_A32, HANDLER, 21, 1)
23
FIELD(TBFLAG_A32, STACKCHECK, 22, 1)
24
25
/* Bit usage when in AArch64 state */
26
-FIELD(TBFLAG_A64, TBI0, 0, 1)
27
-FIELD(TBFLAG_A64, TBI1, 1, 1)
28
+FIELD(TBFLAG_A64, TBII, 0, 2)
29
FIELD(TBFLAG_A64, SVEEXC_EL, 2, 2)
30
FIELD(TBFLAG_A64, ZCR_LEN, 4, 4)
31
FIELD(TBFLAG_A64, PAUTH_ACTIVE, 8, 1)
32
diff --git a/target/arm/translate.h b/target/arm/translate.h
33
index XXXXXXX..XXXXXXX 100644
34
--- a/target/arm/translate.h
35
+++ b/target/arm/translate.h
36
@@ -XXX,XX +XXX,XX @@ typedef struct DisasContext {
37
int user;
38
#endif
39
ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */
40
- bool tbi0; /* TBI0 for EL0/1 or TBI for EL2/3 */
41
- bool tbi1; /* TBI1 for EL0/1, not used for EL2/3 */
42
+ uint8_t tbii; /* TBI1|TBI0 for EL0/1 or TBI for EL2/3 */
43
bool ns; /* Use non-secure CPREG bank on access */
44
int fp_excp_el; /* FP exception EL or 0 if enabled */
45
int sve_excp_el; /* SVE exception EL or 0 if enabled */
46
diff --git a/target/arm/helper.c b/target/arm/helper.c
47
index XXXXXXX..XXXXXXX 100644
48
--- a/target/arm/helper.c
49
+++ b/target/arm/helper.c
50
@@ -XXX,XX +XXX,XX @@ void cpu_get_tb_cpu_state(CPUARMState *env, target_ulong *pc,
51
*pc = env->pc;
52
flags = FIELD_DP32(flags, TBFLAG_ANY, AARCH64_STATE, 1);
53
/* Get control bits for tagged addresses */
54
- flags = FIELD_DP32(flags, TBFLAG_A64, TBI0,
55
+ flags = FIELD_DP32(flags, TBFLAG_A64, TBII,
56
+ (arm_regime_tbi1(env, mmu_idx) << 1) |
57
arm_regime_tbi0(env, mmu_idx));
58
- flags = FIELD_DP32(flags, TBFLAG_A64, TBI1,
59
- arm_regime_tbi1(env, mmu_idx));
60
61
if (cpu_isar_feature(aa64_sve, cpu)) {
62
int sve_el = sve_exception_el(env, current_el);
63
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
64
index XXXXXXX..XXXXXXX 100644
65
--- a/target/arm/translate-a64.c
66
+++ b/target/arm/translate-a64.c
67
@@ -XXX,XX +XXX,XX @@ void gen_a64_set_pc_im(uint64_t val)
68
*/
69
static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
70
{
71
+ /* Note that TBII is TBI1:TBI0. */
72
+ int tbi = s->tbii;
73
74
if (s->current_el <= 1) {
75
/* Test if NEITHER or BOTH TBI values are set. If so, no need to
76
* examine bit 55 of address, can just generate code.
77
* If mixed, then test via generated code
78
*/
79
- if (s->tbi0 && s->tbi1) {
80
+ if (tbi == 3) {
81
TCGv_i64 tmp_reg = tcg_temp_new_i64();
82
/* Both bits set, sign extension from bit 55 into [63:56] will
83
* cover both cases
84
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
85
tcg_gen_shli_i64(tmp_reg, src, 8);
86
tcg_gen_sari_i64(cpu_pc, tmp_reg, 8);
87
tcg_temp_free_i64(tmp_reg);
88
- } else if (!s->tbi0 && !s->tbi1) {
89
+ } else if (tbi == 0) {
90
/* Neither bit set, just load it as-is */
91
tcg_gen_mov_i64(cpu_pc, src);
92
} else {
93
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
94
95
tcg_gen_andi_i64(tcg_bit55, src, (1ull << 55));
96
97
- if (s->tbi0) {
98
+ if (tbi == 1) {
99
/* tbi0==1, tbi1==0, so 0-fill upper byte if bit 55 = 0 */
100
tcg_gen_andi_i64(tcg_tmpval, src,
101
0x00FFFFFFFFFFFFFFull);
102
@@ -XXX,XX +XXX,XX @@ static void gen_a64_set_pc(DisasContext *s, TCGv_i64 src)
103
tcg_temp_free_i64(tcg_tmpval);
104
}
105
} else { /* EL > 1 */
106
- if (s->tbi0) {
107
+ if (tbi != 0) {
108
/* Force tag byte to all zero */
109
tcg_gen_andi_i64(cpu_pc, src, 0x00FFFFFFFFFFFFFFull);
110
} else {
111
@@ -XXX,XX +XXX,XX @@ static void aarch64_tr_init_disas_context(DisasContextBase *dcbase,
112
dc->condexec_cond = 0;
113
core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
114
dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
115
- dc->tbi0 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI0);
116
- dc->tbi1 = FIELD_EX32(tb_flags, TBFLAG_A64, TBI1);
117
+ dc->tbii = FIELD_EX32(tb_flags, TBFLAG_A64, TBII);
118
dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
119
#if !defined(CONFIG_USER_ONLY)
120
dc->user = (dc->current_el == 0);
121
--
122
2.20.1
123
124
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is not really functional yet, because the crypto is not yet
4
implemented. This, however follows the Auth pseudo function.
5
6
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
7
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
8
Message-id: 20190108223129.5570-26-richard.henderson@linaro.org
9
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
10
---
11
target/arm/pauth_helper.c | 21 ++++++++++++++++++++-
12
1 file changed, 20 insertions(+), 1 deletion(-)
13
14
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/target/arm/pauth_helper.c
17
+++ b/target/arm/pauth_helper.c
18
@@ -XXX,XX +XXX,XX @@ static uint64_t pauth_original_ptr(uint64_t ptr, ARMVAParameters param)
19
static uint64_t pauth_auth(CPUARMState *env, uint64_t ptr, uint64_t modifier,
20
ARMPACKey *key, bool data, int keynumber)
21
{
22
- g_assert_not_reached(); /* FIXME */
23
+ ARMMMUIdx mmu_idx = arm_stage1_mmu_idx(env);
24
+ ARMVAParameters param = aa64_va_parameters(env, ptr, mmu_idx, data);
25
+ int bot_bit, top_bit;
26
+ uint64_t pac, orig_ptr, test;
27
+
28
+ orig_ptr = pauth_original_ptr(ptr, param);
29
+ pac = pauth_computepac(orig_ptr, modifier, *key);
30
+ bot_bit = 64 - param.tsz;
31
+ top_bit = 64 - 8 * param.tbi;
32
+
33
+ test = (pac ^ ptr) & ~MAKE_64BIT_MASK(55, 1);
34
+ if (unlikely(extract64(test, bot_bit, top_bit - bot_bit))) {
35
+ int error_code = (keynumber << 1) | (keynumber ^ 1);
36
+ if (param.tbi) {
37
+ return deposit64(ptr, 53, 2, error_code);
38
+ } else {
39
+ return deposit64(ptr, 61, 2, error_code);
40
+ }
41
+ }
42
+ return orig_ptr;
43
}
44
45
static uint64_t pauth_strip(CPUARMState *env, uint64_t ptr, bool data)
46
--
47
2.20.1
48
49
diff view generated by jsdifflib
Deleted patch
1
From: Richard Henderson <richard.henderson@linaro.org>
2
1
3
This is the main crypto routine, an implementation of QARMA.
4
This matches, as much as possible, ARM pseudocode.
5
6
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
7
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
8
Message-id: 20190108223129.5570-28-richard.henderson@linaro.org
9
[PMM: fixed minor checkpatch nits]
10
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
11
---
12
target/arm/pauth_helper.c | 242 +++++++++++++++++++++++++++++++++++++-
13
1 file changed, 241 insertions(+), 1 deletion(-)
14
15
diff --git a/target/arm/pauth_helper.c b/target/arm/pauth_helper.c
16
index XXXXXXX..XXXXXXX 100644
17
--- a/target/arm/pauth_helper.c
18
+++ b/target/arm/pauth_helper.c
19
@@ -XXX,XX +XXX,XX @@
20
#include "tcg/tcg-gvec-desc.h"
21
22
23
+static uint64_t pac_cell_shuffle(uint64_t i)
24
+{
25
+ uint64_t o = 0;
26
+
27
+ o |= extract64(i, 52, 4);
28
+ o |= extract64(i, 24, 4) << 4;
29
+ o |= extract64(i, 44, 4) << 8;
30
+ o |= extract64(i, 0, 4) << 12;
31
+
32
+ o |= extract64(i, 28, 4) << 16;
33
+ o |= extract64(i, 48, 4) << 20;
34
+ o |= extract64(i, 4, 4) << 24;
35
+ o |= extract64(i, 40, 4) << 28;
36
+
37
+ o |= extract64(i, 32, 4) << 32;
38
+ o |= extract64(i, 12, 4) << 36;
39
+ o |= extract64(i, 56, 4) << 40;
40
+ o |= extract64(i, 20, 4) << 44;
41
+
42
+ o |= extract64(i, 8, 4) << 48;
43
+ o |= extract64(i, 36, 4) << 52;
44
+ o |= extract64(i, 16, 4) << 56;
45
+ o |= extract64(i, 60, 4) << 60;
46
+
47
+ return o;
48
+}
49
+
50
+static uint64_t pac_cell_inv_shuffle(uint64_t i)
51
+{
52
+ uint64_t o = 0;
53
+
54
+ o |= extract64(i, 12, 4);
55
+ o |= extract64(i, 24, 4) << 4;
56
+ o |= extract64(i, 48, 4) << 8;
57
+ o |= extract64(i, 36, 4) << 12;
58
+
59
+ o |= extract64(i, 56, 4) << 16;
60
+ o |= extract64(i, 44, 4) << 20;
61
+ o |= extract64(i, 4, 4) << 24;
62
+ o |= extract64(i, 16, 4) << 28;
63
+
64
+ o |= i & MAKE_64BIT_MASK(32, 4);
65
+ o |= extract64(i, 52, 4) << 36;
66
+ o |= extract64(i, 28, 4) << 40;
67
+ o |= extract64(i, 8, 4) << 44;
68
+
69
+ o |= extract64(i, 20, 4) << 48;
70
+ o |= extract64(i, 0, 4) << 52;
71
+ o |= extract64(i, 40, 4) << 56;
72
+ o |= i & MAKE_64BIT_MASK(60, 4);
73
+
74
+ return o;
75
+}
76
+
77
+static uint64_t pac_sub(uint64_t i)
78
+{
79
+ static const uint8_t sub[16] = {
80
+ 0xb, 0x6, 0x8, 0xf, 0xc, 0x0, 0x9, 0xe,
81
+ 0x3, 0x7, 0x4, 0x5, 0xd, 0x2, 0x1, 0xa,
82
+ };
83
+ uint64_t o = 0;
84
+ int b;
85
+
86
+ for (b = 0; b < 64; b += 16) {
87
+ o |= (uint64_t)sub[(i >> b) & 0xf] << b;
88
+ }
89
+ return o;
90
+}
91
+
92
+static uint64_t pac_inv_sub(uint64_t i)
93
+{
94
+ static const uint8_t inv_sub[16] = {
95
+ 0x5, 0xe, 0xd, 0x8, 0xa, 0xb, 0x1, 0x9,
96
+ 0x2, 0x6, 0xf, 0x0, 0x4, 0xc, 0x7, 0x3,
97
+ };
98
+ uint64_t o = 0;
99
+ int b;
100
+
101
+ for (b = 0; b < 64; b += 16) {
102
+ o |= (uint64_t)inv_sub[(i >> b) & 0xf] << b;
103
+ }
104
+ return o;
105
+}
106
+
107
+static int rot_cell(int cell, int n)
108
+{
109
+ /* 4-bit rotate left by n. */
110
+ cell |= cell << 4;
111
+ return extract32(cell, 4 - n, 4);
112
+}
113
+
114
+static uint64_t pac_mult(uint64_t i)
115
+{
116
+ uint64_t o = 0;
117
+ int b;
118
+
119
+ for (b = 0; b < 4 * 4; b += 4) {
120
+ int i0, i4, i8, ic, t0, t1, t2, t3;
121
+
122
+ i0 = extract64(i, b, 4);
123
+ i4 = extract64(i, b + 4 * 4, 4);
124
+ i8 = extract64(i, b + 8 * 4, 4);
125
+ ic = extract64(i, b + 12 * 4, 4);
126
+
127
+ t0 = rot_cell(i8, 1) ^ rot_cell(i4, 2) ^ rot_cell(i0, 1);
128
+ t1 = rot_cell(ic, 1) ^ rot_cell(i4, 1) ^ rot_cell(i0, 2);
129
+ t2 = rot_cell(ic, 2) ^ rot_cell(i8, 1) ^ rot_cell(i0, 1);
130
+ t3 = rot_cell(ic, 1) ^ rot_cell(i8, 2) ^ rot_cell(i4, 1);
131
+
132
+ o |= (uint64_t)t3 << b;
133
+ o |= (uint64_t)t2 << (b + 4 * 4);
134
+ o |= (uint64_t)t1 << (b + 8 * 4);
135
+ o |= (uint64_t)t0 << (b + 12 * 4);
136
+ }
137
+ return o;
138
+}
139
+
140
+static uint64_t tweak_cell_rot(uint64_t cell)
141
+{
142
+ return (cell >> 1) | (((cell ^ (cell >> 1)) & 1) << 3);
143
+}
144
+
145
+static uint64_t tweak_shuffle(uint64_t i)
146
+{
147
+ uint64_t o = 0;
148
+
149
+ o |= extract64(i, 16, 4) << 0;
150
+ o |= extract64(i, 20, 4) << 4;
151
+ o |= tweak_cell_rot(extract64(i, 24, 4)) << 8;
152
+ o |= extract64(i, 28, 4) << 12;
153
+
154
+ o |= tweak_cell_rot(extract64(i, 44, 4)) << 16;
155
+ o |= extract64(i, 8, 4) << 20;
156
+ o |= extract64(i, 12, 4) << 24;
157
+ o |= tweak_cell_rot(extract64(i, 32, 4)) << 28;
158
+
159
+ o |= extract64(i, 48, 4) << 32;
160
+ o |= extract64(i, 52, 4) << 36;
161
+ o |= extract64(i, 56, 4) << 40;
162
+ o |= tweak_cell_rot(extract64(i, 60, 4)) << 44;
163
+
164
+ o |= tweak_cell_rot(extract64(i, 0, 4)) << 48;
165
+ o |= extract64(i, 4, 4) << 52;
166
+ o |= tweak_cell_rot(extract64(i, 40, 4)) << 56;
167
+ o |= tweak_cell_rot(extract64(i, 36, 4)) << 60;
168
+
169
+ return o;
170
+}
171
+
172
+static uint64_t tweak_cell_inv_rot(uint64_t cell)
173
+{
174
+ return ((cell << 1) & 0xf) | ((cell & 1) ^ (cell >> 3));
175
+}
176
+
177
+static uint64_t tweak_inv_shuffle(uint64_t i)
178
+{
179
+ uint64_t o = 0;
180
+
181
+ o |= tweak_cell_inv_rot(extract64(i, 48, 4));
182
+ o |= extract64(i, 52, 4) << 4;
183
+ o |= extract64(i, 20, 4) << 8;
184
+ o |= extract64(i, 24, 4) << 12;
185
+
186
+ o |= extract64(i, 0, 4) << 16;
187
+ o |= extract64(i, 4, 4) << 20;
188
+ o |= tweak_cell_inv_rot(extract64(i, 8, 4)) << 24;
189
+ o |= extract64(i, 12, 4) << 28;
190
+
191
+ o |= tweak_cell_inv_rot(extract64(i, 28, 4)) << 32;
192
+ o |= tweak_cell_inv_rot(extract64(i, 60, 4)) << 36;
193
+ o |= tweak_cell_inv_rot(extract64(i, 56, 4)) << 40;
194
+ o |= tweak_cell_inv_rot(extract64(i, 16, 4)) << 44;
195
+
196
+ o |= extract64(i, 32, 4) << 48;
197
+ o |= extract64(i, 36, 4) << 52;
198
+ o |= extract64(i, 40, 4) << 56;
199
+ o |= tweak_cell_inv_rot(extract64(i, 44, 4)) << 60;
200
+
201
+ return o;
202
+}
203
+
204
static uint64_t pauth_computepac(uint64_t data, uint64_t modifier,
205
ARMPACKey key)
206
{
207
- g_assert_not_reached(); /* FIXME */
208
+ static const uint64_t RC[5] = {
209
+ 0x0000000000000000ull,
210
+ 0x13198A2E03707344ull,
211
+ 0xA4093822299F31D0ull,
212
+ 0x082EFA98EC4E6C89ull,
213
+ 0x452821E638D01377ull,
214
+ };
215
+ const uint64_t alpha = 0xC0AC29B7C97C50DDull;
216
+ /*
217
+ * Note that in the ARM pseudocode, key0 contains bits <127:64>
218
+ * and key1 contains bits <63:0> of the 128-bit key.
219
+ */
220
+ uint64_t key0 = key.hi, key1 = key.lo;
221
+ uint64_t workingval, runningmod, roundkey, modk0;
222
+ int i;
223
+
224
+ modk0 = (key0 << 63) | ((key0 >> 1) ^ (key0 >> 63));
225
+ runningmod = modifier;
226
+ workingval = data ^ key0;
227
+
228
+ for (i = 0; i <= 4; ++i) {
229
+ roundkey = key1 ^ runningmod;
230
+ workingval ^= roundkey;
231
+ workingval ^= RC[i];
232
+ if (i > 0) {
233
+ workingval = pac_cell_shuffle(workingval);
234
+ workingval = pac_mult(workingval);
235
+ }
236
+ workingval = pac_sub(workingval);
237
+ runningmod = tweak_shuffle(runningmod);
238
+ }
239
+ roundkey = modk0 ^ runningmod;
240
+ workingval ^= roundkey;
241
+ workingval = pac_cell_shuffle(workingval);
242
+ workingval = pac_mult(workingval);
243
+ workingval = pac_sub(workingval);
244
+ workingval = pac_cell_shuffle(workingval);
245
+ workingval = pac_mult(workingval);
246
+ workingval ^= key1;
247
+ workingval = pac_cell_inv_shuffle(workingval);
248
+ workingval = pac_inv_sub(workingval);
249
+ workingval = pac_mult(workingval);
250
+ workingval = pac_cell_inv_shuffle(workingval);
251
+ workingval ^= key0;
252
+ workingval ^= runningmod;
253
+ for (i = 0; i <= 4; ++i) {
254
+ workingval = pac_inv_sub(workingval);
255
+ if (i < 4) {
256
+ workingval = pac_mult(workingval);
257
+ workingval = pac_cell_inv_shuffle(workingval);
258
+ }
259
+ runningmod = tweak_inv_shuffle(runningmod);
260
+ roundkey = key1 ^ runningmod;
261
+ workingval ^= RC[4 - i];
262
+ workingval ^= roundkey;
263
+ workingval ^= alpha;
264
+ }
265
+ workingval ^= modk0;
266
+
267
+ return workingval;
268
}
269
270
static uint64_t pauth_addpac(CPUARMState *env, uint64_t ptr, uint64_t modifier,
271
--
272
2.20.1
273
274
diff view generated by jsdifflib