/* Setup Hyp vector base */
WRITE_SYSREG((vaddr_t)hyp_traps_vector, VBAR_EL2);
+ /* Trap Debug and Performance Monitor accesses */
+ WRITE_SYSREG(HDCR_TDRA|HDCR_TDOSA|HDCR_TDA|HDCR_TPM|HDCR_TPMCR,
+ MDCR_EL2);
+
/* Trap CP15 c15 used for implementation defined registers */
WRITE_SYSREG(HSTR_T(15), HSTR_EL2);
advance_pc(regs, hsr);
}
+static void do_cp14(struct cpu_user_regs *regs, union hsr hsr)
+{
+ if ( !check_conditional_instr(regs, hsr) )
+ {
+ advance_pc(regs, hsr);
+ return;
+ }
+
+ inject_undef32_exception(regs);
+}
+
static void do_cp(struct cpu_user_regs *regs, union hsr hsr)
{
if ( !check_conditional_instr(regs, hsr) )
static void do_sysreg(struct cpu_user_regs *regs,
union hsr hsr)
{
+ register_t *x = select_user_reg(regs, hsr.sysreg.reg);
switch ( hsr.bits & HSR_SYSREG_REGS_MASK )
{
+ /* RAZ/WI registers: */
+ /* - Debug */
+ case HSR_SYSREG_MDSCR_EL1:
+ /* - Perf monitors */
+ case HSR_SYSREG_PMINTENSET_EL1:
+ case HSR_SYSREG_PMINTENCLR_EL1:
+ case HSR_SYSREG_PMCR_EL0:
+ case HSR_SYSREG_PMCNTENSET_EL0:
+ case HSR_SYSREG_PMCNTENCLR_EL0:
+ case HSR_SYSREG_PMOVSCLR_EL0:
+ case HSR_SYSREG_PMSWINC_EL0:
+ case HSR_SYSREG_PMSELR_EL0:
+ case HSR_SYSREG_PMCEID0_EL0:
+ case HSR_SYSREG_PMCEID1_EL0:
+ case HSR_SYSREG_PMCCNTR_EL0:
+ case HSR_SYSREG_PMXEVTYPER_EL0:
+ case HSR_SYSREG_PMXEVCNTR_EL0:
+ case HSR_SYSREG_PMUSERENR_EL0:
+ case HSR_SYSREG_PMOVSSET_EL0:
+ /* - Breakpoints */
+ HSR_SYSREG_DBG_CASES(DBGBVR):
+ HSR_SYSREG_DBG_CASES(DBGBCR):
+ /* - Watchpoints */
+ HSR_SYSREG_DBG_CASES(DBGWVR):
+ HSR_SYSREG_DBG_CASES(DBGWCR):
+ if ( hsr.sysreg.read )
+ *x = 0;
+ /* else: write ignored */
+ break;
+
+ /* Write only, Write ignore registers: */
+ case HSR_SYSREG_OSLAR_EL1:
+ if ( hsr.sysreg.read )
+ goto bad_sysreg;
+ /* else: write ignored */
+ break;
case HSR_SYSREG_CNTP_CTL_EL0:
case HSR_SYSREG_CNTP_TVAL_EL0:
if ( !vtimer_emulate(regs, hsr) )
}
break;
default:
+ bad_sysreg:
{
struct hsr_sysreg sysreg = hsr.sysreg;
#ifndef NDEBUG
goto bad_trap;
do_cp15_64(regs, hsr);
break;
+ case HSR_EC_CP14_32:
+ case HSR_EC_CP14_DBG:
+ if ( !is_32bit_domain(current->domain) )
+ goto bad_trap;
+ do_cp14(regs, hsr);
+ break;
case HSR_EC_CP:
if ( !is_32bit_domain(current->domain) )
goto bad_trap;
/* HSTR Hyp. System Trap Register */
#define HSTR_T(x) ((_AC(1,U)<<(x))) /* Trap Cp15 c<x> */
+/* HDCR Hyp. Debug Configuration Register */
+#define HDCR_TDRA (_AC(1,U)<<11) /* Trap Debug ROM access */
+#define HDCR_TDOSA (_AC(1,U)<<10) /* Trap Debug-OS-related register access */
+#define HDCR_TDA (_AC(1,U)<<9) /* Trap Debug Access */
+#define HDCR_TPM (_AC(1,U)<<6) /* Trap Performance Monitors accesses */
+#define HDCR_TPMCR (_AC(1,U)<<5) /* Trap PMCR accesses */
+
#define HSR_EC_UNKNOWN 0x00
#define HSR_EC_WFI_WFE 0x01
#define HSR_EC_CP15_32 0x03
#define HSR_EC_CP15_64 0x04
-#define HSR_EC_CP14_32 0x05
-#define HSR_EC_CP14_DBG 0x06
+#define HSR_EC_CP14_32 0x05 /* Trapped MCR or MRC access to CP14 */
+#define HSR_EC_CP14_DBG 0x06 /* Trapped LDC/STC access to CP14 (only for debug registers) */
#define HSR_EC_CP 0x07 /* HCPTR-trapped access to CP0-CP13 */
#define HSR_EC_CP10 0x08
#define HSR_EC_JAZELLE 0x09
((__HSR_SYSREG_##crm) << HSR_SYSREG_CRM_SHIFT) | \
((__HSR_SYSREG_##op2) << HSR_SYSREG_OP2_SHIFT)
+#define HSR_SYSREG_MDSCR_EL1 HSR_SYSREG(2,0,c0,c2,2)
+#define HSR_SYSREG_OSLAR_EL1 HSR_SYSREG(2,0,c1,c0,4)
+
+#define HSR_SYSREG_DBGBVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,4)
+#define HSR_SYSREG_DBGBCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,5)
+#define HSR_SYSREG_DBGWVRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,6)
+#define HSR_SYSREG_DBGWCRn_EL1(n) HSR_SYSREG(2,0,c0,c##n,7)
+
+#define HSR_SYSREG_DBG_CASES(REG) case HSR_SYSREG_##REG##n_EL1(0): \
+ case HSR_SYSREG_##REG##n_EL1(1): \
+ case HSR_SYSREG_##REG##n_EL1(2): \
+ case HSR_SYSREG_##REG##n_EL1(3): \
+ case HSR_SYSREG_##REG##n_EL1(4): \
+ case HSR_SYSREG_##REG##n_EL1(5): \
+ case HSR_SYSREG_##REG##n_EL1(6): \
+ case HSR_SYSREG_##REG##n_EL1(7): \
+ case HSR_SYSREG_##REG##n_EL1(8): \
+ case HSR_SYSREG_##REG##n_EL1(9): \
+ case HSR_SYSREG_##REG##n_EL1(10): \
+ case HSR_SYSREG_##REG##n_EL1(11): \
+ case HSR_SYSREG_##REG##n_EL1(12): \
+ case HSR_SYSREG_##REG##n_EL1(13): \
+ case HSR_SYSREG_##REG##n_EL1(14): \
+ case HSR_SYSREG_##REG##n_EL1(15)
+
#define HSR_SYSREG_SCTLR_EL1 HSR_SYSREG(3,0,c1, c0,0)
#define HSR_SYSREG_TTBR0_EL1 HSR_SYSREG(3,0,c2, c0,0)
#define HSR_SYSREG_TTBR1_EL1 HSR_SYSREG(3,0,c2, c0,1)
#define HSR_SYSREG_AFSR1_EL1 HSR_SYSREG(3,0,c5, c1,1)
#define HSR_SYSREG_ESR_EL1 HSR_SYSREG(3,0,c5, c2,0)
#define HSR_SYSREG_FAR_EL1 HSR_SYSREG(3,0,c6, c0,0)
+#define HSR_SYSREG_PMINTENSET_EL1 HSR_SYSREG(3,0,c9,c14,1)
+#define HSR_SYSREG_PMINTENCLR_EL1 HSR_SYSREG(3,0,c9,c14,2)
#define HSR_SYSREG_MAIR_EL1 HSR_SYSREG(3,0,c10,c2,0)
#define HSR_SYSREG_AMAIR_EL1 HSR_SYSREG(3,0,c10,c3,0)
#define HSR_SYSREG_CONTEXTIDR_EL1 HSR_SYSREG(3,0,c13,c0,1)
+#define HSR_SYSREG_PMCR_EL0 HSR_SYSREG(3,3,c9,c12,0)
+#define HSR_SYSREG_PMCNTENSET_EL0 HSR_SYSREG(3,3,c9,c12,1)
+#define HSR_SYSREG_PMCNTENCLR_EL0 HSR_SYSREG(3,3,c9,c12,2)
+#define HSR_SYSREG_PMOVSCLR_EL0 HSR_SYSREG(3,3,c9,c12,3)
+#define HSR_SYSREG_PMSWINC_EL0 HSR_SYSREG(3,3,c9,c12,4)
+#define HSR_SYSREG_PMSELR_EL0 HSR_SYSREG(3,3,c9,c12,5)
+#define HSR_SYSREG_PMCEID0_EL0 HSR_SYSREG(3,3,c9,c12,6)
+#define HSR_SYSREG_PMCEID1_EL0 HSR_SYSREG(3,3,c9,c12,7)
+
+#define HSR_SYSREG_PMCCNTR_EL0 HSR_SYSREG(3,3,c9,c13,0)
+#define HSR_SYSREG_PMXEVTYPER_EL0 HSR_SYSREG(3,3,c9,c13,1)
+#define HSR_SYSREG_PMXEVCNTR_EL0 HSR_SYSREG(3,3,c9,c13,2)
+
+#define HSR_SYSREG_PMUSERENR_EL0 HSR_SYSREG(3,3,c9,c14,0)
+#define HSR_SYSREG_PMOVSSET_EL0 HSR_SYSREG(3,3,c9,c14,3)
+
#define HSR_SYSREG_CNTPCT_EL0 HSR_SYSREG(3,3,c14,c0,0)
#define HSR_SYSREG_CNTP_CTL_EL0 HSR_SYSREG(3,3,c14,c2,1)
#define HSR_SYSREG_CNTP_TVAL_EL0 HSR_SYSREG(3,3,c14,c2,0)