1 /*
2 * xen/arch/arm/arm64/sysreg.c
3 *
4 * Emulate system registers trapped.
5 *
6 * Copyright (c) 2011 Citrix Systems.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
18
19 #include <xen/sched.h>
20
21 #include <asm/current.h>
22 #include <asm/regs.h>
23 #include <asm/traps.h>
24 #include <asm/vtimer.h>
25
do_sysreg(struct cpu_user_regs * regs,const union hsr hsr)26 void do_sysreg(struct cpu_user_regs *regs,
27 const union hsr hsr)
28 {
29 int regidx = hsr.sysreg.reg;
30 struct vcpu *v = current;
31
32 switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
33 {
34 /*
35 * HCR_EL2.TACR
36 *
37 * ARMv8 (DDI 0487A.d): D7.2.1
38 */
39 case HSR_SYSREG_ACTLR_EL1:
40 if ( psr_mode_is_user(regs) )
41 return inject_undef_exception(regs, hsr);
42 if ( hsr.sysreg.read )
43 set_user_reg(regs, regidx, v->arch.actlr);
44 break;
45
46 /*
47 * MDCR_EL2.TDRA
48 *
49 * ARMv8 (DDI 0487A.d): D1-1508 Table D1-57
50 */
51 case HSR_SYSREG_MDRAR_EL1:
52 return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 1);
53
54 /*
55 * MDCR_EL2.TDOSA
56 *
57 * ARMv8 (DDI 0487A.d): D1-1509 Table D1-58
58 *
59 * Unhandled:
60 * OSLSR_EL1
61 * DBGPRCR_EL1
62 */
63 case HSR_SYSREG_OSLAR_EL1:
64 return handle_wo_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
65 case HSR_SYSREG_OSDLR_EL1:
66 return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
67
68 /*
69 * MDCR_EL2.TDA
70 *
71 * ARMv8 (DDI 0487A.d): D1-1510 Table D1-59
72 *
73 * Unhandled:
74 * MDCCINT_EL1
75 * DBGDTR_EL0
76 * DBGDTRRX_EL0
77 * DBGDTRTX_EL0
78 * OSDTRRX_EL1
79 * OSDTRTX_EL1
80 * OSECCR_EL1
81 * DBGCLAIMSET_EL1
82 * DBGCLAIMCLR_EL1
83 * DBGAUTHSTATUS_EL1
84 */
85 case HSR_SYSREG_MDSCR_EL1:
86 return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
87 case HSR_SYSREG_MDCCSR_EL0:
88 /*
89 * Accessible at EL0 only if MDSCR_EL1.TDCC is set to 0. We emulate that
90 * register as RAZ/WI above. So RO at both EL0 and EL1.
91 */
92 return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 0);
93 HSR_SYSREG_DBG_CASES(DBGBVR):
94 HSR_SYSREG_DBG_CASES(DBGBCR):
95 HSR_SYSREG_DBG_CASES(DBGWVR):
96 HSR_SYSREG_DBG_CASES(DBGWCR):
97 return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
98
99 /*
100 * MDCR_EL2.TPM
101 *
102 * ARMv8 (DDI 0487A.d): D1-1511 Table D1-61
103 *
104 * Unhandled:
105 * PMEVCNTR<n>_EL0
106 * PMEVTYPER<n>_EL0
107 * PMCCFILTR_EL0
108 * MDCR_EL2.TPMCR
109 *
110 * ARMv7 (DDI 0406C.b): B1.14.17
111 * ARMv8 (DDI 0487A.d): D1-1511 Table D1-62
112 *
113 * NB: Both MDCR_EL2.TPM and MDCR_EL2.TPMCR cause trapping of PMCR.
114 */
115 case HSR_SYSREG_PMINTENSET_EL1:
116 case HSR_SYSREG_PMINTENCLR_EL1:
117 /*
118 * Accessible from EL1 only, but if EL0 trap happens handle as
119 * undef.
120 */
121 return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
122 case HSR_SYSREG_PMUSERENR_EL0:
123 /* RO at EL0. RAZ/WI at EL1 */
124 if ( psr_mode_is_user(regs) )
125 return handle_ro_raz(regs, regidx, hsr.sysreg.read, hsr, 0);
126 else
127 return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
128 case HSR_SYSREG_PMCR_EL0:
129 case HSR_SYSREG_PMCNTENSET_EL0:
130 case HSR_SYSREG_PMCNTENCLR_EL0:
131 case HSR_SYSREG_PMOVSCLR_EL0:
132 case HSR_SYSREG_PMSWINC_EL0:
133 case HSR_SYSREG_PMSELR_EL0:
134 case HSR_SYSREG_PMCEID0_EL0:
135 case HSR_SYSREG_PMCEID1_EL0:
136 case HSR_SYSREG_PMCCNTR_EL0:
137 case HSR_SYSREG_PMXEVTYPER_EL0:
138 case HSR_SYSREG_PMXEVCNTR_EL0:
139 case HSR_SYSREG_PMOVSSET_EL0:
140 /*
141 * Accessible at EL0 only if PMUSERENR_EL0.EN is set. We
142 * emulate that register as 0 above.
143 */
144 return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
145
146 /*
147 * !CNTHCTL_EL2.EL1PCEN
148 *
149 * ARMv8 (DDI 0487A.d): D1-1510 Table D1-60
150 */
151 case HSR_SYSREG_CNTP_CTL_EL0:
152 case HSR_SYSREG_CNTP_TVAL_EL0:
153 case HSR_SYSREG_CNTP_CVAL_EL0:
154 if ( !vtimer_emulate(regs, hsr) )
155 return inject_undef_exception(regs, hsr);
156 break;
157
158 /*
159 * HCR_EL2.FMO or HCR_EL2.IMO
160 *
161 * GIC Architecture Specification (IHI 0069C): Section 4.6.3
162 */
163 case HSR_SYSREG_ICC_SGI1R_EL1:
164 case HSR_SYSREG_ICC_ASGI1R_EL1:
165 case HSR_SYSREG_ICC_SGI0R_EL1:
166
167 if ( !vgic_emulate(regs, hsr) )
168 return inject_undef64_exception(regs, hsr.len);
169 break;
170
171 /*
172 * ICC_SRE_EL2.Enable = 0
173 *
174 * GIC Architecture Specification (IHI 0069C): Section 8.1.9
175 */
176 case HSR_SYSREG_ICC_SRE_EL1:
177 /*
178 * Trapped when the guest is using GICv2 whilst the platform
179 * interrupt controller is GICv3. In this case, the register
180 * should be emulate as RAZ/WI to tell the guest to use the GIC
181 * memory mapped interface (i.e GICv2 compatibility).
182 */
183 return handle_raz_wi(regs, regidx, hsr.sysreg.read, hsr, 1);
184
185 /*
186 * HCR_EL2.TIDCP
187 *
188 * ARMv8 (DDI 0487A.d): D1-1501 Table D1-43
189 *
190 * - Reserved control space for IMPLEMENTATION DEFINED functionality.
191 *
192 * CPTR_EL2.TTA
193 *
194 * ARMv8 (DDI 0487A.d): D1-1507 Table D1-54
195 *
196 * - All implemented trace registers.
197 *
198 * And all other unknown registers.
199 */
200 default:
201 {
202 const struct hsr_sysreg sysreg = hsr.sysreg;
203
204 gdprintk(XENLOG_ERR,
205 "%s %d, %d, c%d, c%d, %d %s x%d @ 0x%"PRIregister"\n",
206 sysreg.read ? "mrs" : "msr",
207 sysreg.op0, sysreg.op1,
208 sysreg.crn, sysreg.crm,
209 sysreg.op2,
210 sysreg.read ? "=>" : "<=",
211 sysreg.reg, regs->pc);
212 gdprintk(XENLOG_ERR, "unhandled 64-bit sysreg access %#x\n",
213 hsr.bits & HSR_SYSREG_REGS_MASK);
214 inject_undef_exception(regs, hsr);
215 return;
216 }
217 }
218
219 regs->pc += 4;
220 }
221
222 /*
223 * Local variables:
224 * mode: C
225 * c-file-style: "BSD"
226 * c-basic-offset: 4
227 * indent-tabs-mode: nil
228 * End:
229 */
230