return inject_undef_exception(regs, hsr);
break;
+ /*
+ * HCR_EL2.FMO or HCR_EL2.IMO
+ *
+ * GIC Architecture Specification (IHI 0069C): Section 4.6.3
+ */
+ case HSR_CPREG64(ICC_SGI1R):
+ case HSR_CPREG64(ICC_ASGI1R):
+ case HSR_CPREG64(ICC_SGI0R):
+ if ( !vgic_emulate(regs, hsr) )
+ return inject_undef_exception(regs, hsr);
+ break;
+
/*
* CPTR_EL2.T{0..9,12..13}
*
}
}
+static bool vgic_v3_emulate_cp64(struct cpu_user_regs *regs, union hsr hsr)
+{
+ struct hsr_cp64 cp64 = hsr.cp64;
+
+ if ( cp64.read )
+ perfc_incr(vgic_cp64_reads);
+ else
+ perfc_incr(vgic_cp64_writes);
+
+ switch ( hsr.bits & HSR_CP64_REGS_MASK )
+ {
+ case HSR_CPREG64(ICC_SGI1R):
+ return vreg_emulate_cp64(regs, hsr, vgic_v3_emulate_sgi1r);
+ default:
+ return false;
+ }
+}
+
static bool vgic_v3_emulate_reg(struct cpu_user_regs *regs, union hsr hsr)
{
switch (hsr.ec)
{
case HSR_EC_SYSREG:
return vgic_v3_emulate_sysreg(regs, hsr);
+ case HSR_EC_CP15_64:
+ return vgic_v3_emulate_cp64(regs, hsr);
default:
return false;
}
/* CP15 CR11: DMA Operations for TCM Access */
/* CP15 CR12: */
+#define ICC_SGI1R p15,0,c12 /* Interrupt Controller SGI Group 1 */
+#define ICC_ASGI1R p15,1,c12 /* Interrupt Controller Alias SGI Group 1 Register */
+#define ICC_SGI0R p15,2,c12 /* Interrupt Controller SGI Group 0 */
#define VBAR p15,0,c12,c0,0 /* Vector Base Address Register */
#define HVBAR p15,4,c12,c0,0 /* Hyp. Vector Base Address Register */
PERFCOUNTER(vgicd_writes, "vgicd: write")
PERFCOUNTER(vgicr_reads, "vgicr: read")
PERFCOUNTER(vgicr_writes, "vgicr: write")
+PERFCOUNTER(vgic_cp64_reads, "vgic: cp64 read")
+PERFCOUNTER(vgic_cp64_writes, "vgic: cp64 write")
PERFCOUNTER(vgic_sysreg_reads, "vgic: sysreg read")
PERFCOUNTER(vgic_sysreg_writes, "vgic: sysreg write")
PERFCOUNTER(vgic_sgi_list , "vgic: SGI send to list")