master
c 130 lines 4.74 KB
Raw
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2
3 #include "qemu/osdep.h"
4 #include "cpu.h"
5 #include "qemu/target-info.h"
6 #include "internals.h"
7
8
9 /* Share AArch32 -cpu max features with AArch64. */
10 void aa32_max_features(ARMCPU *cpu)
11 {
12 uint32_t t;
13 ARMISARegisters *isar = &cpu->isar;
14
15 /* Add additional features supported by QEMU */
16 t = GET_IDREG(isar, ID_ISAR5);
17 t = FIELD_DP32(t, ID_ISAR5, AES, 2); /* FEAT_PMULL */
18 t = FIELD_DP32(t, ID_ISAR5, SHA1, 1); /* FEAT_SHA1 */
19 t = FIELD_DP32(t, ID_ISAR5, SHA2, 1); /* FEAT_SHA256 */
20 t = FIELD_DP32(t, ID_ISAR5, CRC32, 1);
21 t = FIELD_DP32(t, ID_ISAR5, RDM, 1); /* FEAT_RDM */
22 t = FIELD_DP32(t, ID_ISAR5, VCMA, 1); /* FEAT_FCMA */
23 SET_IDREG(isar, ID_ISAR5, t);
24
25 t = GET_IDREG(isar, ID_ISAR6);
26 t = FIELD_DP32(t, ID_ISAR6, JSCVT, 1); /* FEAT_JSCVT */
27 t = FIELD_DP32(t, ID_ISAR6, DP, 1); /* Feat_DotProd */
28 t = FIELD_DP32(t, ID_ISAR6, FHM, 1); /* FEAT_FHM */
29 t = FIELD_DP32(t, ID_ISAR6, SB, 1); /* FEAT_SB */
30 t = FIELD_DP32(t, ID_ISAR6, SPECRES, 1); /* FEAT_SPECRES */
31 t = FIELD_DP32(t, ID_ISAR6, BF16, 1); /* FEAT_AA32BF16 */
32 t = FIELD_DP32(t, ID_ISAR6, I8MM, 1); /* FEAT_AA32I8MM */
33 SET_IDREG(isar, ID_ISAR6, t);
34
35 t = cpu->isar.mvfr1;
36 t = FIELD_DP32(t, MVFR1, FPHP, 3); /* FEAT_FP16 */
37 t = FIELD_DP32(t, MVFR1, SIMDHP, 2); /* FEAT_FP16 */
38 cpu->isar.mvfr1 = t;
39
40 t = cpu->isar.mvfr2;
41 t = FIELD_DP32(t, MVFR2, SIMDMISC, 3); /* SIMD MaxNum */
42 t = FIELD_DP32(t, MVFR2, FPMISC, 4); /* FP MaxNum */
43 cpu->isar.mvfr2 = t;
44
45 FIELD_DP32_IDREG(isar, ID_MMFR3, PAN, 2); /* FEAT_PAN2 */
46
47 t = GET_IDREG(isar, ID_MMFR4);
48 t = FIELD_DP32(t, ID_MMFR4, HPDS, 2); /* FEAT_HPDS2 */
49 t = FIELD_DP32(t, ID_MMFR4, AC2, 1); /* ACTLR2, HACTLR2 */
50 t = FIELD_DP32(t, ID_MMFR4, CNP, 1); /* FEAT_TTCNP */
51 t = FIELD_DP32(t, ID_MMFR4, XNX, 1); /* FEAT_XNX */
52 t = FIELD_DP32(t, ID_MMFR4, EVT, 2); /* FEAT_EVT2 */
53 SET_IDREG(isar, ID_MMFR4, t);
54
55 FIELD_DP32_IDREG(isar, ID_MMFR5, ETS, 2); /* FEAT_ETS2 */
56
57 t = GET_IDREG(isar, ID_PFR0);
58 t = FIELD_DP32(t, ID_PFR0, CSV2, 2); /* FEAT_CSV2 */
59 t = FIELD_DP32(t, ID_PFR0, DIT, 1); /* FEAT_DIT */
60 t = FIELD_DP32(t, ID_PFR0, RAS, 1); /* FEAT_RAS */
61 SET_IDREG(isar, ID_PFR0, t);
62
63 t = GET_IDREG(isar, ID_PFR2);
64 t = FIELD_DP32(t, ID_PFR2, CSV3, 1); /* FEAT_CSV3 */
65 t = FIELD_DP32(t, ID_PFR2, SSBS, 1); /* FEAT_SSBS */
66 SET_IDREG(isar, ID_PFR2, t);
67
68 t = GET_IDREG(isar, ID_DFR0);
69 t = FIELD_DP32(t, ID_DFR0, COPDBG, 10); /* FEAT_Debugv8p8 */
70 t = FIELD_DP32(t, ID_DFR0, COPSDBG, 10); /* FEAT_Debugv8p8 */
71 t = FIELD_DP32(t, ID_DFR0, PERFMON, 6); /* FEAT_PMUv3p5 */
72 SET_IDREG(isar, ID_DFR0, t);
73
74 /* Debug ID registers. */
75
76 /* Bit[15] is RES1, Bit[13] and Bits[11:0] are RES0. */
77 t = 0x00008000;
78 t = FIELD_DP32(t, DBGDIDR, SE_IMP, 1);
79 t = FIELD_DP32(t, DBGDIDR, NSUHD_IMP, 1);
80 t = FIELD_DP32(t, DBGDIDR, VERSION, 10); /* FEAT_Debugv8p8 */
81 t = FIELD_DP32(t, DBGDIDR, CTX_CMPS, 1);
82 t = FIELD_DP32(t, DBGDIDR, BRPS, 5);
83 t = FIELD_DP32(t, DBGDIDR, WRPS, 3);
84 cpu->isar.dbgdidr = t;
85
86 t = 0;
87 t = FIELD_DP32(t, DBGDEVID, PCSAMPLE, 3);
88 t = FIELD_DP32(t, DBGDEVID, WPADDRMASK, 1);
89 t = FIELD_DP32(t, DBGDEVID, BPADDRMASK, 15);
90 t = FIELD_DP32(t, DBGDEVID, VECTORCATCH, 0);
91 t = FIELD_DP32(t, DBGDEVID, VIRTEXTNS, 1);
92 t = FIELD_DP32(t, DBGDEVID, DOUBLELOCK, 1);
93 t = FIELD_DP32(t, DBGDEVID, AUXREGS, 0);
94 t = FIELD_DP32(t, DBGDEVID, CIDMASK, 0);
95 cpu->isar.dbgdevid = t;
96
97 /* Bits[31:4] are RES0. */
98 t = 0;
99 t = FIELD_DP32(t, DBGDEVID1, PCSROFFSET, 2);
100 cpu->isar.dbgdevid1 = t;
101
102 FIELD_DP32_IDREG(isar, ID_DFR1, HPMN0, 1); /* FEAT_HPMN0 */
103 }
104
105 void aarch32_max_v8_tcg_initfn(Object *obj)
106 {
107 ARMCPU *cpu = ARM_CPU(obj);
108
109 aarch64_aa32_a57_init(cpu, false);
110 aa32_max_features(cpu);
111 #ifdef CONFIG_USER_ONLY
112 /*
113 * Break with true ARMv8 and add back old-style VFP short-vector
114 * support. Only do this for user-mode, where -cpu max is the default,
115 * so that older v6 and v7 programs are more likely to work without
116 * adjustment.
117 */
118 cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
119 #endif
120 }
121
122 static void cpu_max_v8_register_type(void)
123 {
124 static const ARMCPUInfo max_v8[2] = {
125 { .name = "max-v8", .initfn = aarch32_max_v8_tcg_initfn },
126 { .name = "max-v8", .initfn = aarch64_max_v8_tcg_initfn },
127 };
128 arm_cpu_register(&max_v8[target_aarch64()]);
129 }
130 type_init(cpu_max_v8_register_type)