mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
xen: arm: handle accesses to CNTP_CVAL_EL0
All OSes we have run on top of Xen use CNTP_TVAL_EL0 but for completeness we really should handle CVAL too. In vtimer_emulate_cp64 pull the propagation of the 64-bit result into two 32-bit registers out of the switch to avoid duplicating for every register. We also need to initialise x now since previously the only register implemented register was R/O. While adding HSR_SYSREG_CNTP_CVAL_EL0 also move HSR_SYSREG_CNTP_CTL_EL0 so it is sorted correctly. Signed-off-by: Ian Campbell <ian.campbell@citrix.com> Reviewed-by: Julien Grall <julien.grall@linaro.org>
This commit is contained in:
1 parent
d306211e21
commit
9cfa8ebe2e
3 files changed
+45
-8
No files matched your search
@@ -1658,6 +1658,7 @@ static void do_cp15_64(struct cpu_user_regs *regs,
|
||||
switch ( hsr.bits & HSR_CP64_REGS_MASK )
|
||||
{
|
||||
case HSR_CPREG64(CNTPCT):
|
||||
case HSR_CPREG64(CNTP_CVAL):
|
||||
if ( !vtimer_emulate(regs, hsr) )
|
||||
goto undef_cp15_64;
|
||||
break;
|
||||
@@ -1829,6 +1830,7 @@ static void do_sysreg(struct cpu_user_regs *regs,
|
||||
break;
|
||||
case HSR_SYSREG_CNTP_CTL_EL0:
|
||||
case HSR_SYSREG_CNTP_TVAL_EL0:
|
||||
case HSR_SYSREG_CNTP_CVAL_EL0:
|
||||
if ( !vtimer_emulate(regs, hsr) )
|
||||
goto undef_sysreg;
|
||||
break;
|
||||
|
||||
+41
-7
@@ -219,6 +219,30 @@ static int vtimer_cntp_tval(struct cpu_user_regs *regs, uint32_t *r, int read)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int vtimer_cntp_cval(struct cpu_user_regs *regs, uint64_t *r, int read)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
|
||||
if ( !ACCESS_ALLOWED(regs, EL0PTEN) )
|
||||
return 0;
|
||||
|
||||
if ( read )
|
||||
{
|
||||
*r = ns_to_ticks(v->arch.phys_timer.cval);
|
||||
}
|
||||
else
|
||||
{
|
||||
v->arch.phys_timer.cval = ticks_to_ns(*r);
|
||||
if ( v->arch.phys_timer.ctl & CNTx_CTL_ENABLE )
|
||||
{
|
||||
v->arch.phys_timer.ctl &= ~CNTx_CTL_PENDING;
|
||||
set_timer(&v->arch.phys_timer.timer,
|
||||
v->arch.phys_timer.cval +
|
||||
v->domain->arch.phys_timer_base.offset);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
static int vtimer_cntpct(struct cpu_user_regs *regs, uint64_t *r, int read)
|
||||
{
|
||||
struct vcpu *v = current;
|
||||
@@ -270,7 +294,7 @@ static int vtimer_emulate_cp64(struct cpu_user_regs *regs, union hsr hsr)
|
||||
struct hsr_cp64 cp64 = hsr.cp64;
|
||||
uint32_t *r1 = (uint32_t *)select_user_reg(regs, cp64.reg1);
|
||||
uint32_t *r2 = (uint32_t *)select_user_reg(regs, cp64.reg2);
|
||||
uint64_t x;
|
||||
uint64_t x = (uint64_t)(*r1) | ((uint64_t)(*r2) << 32);
|
||||
|
||||
if ( cp64.read )
|
||||
perfc_incr(vtimer_cp64_reads);
|
||||
@@ -282,17 +306,24 @@ static int vtimer_emulate_cp64(struct cpu_user_regs *regs, union hsr hsr)
|
||||
case HSR_CPREG64(CNTPCT):
|
||||
if ( !vtimer_cntpct(regs, &x, cp64.read) )
|
||||
return 0;
|
||||
break;
|
||||
|
||||
if ( cp64.read )
|
||||
{
|
||||
*r1 = (uint32_t)(x & 0xffffffff);
|
||||
*r2 = (uint32_t)(x >> 32);
|
||||
}
|
||||
return 1;
|
||||
case HSR_CPREG64(CNTP_CVAL):
|
||||
if ( !vtimer_cntp_cval(regs, &x, cp64.read) )
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( cp64.read )
|
||||
{
|
||||
*r1 = (uint32_t)(x & 0xffffffff);
|
||||
*r2 = (uint32_t)(x >> 32);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARM_64
|
||||
@@ -322,6 +353,9 @@ static int vtimer_emulate_sysreg(struct cpu_user_regs *regs, union hsr hsr)
|
||||
*x = r;
|
||||
return 1;
|
||||
|
||||
case HSR_SYSREG_CNTP_CVAL_EL0:
|
||||
return vtimer_cntp_cval(regs, x, sysreg.read);
|
||||
|
||||
case HSR_SYSREG_CNTPCT_EL0:
|
||||
return vtimer_cntpct(regs, x, sysreg.read);
|
||||
|
||||
|
||||
@@ -100,8 +100,9 @@
|
||||
#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)
|
||||
#define HSR_SYSREG_CNTP_CTL_EL0 HSR_SYSREG(3,3,c14,c2,1)
|
||||
#define HSR_SYSREG_CNTP_CVAL_EL0 HSR_SYSREG(3,3,c14,c2,2)
|
||||
|
||||
/*
|
||||
* GIC System register assembly aliases picked from kernel
|
||||
|
||||